我正在尝试从源代码构建第三方C ++库,这取决于Boost。在构建的最后一步,我得到了如下错误:
[ 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)'
我在StackOverflow上搜索了其他问题(例如Boost Program Options link error),最初认为这是由用于构建Boost的非标头部分的不同编译器引起的,因此我下载了Boost 1.68.0的源代码并使用与构建第3方库(编译器为gcc 8.2.0)相同的编译器将其构建在我的个人目录中,从错误消息中,我可以确定使用了C ++ 11标准(您可以看到错误消息中的cxx11
),因此不可能像先前所假设的那样,不支持C ++ 11的编译器引起麻烦。为了使用自定义编译器构建Boost(服务器的默认编译器已经过时了),我遵循了undefined reference to boost::program_options in xubuntu的说明。
一些进一步的搜索显示这是一个链接问题。第三方库必须由CMake构建,并且我将上一行添加到第三方库的根目录中的CMakeLists.txt
中来遵循上一个问题(here)的说明:
target_link_libraries(Shannon_RNASeq_Cpp ${Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE})
但是,相同的问题仍然存在。我检查了文件CMakeCache.txt
,并确认已使用所需的编译器,并且Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE
指向我放置Boost 1.68.0的目录中的libboost_program_options.so
(服务器具有其他较旧的版本促进)。然后,我使用make VERBOSE=1
检查在构建库时调用的bash命令。该命令听起来没有错; Boost program_options库已链接;这是来自make VERBOSE=1
的命令:
/usr/bin/cmake3 -E cmake_link_script CMakeFiles/Shannon_RNASeq_Cpp.dir/link.txt --verbose=1
它是指link.txt
中的某物,这是我在那发现的:
/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
是的,Boost program_options已被链接(-lboost_program_options)。我不知道program_options是否有问题,因为在此阶段发生的所有错误均来自program_options。我还链接了另外2个Boost编译库,即文件系统和系统,它们没有出现在我在这里看到的任何错误消息中。
我自己解决了这个问题(请参阅下面的答案),但是对CMake还是陌生的(我对C ++的唯一经验是Rcpp
),我不知道它为什么起作用。有人可以解释一下为什么切换到静态库有效吗?另外,当CMake链接到服务器上默认的Boost版本时,即使.so
可用,它默认也使用.a
而不是.a
。有什么方法可以告诉CMake使用.a
而不是.so
?还有其他解决方案吗?
答案 0 :(得分:0)
我所做的是将.so
中的所有CMakeCache.txt
更改为.a
,就像我将libboost_program_options.so
更改为libboost_program_options.a
一样,此错误消失了。远。然后来自make VERBOSE=1
的命令变为:
/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