4

I have a CMake file like this:

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)

### https://stackoverflow.com/a/69290761/3405291
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
)

All the libraries are linked-to by CMake. The symbols are all available. But, linker cannot link find symbols at all. With many errors like this:

...
[ 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()'
...

Guess

One guess is that I'm having 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.

Tried

I tried this, but it had no effect. The same link errors are thrown:

target_link_options(${PROJECT_NAME} PUBLIC
    "LINKER:-no-as-needed"
)

Question

I ran out of options debugging this problem. Does anybody have any suggestion to try out?


CMake commands

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.

Compile commands

CMake shows the compile logs are like:

[  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 command

CMake log shows the link command is:

[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 

The errors are thrown exactly right after the above link command. Errors like:

undefined reference to `openvdb::v7_2::initialize()'

Symbols

Symbols are defined inside the linked libraries:

nm /usr/local/lib64/libopenvdb.so | less

The above command shows the initialize symbol is available:

Symbol

Megidd
  • 7,089
  • 6
  • 65
  • 142
  • 3
    Checking what's on the compiler command line would be the first debugging step – Alan Birtles Feb 23 '22 at 07:51
  • 1
    "All the libraries are linked-to by CMake." - Have you found that by inspecting the exact command line which is executed during the build? Show that command line (add it to the question post). "The symbols are all available." - Have you found that by inspecting output of `nm`? Show that output. – Tsyvarev Feb 23 '22 at 08:04
  • 1
    Does the link command mention the library at all? – fabian Feb 23 '22 at 18:33
  • @fabian No, not at all. This error happens on a Linux machine. I am building on another Windows just fine, I checked out the *link* command on Windows. I noticed that even on Windows which builds fine, there is no library mentioned by *link* command. – Megidd Feb 24 '22 at 02:48
  • On Windows you can use a pragma to specify a library right inside your C or C++ code. No such luck on Linux. – n. m. could be an AI Feb 24 '22 at 08:02
  • 1
    The guess is wrong. Since no libraries are mentioned in the link command, where they clearly should, the problem lies in cmake ignoring the libraries specified in `target_link_libraries`. – n. m. could be an AI Feb 24 '22 at 09:49
  • @n.1.8e9-where's-my-sharem. Right. I suspect a syntax error in my CMake file. Is there any tool to detect faults inside a CMake list file? – Megidd Feb 24 '22 at 11:43

1 Answers1

2

Fix

The cause of the linker errors was this statement:

if(LINUX)

The fix was to replace it with this:

if(UNIX AND NOT APPLE)

This commit fixes the problem:

Commit

Reference: https://stackoverflow.com/a/40152725/3405291

Strangely, CMake wasn't complaining about anything and just throwing random linker errors.

Megidd
  • 7,089
  • 6
  • 65
  • 142