1
votes

I'm trying to build a 3rd party C++ library from source, and it depends on Boost. In the very last step when building, I got errors like this:

[ 90%] Linking CXX executable Shannon_RNASeq_Cpp
CMakeFiles/Shannon_RNASeq_Cpp.dir/src/main.cpp.o: In function `command_line_for_find_rep(int, char**, Shannon_C_setting&, 
std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> >&, std::__cxx11::basic_string<char, 
std::char_traits<char>, std::allocator<char> >&)':
/home/lambda/Shannon_Cpp_RNA_seq/src/main.cpp:320: undefined reference to `boost::program_options::options_description::options_description(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, unsigned int)'

I searched other questions on StackOverflow (e.g. Boost Program Options link error), and initially thought that it was caused by the different compilers used to build the non-header part of Boost, so I downloaded the source of Boost 1.68.0 and built it in my personal directory using the same compiler I used to build the 3rd party library (the compiler is gcc 8.2.0), and from the error message, I can tell that C++11 standard was used (you can see cxx11 in the error message), so it can't be the case that compiler not supporting C++11 is causing the trouble, as supposed previously (e.g. undefined reference to boost::program_options in xubuntu). To build Boost with a custom compiler (the default compiler of the server is terribly outdated), I followed the instructions here.

Some further search reveals that this is a linking problem. The 3rd party library must be built by CMake, and I followed the instruction in an answer to a previous question (How to link C++ program with Boost using CMake), by adding this line to CMakeLists.txt in the root directory of the 3rd party library:

target_link_libraries(Shannon_RNASeq_Cpp ${Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE})

However, the same problem persists. I checked the file CMakeCache.txt, and confirmed that the desired compiler is used and Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE points to the libboost_program_options.so in the directory where I put Boost 1.68.0 (the server has other older versions of Boost). I then used make VERBOSE=1 to check the bash commands invoked while building the library. The command doesn't sound wrong; the Boost program_options library has been linked; here's the command from make VERBOSE=1:

/usr/bin/cmake3 -E cmake_link_script CMakeFiles/Shannon_RNASeq_Cpp.dir/link.txt --verbose=1

It's referring to something in link.txt, and here's what I found there:

/home/lambda/mylibs/bin/c++  -g  -rdynamic CMakeFiles/Shannon_RNASeq_Cpp.dir/src/main.cpp.o 
CMakeFiles/Shannon_RNASeq_Cpp.dir/src/run_tasks.cpp.o  -o 
Shannon_RNASeq_Cpp lib_shannon/libmulti_graph_handler.a 
lib_shannon/libcontig_graph_handler.a lib_shannon/libprimary_lib.a 
-lboost_program_options lib_shannon/libsparse_flow_handler.a 
-lglpk lib_shannon/libseq_graph_handler.a -lpthread 
-lboost_system -Wl,-Bstatic -lmetis -Wl,-Bdynamic -lboost_filesystem 
-lboost_program_options 

So yes, Boost program_options has been linked (-lboost_program_options). I wonder if this is something wrong with program_options, since all errors that occurred at this stage are from program_options; I also linked to 2 other Boost compiled libraries, namely filesystem and system, and they do not appear in any error message I saw here.

I solved this problem myself (see my answer below), but new to CMake (and my only experiences with C++ is Rcpp), I don't know why it worked. Can someone please explain why switching to a static library worked? Also, when CMake linked to the default version of Boost on the server, it also by default used the .sos rather than the .as, even though the .as are available. Is there any way to tell CMake to use the .as rather than the .sos? Are there other solutions?

1

1 Answers

0
votes

What I did was to change all the .sos in CMakeCache.txt into .as, like I changed libboost_program_options.so into libboost_program_options.a, and this error went away. Then the command from make VERBOSE=1 became:

/home/lambda/mylibs/bin/c++  -g  -rdynamic CMakeFiles/Shannon_RNASeq_Cpp.dir/src/main.cpp.o 
CMakeFiles/Shannon_RNASeq_Cpp.dir/src/run_tasks.cpp.o  
-o Shannon_RNASeq_Cpp lib_shannon/libmulti_graph_handler.a 
lib_shannon/libcontig_graph_handler.a lib_shannon/libprimary_lib.a 
-Wl,-Bstatic -lboost_program_options lib_shannon/libsparse_flow_handler.a 
-Wl,-Bdynamic -lglpk lib_shannon/libseq_graph_handler.a -lpthread 
-Wl,-Bstatic -lboost_system -lmetis -lboost_filesystem -lboost_program_options -Wl,-Bdynamic