diff mbox series

libradosstriper linkage conundrum

Message ID alpine.LSU.2.21.1807260939580.29092@smaug (mailing list archive)
State New, archived
Headers show
Series libradosstriper linkage conundrum | expand

Commit Message

Jesse Williamson July 26, 2018, 6:47 p.m. UTC
Hi folks,

I'm working on a feature to make libradosstriper optional:
https://github.com/ceph/ceph/pull/21983

While I believe I'm in the home stretch, I'm also getting a link error 
that I find mysterious. In the above PR, I have[1]:

target_link_libraries(rados librados global ${BLKID_LIBRARIES} 
${CMAKE_DL_LIBS})
if(WITH_LIBRADOSSTRIPER)
  target_link_libraries(rados radosstriper)
else(WITH_LIBRADOSSTRIPER)
  target_link_libraries(rados cls_lock_client)
endif(WITH_LIBRADOSSTRIPER)

...notice the line linking in cls_lock_client. With this present, things 
look ok. Remove it, and for me this fails to compile (link errors follow 
text).

It looks like cls_lock_client should already be linked into librados, as 
per src/librados/CMakeLists.txt:

target_link_libraries(librados PRIVATE
   osdc ceph-common cls_lock_client
   ${BLKID_LIBRARIES} ${CRYPTO_LIBS} ${EXTRALIBS})

I wondered if it might have been related to name mangling (usually 
something I've seen when extern "C" is used and then another TU uses C++ 
linkage), but although the symbols in cls_lock_client.h are marked 
"export", that's the default linkage for C++ so I don't think there is 
anything in the source code.

That leaves me to wonder if it's a cmake thing. Perhaps I'm missing 
something obvious?

  if(WITH_TESTS)

1) Compile with (note -DWITH_LIBRADOSSTRIPER=0) the following:

./do_cmake.sh -DHAS_VTA=0 -DWITH_LEVELDB=0 -DWITH_CCACHE=1 -DWITH_LTTNG=0
-DWITH_BABELTRACE=0 -DWITH_LZ4=0 -DWITH_LIBRADOSSTRIPER=0

cd build && make rados

2) I then see the errors listed below. Note that compiling with 
-DWITH_LIBRADOSSTRIPER=1, which is the default, should work just fine.

Am I missing something obvious? Some cmake magic?

I've had one other person not be able to reproduce this. Does it also work 
for everyone else (with -DWITH_LIBRADOSSTRIPER=0)? If so... what version 
of cmake are folks using?

Appreciatively,

-Jesse

CMakeFiles/rados.dir/rados/rados.cc.o: In function `do_lock_cmd':
/home/jwilliamson/work/ceph-libradosstriper/src/tools/rados/rados.cc:1246: 
undefined reference to `rados::cls::lock::get_lock_info(librados::IoCtx*, 
std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> > const&, std::__cxx11::basic_string<char, 
std::char_traits<char>, std::allocator<char> > const&, 
std::map<rados::cls::lock::locker_id_t, rados::cls::lock::locker_info_t, 
std::less<rados::cls::lock::locker_id_t>, 
std::allocator<std::pair<rados::cls::lock::locker_id_t const, 
rados::cls::lock::locker_info_t> > >*, ClsLockType*, 
std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> >*)'
/home/jwilliamson/work/ceph-libradosstriper/src/tools/rados/rados.cc:1309: 
undefined reference to 
`rados::cls::lock::Lock::break_lock(librados::IoCtx*, 
std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> > const&, entity_name_t const&)'
/home/jwilliamson/work/ceph-libradosstriper/src/tools/rados/rados.cc:1283: 
undefined reference to 
`rados::cls::lock::Lock::lock_shared(librados::IoCtx*, 
std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> > const&)'
/home/jwilliamson/work/ceph-libradosstriper/src/tools/rados/rados.cc:1286: 
undefined reference to 
`rados::cls::lock::Lock::lock_exclusive(librados::IoCtx*, 
std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> > const&)'
/home/jwilliamson/work/ceph-libradosstriper/src/tools/rados/rados.cc:1216: 
undefined reference to `rados::cls::lock::list_locks(librados::IoCtx*, 
std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> > const&, 
std::__cxx11::list<std::__cxx11::basic_string<char, 
std::char_traits<char>, std::allocator<char> >, 
std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> > > >*)'
collect2: error: ld returned 1 exit status

