Getting tbb linker errors when including the <execution> header - c++

I have been writing a visualisation tool using OpenGL. It has been compiling and linking just fine (using gcc 11.2.0) until I recently installed the Linux dependencies for OpenVDB (listed under Using UNIX apt-get). I am now getting linker errors that I have narrowed down to the inclusion of the <execution> header file:
/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o: in function `tbb::detail::d1::execution_slot(tbb::detail::d1::execution_data const&)':
main.cpp:(.text._ZN3tbb6detail2d114execution_slotERKNS1_14execution_dataE[_ZN3tbb6detail2d114execution_slotERKNS1_14execution_dataE]+0x18): undefined reference to `tbb::detail::r1::execution_slot(tbb::detail::d1::execution_data const*)'
/usr/bin/ld: CMakeFiles/test.dir/main.cpp.o: in function `tbb::detail::d1::current_thread_index()':
main.cpp:(.text._ZN3tbb6detail2d120current_thread_indexEv[_ZN3tbb6detail2d120current_thread_indexEv]+0x12): undefined reference to `tbb::detail::r1::execution_slot(tbb::detail::d1::execution_data const*)'
The above is from the following minimal example.
main.cpp:
#include <execution>
#include <iostream>
int main()
{
std::cout << "Hello, World!" << std::endl;
return 0;
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.22)
project(test)
set(CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 20)
add_executable(test main.cpp)
I have tried linking TBB with my project like so:
# Find and link TBB.
find_package(TBB REQUIRED)
include_directories(${TBB_INCLUDE_DIRS})
link_directories(${TBB_LIBRARY_DIRS})
add_definitions(${TBB_DEFINITIONS})
if(NOT TBB_FOUND)
message("Error: TBB not found")
endif(NOT TBB_FOUND)
add_executable(test main.cpp)
target_link_libraries(test ${TBB_LIBRARIES})
...and also adding the -ltbb linker flag (as per the answer to this post) using
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -ltbb")
However, this does not solve the issue.
What I find particularly strange is that I didn't use to have to link against tbb despite having included the <excution> header all along. Only after installing the OpenVDB dependencies has this become an issue.
Can anyone advise me on how to solve this (either by appropriately linking tbb, or not having to link it at all, as was the case before)? Any form of insight would be much appreciated.

I have managed to successfully link tbb as follows:
find_package(TBB REQUIRED COMPONENTS tbb)
add_executable(test main.cpp)
target_link_libraries(test tbb)
Although I am still clueless as to why I suddenly needed to link with tbb, considering I previously didn't need to.

Uninstalling libtbb-dev also works and dont require editing the CMakeFiles.txt.

Related

Undefined reference errors in simple boost serialization

I have a minimal example of Boost serialization where I try to save an integer in a binary archive file
Here is main.cpp:
#include <iostream>
#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
int main() {
int t = 0;
std::ofstream file("Test.bin");
boost::archive::binary_oarchive archive(file);
archive << t;
file.close();
return 0;
}
and here is the CMake file:
cmake_minimum_required(VERSION 3.15)
project(Test)
set(CMAKE_CXX_STANDARD 17)
find_package(Boost REQUIRED serialization)
add_executable(Test main.cpp)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(Test ${Boost_LIBRARIES})
endif()
When I try to run this program in CLion, I get a large list of undefined reference errors as shown here:
https://pastebin.com/8uX9MZFf
I have setup Boost using vcpkg package manager. I'm compiling using Mingw-w64. The CMake file loads without errors (only a warning that says "New Boost version may have incorrect or missing dependencies and imported targets," though I've heard this warning isn't of concern, as it just means the current version of CMake isn't aware of the newest version of Boost).
I've tried to look for solutions to this everywhere, but I can't seem to find anything that works here. Any help would be appreciated.
I'm using cmake 3.15.3, boost 1.73.0 and mingw-w64 6.0.
EDIT
I uninstalled and reinstalled Boost without using the package manager, and tried getting the serialization library again. In this context, CMake runs into errors saying it can't find Boost with serialization (Though it can find Boost alone). I set Boost_DEBUG to ON and looked at the output, and noticed the following things:
_boost_COMPILER = "-mgw81" (guessed)
CMake seems to guess that the compiler I used to compile boost was mgw81. I'm guessing it got the 8.1 from my gcc version, which is correct.
Searching for SERIALIZATION_LIBRARY_RELEASE: boost_serialization-mgw81-mt-x64-1_73;boost_serialization-mgw81-mt-x64;...
As a result of that compiler selection, it searches for a file with "-mgw81" in the name. The problem is that the library files generated when I built boost are named like so:
libboost_serialization-mgw8-mt-x64-1_73.a
This says "-mgw8" instead of "-mgw81". I don't know how to correct CMake or build boost in such a way that this conflict doesn't happen. I've tried rebuilding boost with toolset=gcc-8.1 instead of toolset=gcc, but I still get "-mgw8" in the library file names.
EDIT 2
I found the solution to the above issue. I've posted it below.
After realizing that the issue was what I mentioned in EDIT, I looked further into how that issue could be resolved, and I found out you can manually set the compiler that is used to search through the variable Boost_COMPILER.
I changed my CMake file to the following:
cmake_minimum_required(VERSION 3.15)
project(Test)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "C:/boost_1_73_0")
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "C:/boost_1_73_0/libs")
set(Boost_DEBUG ON)
set(Boost_COMPILER -mgw8)
set(Boost_ARCHITECTURE -x64)
set(BOOST_ROOT C:/boost)
set(BOOST_INCLUDEDIR C:/boost/include/boost-1_73/boost)
set(BOOST_LIBRARYDIR C:/boost/lib)
set(BOOST_NO_SYSTEM_PATHS ON)
find_package(Boost REQUIRED serialization)
add_executable(Test main.cpp)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(Test ${Boost_LIBRARIES})
endif()
I believe the critical changes here were setting Boost_COMPILER and Boost_ARCHITECTURE. I realized Boost_ARCHITECTURE needed to be set from this question: Linking boost in CLion project.
With this CMake file, my main.cpp file from above ran properly.

