【问题标题】:Cmake undefined reference to symbol 'dlsym@@GLIBC_2.2.5 even though I link with -ldl即使我与-ldl链接,Cmake对符号'dlsym@@GLIBC_2.2.5的未定义引用
【发布时间】:2020-11-19 00:40:52
【问题描述】:

即使在库之前和之后链接 dlsym@@GLIBC_2.2.5 之后,我也得到未定义的引用。然而,在链接输出中,它似乎是在链接之前,但在所有库都应该工作之前链接,我猜。

/bin/g++-9     CMakeFiles/http_downloader.dir/http_downloader_cli.cpp.o CMakeFiles/http_downloader.dir/SimpleOpenVPNSocket.cpp.o  -o http_downloader  -lpthread /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/liblz4.so -ldl downloader/libhttp_downloader_cli.a downloader/libhttp_downloader_lib.a ../../libopenvpn/libopenvpn_lib.a ../../_smoltcp_cpp_interface/libsmoltcp_cpp.a ../../_libtins/lib/libtins.a -ldl /usr/lib/x86_64-linux-gnu/libcrypto.so -lpthread /usr/lib/x86_64-linux-gnu/liblz4.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so ../../../../smoltcp_cpp_interface/target/debug/libsmoltcp_cpp_interface_rust.a /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so 
/usr/bin/ld: ../../../../smoltcp_cpp_interface/target/debug/libsmoltcp_cpp_interface_rust.a(std-6640d3868fa846e8.std.1mk5kra7-cgu.0.rcgu.o): undefined reference to symbol 'dlsym@@GLIBC_2.2.5'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libdl.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [src/examples/http_downloader/CMakeFiles/http_downloader.dir/build.make:113: src/examples/http_downloader/http_downloader] Error 1
make[2]: Leaving directory '/workspaces/libopenvpnclient/build'
make[1]: *** [CMakeFiles/Makefile2:519: src/examples/http_downloader/CMakeFiles/http_downloader.dir/all] Error 2
make[1]: Leaving directory '/workspaces/libopenvpnclient/build'
make: *** [Makefile:130: all] Error 2

这就是我在 CMake 中链接它的方式:

add_executable(http_downloader http_downloader_cli.cpp SimpleOpenVPNSocket.cpp)
add_core_dependencies(http_downloader)

target_include_directories(http_downloader PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/downloader/include)
add_dependencies(http_downloader http_downloader_cli http_downloader_lib openvpn_lib smoltcp_cpp tins)
set_property(TARGET http_downloader PROPERTY CXX_STANDARD 17)
target_link_libraries(http_downloader dl http_downloader_cli http_downloader_lib openvpn_lib smoltcp_cpp tins dl)

如您所见,我在所有内容之前和之后都添加了dl 以确保。

如果我理解正确,.a 库没有依赖关系,它们只有缺少的符号,我们必须填充它们。好像我是通过链接-ldl来做到这一点的@

【问题讨论】:

  • 所有的代码和所有的库都编译在同一个平台上吗?

标签: c++ cmake dependencies shared-libraries


【解决方案1】:

你会仔细检查用于链接的实际命令行,你会发现之后 libsmoltcp_cpp_interface_rust.a,它有遗漏的符号,有没有 -ldl 参数。

在您的情况下,smoltcp_cpp 似乎是一个导入库 target,它具有 libsmoltcp_cpp_interface_rust.a 作为 链接依赖项(而不是 IMPORTED_LOCATION 属性左右)。

虽然 CMake 保留库的顺序,链接到 单个 二进制文件(一个或另一个库),但未定义这些库的 依赖关系 之间的顺序。

您需要添加-ldl 作为smoltcp_cpp 目标本身的链接依赖项:

target_link_libraries(smoltcp_cpp INTERFACE -ldl)

但是,只有当libsmoltcp_cpp_interface_rust.asmoltcp_cpp 目标的直接链接依赖项时,这才有效,指定为

target_link_libraries(smoltcp_cpp INTERFACE libsmoltcp_cpp_interface_rust.a)

如果是间接依赖,比如

target_link_libraries(smoltcp_cpp INTERFACE <intermediate-target>)
target_link_libraries(<intermediate-target> INTERFACE libsmoltcp_cpp_interface_rust.a)

您需要添加 -ldl 作为该 &lt;intermediate-target&gt; 的依赖项。

理想情况下,每个 IMPORTED 目标都应该是自包含的,因此您可以在不知道其内部结构的情况下安全地链接到该目标。

【讨论】:

  • 谢谢!但是我怎样才能使导入的目标自包含呢?公平地说,我以为他们已经是那样了
  • "如何使导入的目标自包含?" - 只需为该目标调用target_link_libraries 并添加该目标所需的链接库。顺便说一句,target_link_libraries(smoltcp_cpp INTERFACE -ldl) 这行实际上是为了使导入的目标smoltcp_cpp 成为独立的。 “公平地说,我认为他们已经是那样了” - 你链接你的可执行文件 - http_downloader - 与 dl 库,但 你的代码 (http_downloader_cli.cpp, SimpleOpenVPNSocket.cpp) 没有使用这个库。这与库的“自包含”属性相反。
猜你喜欢
  • 1970-01-01
  • 2013-04-21
  • 2016-03-12
  • 2014-10-26
  • 1970-01-01
  • 2013-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多