--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Casey Bodley July 26, 2018, 6:59 p.m. UTC | #1
On 07/26/2018 02:47 PM, Jesse Williamson wrote:
>
> Hi folks,
>
> I'm working on a feature to make libradosstriper optional:
> https://github.com/ceph/ceph/pull/21983
>
> While I believe I'm in the home stretch, I'm also getting a link error 
> that I find mysterious. In the above PR, I have[1]:
>
> target_link_libraries(rados librados global ${BLKID_LIBRARIES} 
> ${CMAKE_DL_LIBS})
> if(WITH_LIBRADOSSTRIPER)
>  target_link_libraries(rados radosstriper)
> else(WITH_LIBRADOSSTRIPER)
>  target_link_libraries(rados cls_lock_client)
> endif(WITH_LIBRADOSSTRIPER)
>
> ...notice the line linking in cls_lock_client. With this present, 
> things look ok. Remove it, and for me this fails to compile (link 
> errors follow text).
>
> It looks like cls_lock_client should already be linked into librados, 
> as per src/librados/CMakeLists.txt:
>
> target_link_libraries(librados PRIVATE
>   osdc ceph-common cls_lock_client
>   ${BLKID_LIBRARIES} ${CRYPTO_LIBS} ${EXTRALIBS})
>

the PRIVATE there means that the link dependencies aren't transitive - 
so while rados will link with librados, it won't link directly with 
cls_lock_client