BOOST_ROOT not respected at link stage after cmake config

Apologies for a lengthy title.
I am struggling linking boost with cmake due to existence of boost libraries in /usr/lib64 directory. My boost is compiled in a different place and I am pointing cmake with BOOST_ROOT. Aware of potential problems I am setting a minimal version and Boost_NO_SYSTEM_PATH. Configure stage works fine, but when linking I get an error:
test.cpp:(.text._ZN5boost15program_options25basic_command_line_parserIcEC2EiPKPKc[_ZN5boost15program_options25basic_command_line_parserIcEC5EiPKPKc]+0xa8): undefined reference to `boost::program_options::detail::cmdline::cmdline(std::vector<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> > > > const&)'
This is clearly a problem of picking up the wrong library and I can see with make VERBOSE=2 that the g++ line doesn't respect my previously found boost setting in BOOST_ROOT
g++ CMakeFiles/test.dir/test.cpp.o -o test -rdynamic -lboost_program_options-mt
But I would expect something along these lines:
g++ ... -L/path/to/my/own/boost/lib -lboost_program_options-mt
As a "debug" step I print out a message in cmake with Boost_LIBRARY_DIRS and I can see /path/to/my/own/boost/lib. When I "manually" add the -L flag the linking works, which is how I know that the system libs are still interfering. Also, my *LIBRARY_PATH are pointing only at /path/to/my/own/boost/lib.
Perhaps, it's not unlikely that this is a bug of FindBoost module, but I am finding it hard to believe. It seems to me that there's still something major in cmake I do not understand? Why is the -L flag not generated in this instance or a link to a specific file? Please advise.
Here is my CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
set(Boost_NO_SYSTEM_PATHS ON)
find_package(Boost 1.67.0 REQUIRED COMPONENTS program_options)
include_directories(${Boost_INCLUDE_DIR})
add_executable(test test.cpp)
target_link_libraries(test LINK_PUBLIC ${Boost_PROGRAM_OPTIONS_LIBRARY})
And my program:
#include <iostream>
#include <string>
#include <boost/program_options.hpp>
namespace po=boost::program_options;
int main( int argc, char* argv[])
{
po::options_description options_description;
po::positional_options_description positional_options_description;
po::variables_map variables_map;
options_description.add_options()
("help,h", "print usage message");
po::store(po::command_line_parser(argc, argv).options(
options_description).positional(positional_options_description).run(),
variables_map);
return 0;
}
Other relevant output
I am using message to pull out varables from cmake config step after find_package:
${Boost_INCLUDE_DIR} /path/to/my/own/boost/include
${Boost_LIBRARY_DIRS} /path/to/my/own/boost/lib
${Boost_LIBRARIES} /path/to/my/own/boost/lib/libboost_program_options-mt.so
${Boost_PROGRAM_OPTIONS_LIBRARY} /path/to/my/own/boost/lib/libboost_program_options-mt.so
I don't know which CMake version you are using but did you try using Boost imported target instead of the old-fashioned CMake variable:
i.e.
replace:
target_link_libraries(test LINK_PUBLIC ${Boost_PROGRAM_OPTIONS_LIBRARY})
by
target_link_libraries(test LINK_PUBLIC Boost::program_options)
After calling in on cmake-developer mailing list and finally leaving a post on cmake gitlab issues I realised that the problem was not so much my cmake version, but rather my cmake_minimum_required which I inherited from an older project.
I was setting:
cmake_minium_required(VERSION 2.8)
After updating it to 3.12 that I got the correct behaviour:
/path/to/g++ -rdynamic CMakeFiles/test.dir/test.cpp.o -o test -lboost_program_options-mt
Reading cmake_minimum_required docs I understood that "command implicitly invokes" cmake_policy. I believe the latter wasn't playing well with FindBoost from my 3.12 `cmake.
I am not sure if this post is useful to SO, but I have certainly learnt my cmake lesson here.

