`ld` 未定义引用错误,但库由 CMake 链接到并且符号存在
`ld` undefined reference error, but libraries are linked to by CMake and symbols exist
我有一个这样的 CMake 文件:
cmake_minimum_required(VERSION 3.12)
project(cpp-service VERSION 0.1.0)
add_compile_definitions(OPENVDB_7_ABI_COMPATIBLE)
list(APPEND CMAKE_MODULE_PATH "/usr/local/lib64/cmake/OpenVDB/")
find_package(OpenVDB REQUIRED)
###
list(APPEND CMAKE_MODULE_PATH "deps/tbb/cmake/")
find_package(TBB REQUIRED)
add_executable(${PROJECT_NAME}
src/main.cpp
)
target_link_libraries(${PROJECT_NAME} PUBLIC
OpenVDB::openvdb
TBB::tbb
)
所有库都是由 CMake link编辑的。这些符号都可用。但是,linker 根本无法link 找到符号。有很多这样的错误:
...
[ 92%] Building CXX object ...
[ 96%] Building CXX object ...
[100%] Linking CXX executable cpp-service
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: CMakeFiles/cpp-service.dir/src/main.cpp.o: in function `hollowing::mesh_to_grid(hollowing::Contour const&, openvdb::v7_2::math::Transform const&, float, float, int)':
/home/m3/repos/cpp-service/src/hollowing.h:268: undefined reference to `openvdb::v7_2::initialize()'
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: CMakeFiles/cpp-service.dir/src/main.cpp.o: in function `tbb::task_group_context::task_group_context(tbb::task_group_context::kind_type, unsigned long)':
/home/m3/repos/cpp-service/deps/tbb/include/tbb/task.h:499: undefined reference to `tbb::task_group_context::init()'
...
猜一猜
一种猜测是我 this problem:
...It seems that gcc now send the linker flag --as-needed
to ld
. This has the effect of discarding any specified libraries that do not have symbols that are required for linking.
尝试过
这个我试过了,没有效果。抛出相同的 link 错误:
target_link_options(${PROJECT_NAME} PUBLIC
"LINKER:-no-as-needed"
)
问题
我运行没有调试这个问题的选项。有人有任何尝试的建议吗?
CMake 命令
export CC=/usr/bin/gcc-11
export CXX=/usr/bin/g++-11
mkdir build
cd build
cmake ..
cmake --build . --verbose >> log.txt 2>&1 # Save log to file.
编译命令
CMake 显示编译日志如下:
[ 3%] Building CXX object CMakeFiles/cpp-service.dir/src/main.cpp.o
/usr/bin/g++-11 -I/home/m3/repos/cpp-service/deps/tbb/include -I/.../more/include/paths/.../... -g -std=c++17 -MD -MT CMakeFiles/cpp-service.dir/src/main.cpp.o -MF CMakeFiles/cpp-service.dir/src/main.cpp.o.d -o CMakeFiles/cpp-service.dir/src/main.cpp.o -c /home/m3/repos/cpp-service/src/main.cpp
Link 命令
CMake 日志显示 link 命令是:
[100%] Linking CXX executable cpp-service
/usr/local/bin/cmake -E cmake_link_script CMakeFiles/cpp-service.dir/link.txt --verbose=1
/usr/bin/g++-11 -g CMakeFiles/cpp-service.dir/src/main.cpp.o CMakeFiles/cpp-service.dir/src/***.cpp.o CMakeFiles/cpp-service.dir/src/***more***object***files***.cpp.o -o cpp-service
错误是在上述 link 命令之后立即抛出的。错误如:
undefined reference to `openvdb::v7_2::initialize()'
符号
符号在 linked 库中定义:
nm /usr/local/lib64/libopenvdb.so | less
以上命令显示 initialize
符号可用:
修复
链接器错误的原因是这条语句:
if(LINUX)
修复方法是将其替换为:
if(UNIX AND NOT APPLE)
此提交修复了问题:
参考:
奇怪的是,CMake 并没有抱怨任何事情,只是抛出随机链接器错误。
我有一个这样的 CMake 文件:
cmake_minimum_required(VERSION 3.12)
project(cpp-service VERSION 0.1.0)
add_compile_definitions(OPENVDB_7_ABI_COMPATIBLE)
list(APPEND CMAKE_MODULE_PATH "/usr/local/lib64/cmake/OpenVDB/")
find_package(OpenVDB REQUIRED)
###
list(APPEND CMAKE_MODULE_PATH "deps/tbb/cmake/")
find_package(TBB REQUIRED)
add_executable(${PROJECT_NAME}
src/main.cpp
)
target_link_libraries(${PROJECT_NAME} PUBLIC
OpenVDB::openvdb
TBB::tbb
)
所有库都是由 CMake link编辑的。这些符号都可用。但是,linker 根本无法link 找到符号。有很多这样的错误:
...
[ 92%] Building CXX object ...
[ 96%] Building CXX object ...
[100%] Linking CXX executable cpp-service
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: CMakeFiles/cpp-service.dir/src/main.cpp.o: in function `hollowing::mesh_to_grid(hollowing::Contour const&, openvdb::v7_2::math::Transform const&, float, float, int)':
/home/m3/repos/cpp-service/src/hollowing.h:268: undefined reference to `openvdb::v7_2::initialize()'
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: CMakeFiles/cpp-service.dir/src/main.cpp.o: in function `tbb::task_group_context::task_group_context(tbb::task_group_context::kind_type, unsigned long)':
/home/m3/repos/cpp-service/deps/tbb/include/tbb/task.h:499: undefined reference to `tbb::task_group_context::init()'
...
猜一猜
一种猜测是我 this problem:
...It seems that gcc now send the linker flag
--as-needed
told
. This has the effect of discarding any specified libraries that do not have symbols that are required for linking.
尝试过
这个我试过了,没有效果。抛出相同的 link 错误:
target_link_options(${PROJECT_NAME} PUBLIC
"LINKER:-no-as-needed"
)
问题
我运行没有调试这个问题的选项。有人有任何尝试的建议吗?
CMake 命令
export CC=/usr/bin/gcc-11
export CXX=/usr/bin/g++-11
mkdir build
cd build
cmake ..
cmake --build . --verbose >> log.txt 2>&1 # Save log to file.
编译命令
CMake 显示编译日志如下:
[ 3%] Building CXX object CMakeFiles/cpp-service.dir/src/main.cpp.o
/usr/bin/g++-11 -I/home/m3/repos/cpp-service/deps/tbb/include -I/.../more/include/paths/.../... -g -std=c++17 -MD -MT CMakeFiles/cpp-service.dir/src/main.cpp.o -MF CMakeFiles/cpp-service.dir/src/main.cpp.o.d -o CMakeFiles/cpp-service.dir/src/main.cpp.o -c /home/m3/repos/cpp-service/src/main.cpp
Link 命令
CMake 日志显示 link 命令是:
[100%] Linking CXX executable cpp-service
/usr/local/bin/cmake -E cmake_link_script CMakeFiles/cpp-service.dir/link.txt --verbose=1
/usr/bin/g++-11 -g CMakeFiles/cpp-service.dir/src/main.cpp.o CMakeFiles/cpp-service.dir/src/***.cpp.o CMakeFiles/cpp-service.dir/src/***more***object***files***.cpp.o -o cpp-service
错误是在上述 link 命令之后立即抛出的。错误如:
undefined reference to `openvdb::v7_2::initialize()'
符号
符号在 linked 库中定义:
nm /usr/local/lib64/libopenvdb.so | less
以上命令显示 initialize
符号可用:
修复
链接器错误的原因是这条语句:
if(LINUX)
修复方法是将其替换为:
if(UNIX AND NOT APPLE)
此提交修复了问题:
参考:
奇怪的是,CMake 并没有抱怨任何事情,只是抛出随机链接器错误。