> I wondered if it might have been related to name mangling (usually 
> something I've seen when extern "C" is used and then another TU uses 
> C++ linkage), but although the symbols in cls_lock_client.h are marked 
> "export", that's the default linkage for C++ so I don't think there is 
> anything in the source code.
>
> That leaves me to wonder if it's a cmake thing. Perhaps I'm missing 
> something obvious?
>
> ====
>
> To reproduce:
>
> 0) Make sure that "cls_lock_client" isn't included, by patching the above
> (as per Kefu):
>
> diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
> index ad8c2f81a1..b63654c09f 100644
> --- a/src/tools/CMakeLists.txt
> +++ b/src/tools/CMakeLists.txt
> @@ -10,10 +10,10 @@ add_executable(rados ${rados_srcs})
>
>  target_link_libraries(rados librados global ${BLKID_LIBRARIES}
> ${CMAKE_DL_LIBS})
>  if(WITH_LIBRADOSSTRIPER)
> -target_link_libraries(rados radosstriper)
> -else(WITH_LIBRADOSSTRIPER)
> -target_link_libraries(rados cls_lock_client)
> -endif(WITH_LIBRADOSSTRIPER)
> +  target_link_libraries(rados radosstriper)
> +  #else()
> +  #target_link_libraries(rados cls_lock_client)
> +endif()
>  install(TARGETS rados DESTINATION bin)
>
>  if(WITH_TESTS)
>
> 1) Compile with (note -DWITH_LIBRADOSSTRIPER=0) the following:
>
> ./do_cmake.sh -DHAS_VTA=0 -DWITH_LEVELDB=0 -DWITH_CCACHE=1 -DWITH_LTTNG=0
> -DWITH_BABELTRACE=0 -DWITH_LZ4=0 -DWITH_LIBRADOSSTRIPER=0
>
> cd build && make rados
>
> 2) I then see the errors listed below. Note that compiling with 
> -DWITH_LIBRADOSSTRIPER=1, which is the default, should work just fine.
>
> Am I missing something obvious? Some cmake magic?
>
> I've had one other person not be able to reproduce this. Does it also 
> work for everyone else (with -DWITH_LIBRADOSSTRIPER=0)? If so... what 
> version of cmake are folks using?
>
> Appreciatively,
>
> -Jesse
>
> CMakeFiles/rados.dir/rados/rados.cc.o: In function `do_lock_cmd':
> /home/jwilliamson/work/ceph-libradosstriper/src/tools/rados/rados.cc:1246: 
> undefined reference to 
> `rados::cls::lock::get_lock_info(librados::IoCtx*, 
> std::__cxx11::basic_string<char, std::char_traits<char>, 
> std::allocator<char> > const&, std::__cxx11::basic_string<char, 
> std::char_traits<char>, std::allocator<char> > const&, 
> std::map<rados::cls::lock::locker_id_t, 
> rados::cls::lock::locker_info_t, 
> std::less<rados::cls::lock::locker_id_t>, 
> std::allocator<std::pair<rados::cls::lock::locker_id_t const, 
> rados::cls::lock::locker_info_t> > >*, ClsLockType*, 
> std::__cxx11::basic_string<char, std::char_traits<char>, 
> std::allocator<char> >*)'
> /home/jwilliamson/work/ceph-libradosstriper/src/tools/rados/rados.cc:1309: 
> undefined reference to 
> `rados::cls::lock::Lock::break_lock(librados::IoCtx*, 
> std::__cxx11::basic_string<char, std::char_traits<char>, 
> std::allocator<char> > const&, entity_name_t const&)'
> /home/jwilliamson/work/ceph-libradosstriper/src/tools/rados/rados.cc:1283: 
> undefined reference to 
> `rados::cls::lock::Lock::lock_shared(librados::IoCtx*, 
> std::__cxx11::basic_string<char, std::char_traits<char>, 
> std::allocator<char> > const&)'
> /home/jwilliamson/work/ceph-libradosstriper/src/tools/rados/rados.cc:1286: 
> undefined reference to 
> `rados::cls::lock::Lock::lock_exclusive(librados::IoCtx*, 
> std::__cxx11::basic_string<char, std::char_traits<char>, 
> std::allocator<char> > const&)'
> /home/jwilliamson/work/ceph-libradosstriper/src/tools/rados/rados.cc:1216: 
> undefined reference to `rados::cls::lock::list_locks(librados::IoCtx*, 
> std::__cxx11::basic_string<char, std::char_traits<char>, 
> std::allocator<char> > const&, 
> std::__cxx11::list<std::__cxx11::basic_string<char, 
> std::char_traits<char>, std::allocator<char> >, 
> std::allocator<std::__cxx11::basic_string<char, 
> std::char_traits<char>, std::allocator<char> > > >*)'
> collect2: error: ld returned 1 exit status
>
> -- 
> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jesse Williamson July 26, 2018, 7:06 p.m. UTC | #2
On Thu, 26 Jul 2018, Casey Bodley wrote:

>>  target_link_libraries(librados PRIVATE
>>    osdc ceph-common cls_lock_client
>>    ${BLKID_LIBRARIES} ${CRYPTO_LIBS} ${EXTRALIBS})
>> 
>
> the PRIVATE there means that the link dependencies aren't transitive - so 
> while rados will link with librados, it won't link directly with 
> cls_lock_client

Ah! Another mysterious mystery of cmake. Thank you.

Now, is the solution to go ahead and link with cls_lock_client (there's a 
static library that I see has been built)?

-Jesse
diff mbox series

Patch

====

To reproduce:

0) Make sure that "cls_lock_client" isn't included, by patching the above
(as per Kefu):

diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
index ad8c2f81a1..b63654c09f 100644
--- a/src/tools/CMakeLists.txt
+++ b/src/tools/CMakeLists.txt
@@ -10,10 +10,10 @@  add_executable(rados ${rados_srcs})

  target_link_libraries(rados librados global ${BLKID_LIBRARIES}
${CMAKE_DL_LIBS})
  if(WITH_LIBRADOSSTRIPER)
-target_link_libraries(rados radosstriper)
-else(WITH_LIBRADOSSTRIPER)
-target_link_libraries(rados cls_lock_client)
-endif(WITH_LIBRADOSSTRIPER)
+  target_link_libraries(rados radosstriper)
+  #else()
+  #target_link_libraries(rados cls_lock_client)
+endif()
  install(TARGETS rados DESTINATION bin)