Cmake undefined reference to `boost::gregorian::greg_month::as_short_string() const'

I spend whole day trying to link the data_time library to my c++ cmake project.
So I am using cmake 3.4 and boost 1.61.0.
I have the class where is a function which is taking local time:
void TestClass::getTime() {
this->endDate = boost::posix_time::second_clock::local_time();
}
Then I want to return the value of endDate by function returning string:
string testCalss::Info() {
return to_simple_string(this->beginningDate);
}
I need to convert the type of endDate variable to string, because function is string type.
I am getting error messages while program is linking:
In function boost::date_time::month_formatter<boost::gregorian::greg_month, boost::date_time::simple_format<char>, char>::format_month(boost::gregorian::greg_month const&, std::ostream&)':
/usr/include/boost/date_time/date_formatting.hpp:44: undefined reference to `boost::gregorian::greg_month::as_short_string() const'
/usr/include/boost/date_time/date_formatting.hpp:49: undefined reference to `boost::gregorian::greg_month::as_long_string() const'
I have read that data_time is not only header-only library and I should build and add it to my project.
I have tried this command gcc myapp.cpp -omyapp -lboost_date_time, and it's does not work because I am using g++ in cmake project and I haven't find nothing for g++.
I also tried this:
c++ -I path/to/boost_1_61_0 example.cpp -o example \
~/boost/stage/lib/libboost_regex-gcc34-mt-d-1_36.a
Its example from official boost docs how to link libraries.
In cmake project I have few cpp files. Should I run this command using file where is my converting command?
Is there any easier way to fix this error?
I found out how to solve the problem. The way I choose is simple. First of all I have used the locate */boost/date_time* command to find where is my boost and date_time libraries installed. I did not know what version of boost library I am using, so I used locate command again to find boost/version.hpp file. After that I added few lines to my CmakeLists.txt:
find_package( Boost 1.60.0 COMPONENTS date_time)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries( Program ${Boost_DATE_TIME_LIBRARY} )
endif()
Thats all.
cmake_minimum_required(VERSION 3.17)
project(boost_ptime)
set(CMAKE_CXX_STANDARD 17)
set(SOURCE_FILES main.cpp)
add_executable(boost_ptime ${SOURCE_FILES})
find_package( Boost 1.73 COMPONENTS date_time)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries( boost_ptime ${Boost_DATE_TIME_LIBRARY} )
endif()
Thanks to Warszawski Koks, I was able to compile my program in this way. Above is the full CMakeLists.txt file.

How to link compiled cmph library in my project using CMake

In order to use cmph, a perfect minimal hashing library, in my project organised using CMake, I installed cmph library in a ubuntu machine and tested it using a single c file called main.c.
If I try to compile this file using gcc 5.3.0 using the following command:
gcc main.c
I will get the following output
/tmp/ccSOH5ob.o: In function `main':
testperfect.c:(.text+0x63): undefined reference to `cmph_io_vector_adapter'
testperfect.c:(.text+0x73): undefined reference to `cmph_config_new'
testperfect.c:(.text+0x88): undefined reference to `cmph_config_set_algo'
testperfect.c:(.text+0x9b): undefined reference to `cmph_config_set_mphf_fd'
testperfect.c:(.text+0xa7): undefined reference to `cmph_new'
testperfect.c:(.text+0xb7): undefined reference to `cmph_config_destroy'
testperfect.c:(.text+0xca): undefined reference to `cmph_dump'
testperfect.c:(.text+0xd6): undefined reference to `cmph_destroy'
testperfect.c:(.text+0xe2): undefined reference to `cmph_load'
testperfect.c:(.text+0x118): undefined reference to `cmph_search'
testperfect.c:(.text+0x153): undefined reference to `cmph_destroy'
testperfect.c:(.text+0x15f): undefined reference to `cmph_io_vector_adapter_destroy'
But if I run this command:
gcc main.c $(pkg-config --libs cmph) -o main
It will be compiled and run normally.
Now I need to add a similar piece of code in my project and the CMakeList.txt is written like this:
set(PROJECT_EXECUTABLE ${PROJECT_NAME})
# Compiling flags.
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR
CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
endif()
# Inject project config.
configure_file(
${PROJECT_INCLUDE_DIR}/phsim/config.hpp.in
${PROJECT_INCLUDE_DIR}/phsim/config.hpp
)
include(FindPkgConfig)
find_package(PkgConfig REQUIRED)
pkg_search_module(CMPH REQUIRED cmph)
target_link_libraries(Phsim ${CMPH_LIBRARIES})
target_include_directories(Phsim PUBLIC ${CMPH_INCLUDE_DIRS})
target_compile_options(Phsim PUBLIC ${CMPH_CFLAGS_OTHER})
# Compile executable.
file(GLOB SOURCES ${PROJECT_SRC_DIR}/*.cpp)
add_executable(${PROJECT_EXECUTABLE} ${SOURCES})
set_target_properties(${PROJECT_EXECUTABLE} PROPERTIES
VERSION ${PHSIM_VERSION_LITER}
)
And then I try to run cmake . and make, but only get the error message:
CMake Error at src/CMakeLists.txt:20 (target_link_libraries):
Cannot specify link libraries for target "Phsim" which is not built by this
project.
But I won't get target executable file unless I compile the project. If I try to compile my project without those commands related to library linking, the compiler will give similar link errors provided in the beginning of my question.
I have checked the following questions:
Undefined reference to cmph functions even after installing cpmh library
And I tried instructions provided by these sites:
https://cmake.org/Wiki/CMake:How_To_Find_Libraries
https://cmake.org/cmake/help/v3.6/module/FindPkgConfig.html
Many thanks in advance.
Finally Solved.
cmake_minimum_required(VERSION 3.0.2)
project(TestGamma)
set(GAMMATEST_VERSION_MAJOR 1)
set(GAMMATEST_VERSION_MINOR 0)
set(CMPH_INCLUDE_DIR /usr/local/lib)
include(FindPkgConfig)
configure_file(
"${PROJECT_SOURCE_DIR}/TestGammaConfig.h.in"
"${PROJECT_BINARY_DIR}/TestGammaConfig.h"
)
include_directories(${PROJECT_BINARY_DIR})
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(testgamma ${SOURCE_FILES})
pkg_check_modules(CMPH REQUIRED cmph)
include_directories(${CMPH_INDLUDE_DIR})
link_directories(${CMPH_INCLUDE_DIR})
target_link_libraries(testgamma cmph ${CMPH_INCLUDE_DIR})
Make sure to include pkgconfig at first and add link operations after calling "add_executable"
#usr1234567 Thank you for your attention.

unresolved symbols while linking boost program options

A user of my project reported this error to me. I cannot reproduce it on my computer or my lab's server, so I ask it here.
The project uses CMake to generate build environment. It uses the FindBoost utility (provided with CMake) to find Boost resources.
On the beginning, my user said while linking the final programs, the compiler was provided with "/usr/lib64/lib64/libboost_XXX.so", instead of the correct "/usr/lib64/libboost_XXX.so". I failed to find why CMake generated such weird library location, and asked him to manually set the variable Boost_LIBRARIES, and print them:
Boost libraries are: /usr/lib64/libboost_thread-mt.so;/usr/lib64/libboost_program_options-mt.so;/usr/lib64/libboost_filesystem-mt.so
Things seem to be correct. The compilation was successful. But when it goes to linking, the program cries about many undefined symbols:
CMakeFiles/ht-filter.dir/ht-filter.cpp.o: In function `parse_options(int, char**)':
/public/home/yli/Downloads/htqc-0.15.0-Source/ht-filter.cpp:43: undefined reference to `boost::program_options::options_description::options_description(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, unsigned int)'
......
/usr/local/include/boost/program_options/errors.hpp:372: undefined reference to `boost::program_options::validation_error::get_template(boost::program_options::validation_error::kind_t)'
This is the two typical of the so-many errors: one locates from my source code, the other locates from boost's header. In the corresponding line of my source code, I just created the options_description object
// I renamed boost::program_options to opt
opt::options_description opt_main("Options:");
The OS of my user is CentOS 6.2, and his Boost version is 1.50.0 which is similiar with the one in my computer. The version of CMake of my user is 2.8.11 which is also same with mine.
While using CMake's find_package for Boost, you can give a few hints to CMake which may help it find the correct library, such as:
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(BOOST_ROOT "/usr")
find_package(Boost 1.50.0)
message(STATUS "Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
message(STATUS "Boost_LIBRARY_DIRS: ${Boost_LIBRARY_DIRS}")
Also if you are linking with dynamic libs make sure to let Boost headers know about it (I think you shouldn't mess with the order in here):
link_directories(${Boost_LIBRARY_DIRS})
include_directories(${Boost_INCLUDE_DIRS})
add_definitions( -DBOOST_ALL_DYN_LINK )