【发布时间】:2017-03-21 14:35:21
【问题描述】:
当我尝试在集群上构建一个简单的 Boost 测试程序时,我遇到了一个奇怪的问题。 在我的机器上,一切正常。
首先是例子:
//main.cpp
#include <iostream>
#include <string>
#include "boost/program_options.hpp"
namespace po = boost::program_options;
int main( int argc , char* argv[] ) {
po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("greet", po::value<std::string>()->default_value("World"), "the greeting")
;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
std::cout << "Hello, " << vm["greet"].as<std::string>() << "!" << std::endl;
return 0;
}
还有 CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(boost_test)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
find_package(Boost COMPONENTS program_options)
set(SOURCE_FILES main.cpp)
if(Boost_FOUND)
add_executable(boost_test ${SOURCE_FILES})
target_include_directories(boost_test PRIVATE ${Boost_INCLUDE_DIRS})
target_link_libraries(boost_test PRIVATE ${Boost_LIBRARIES})
endif(Boost_FOUND)
我使用 cmake 之类的
cmake -G "Unix Makefiles" /path/to/code
make
我得到的错误是链接期间未定义的引用错误:
Linking CXX executable boost_test
CMakeFiles/boost_test.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x6d): undefined reference to `boost::program_options::options_description::options_description(std::string const&, unsigned int, unsigned int)'
CMakeFiles/boost_test.dir/main.cpp.o: In function `boost::program_options::variables_map::operator[](std::string const&) const':
main.cpp:(.text._ZNK5boost15program_options13variables_mapixERKSs[_ZNK5boost15program_options13variables_mapixERKSs]+0x1f): undefined reference to `boost::program_options::abstract_variables_map::operator[](std::string const&) const'
等等……
所以我想可能是boost的安装不正确,我尝试自己写了一个makefile。
boost-test-1: ../code/main.cpp
g++ ../code/main.cpp -o boost-test-1 -lboost_program_options
boost-test-2: ../code/main.cpp
g++ ../code/main.cpp -o boost-test-2 /some/fancy/cluster/path/certainly/non/standard/Boost/lib/libboost_program_options.so
构建程序的两种方法都可以正常工作。但是cmake所做的基本上如下:首先,构建一个目标文件,然后将目标文件和库链接在一起,然后失败了。
boost-test-3: ../code/main.cpp
/usr/bin/c++ -I/some/fancy/cluster/path/certainly/non/standard/Boost/include -std=c++11 -o main.cpp.o -c ../code/main.cpp
/usr/bin/c++ -std=c++11 main.cpp.o -o boost-test-3 /some/fancy/cluster/path/certainly/non/standard/Boost/lib/libboost_program_options.so
如前所述,在我的计算机上所有描述的构建程序的方法都可以工作,但在集群上,cmake 方法不幸失败了。问题是我有另一个使用 cmake 的大型项目,我正在寻找一种在该特定集群上构建它的方法。
您知道导致问题的原因以及解决方法吗? 谢谢!
更新:这是构建过程的全部输出。我缩短了 cmake 的路径并将其提升为“path/to/cmake”和“path/to/boost”以使其更短且可读性更好,但它与上述相同的长路径。
$ cmake -G "Unix Makefiles" ../code/
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Boost version: 1.61.0
-- Found the following Boost libraries:
-- program_options
-- Boost include directories (Boost_INCLUDE_DIRS): /path/to/Boost/include
-- Link directories for Boost libraries (Boost_LIBRARY_DIRS): /path/to/Boost/lib
-- Boost component libraries to be linked (Boost_LIBRARIES): /path/to/Boost/lib/libboost_program_options.so
-- Configuring done
-- Generating done
-- Build files have been written to: /home/test/build
$ make VERBOSE=1
/path/to/CMake/bin/cmake -H/home/test/code -B/home/test/build --check-build-system CMakeFiles/Makefile.cmake 0
/path/to/CMake/bin/cmake -E cmake_progress_start /home/test/build/CMakeFiles /home/test/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/home/test/build'
make -f CMakeFiles/boost_test.dir/build.make CMakeFiles/boost_test.dir/depend
make[2]: Entering directory `/home/test/build'
cd /home/test/build && /path/to/CMake/bin/cmake -E cmake_depends "Unix Makefiles" /home/test/code /home/test/code /home/test/build /home/test/build /home/test/build/CMakeFiles/boost_test.dir/DependInfo.cmake --color=
Dependee "/home/test/build/CMakeFiles/boost_test.dir/DependInfo.cmake" is newer than depender "/home/test/build/CMakeFiles/boost_test.dir/depend.internal".
Dependee "/home/test/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/test/build/CMakeFiles/boost_test.dir/depend.internal".
Scanning dependencies of target boost_test
make[2]: Leaving directory `/home/test/build'
make -f CMakeFiles/boost_test.dir/build.make CMakeFiles/boost_test.dir/build
make[2]: Entering directory `/home/test/build'
[ 50%] Building CXX object CMakeFiles/boost_test.dir/main.cpp.o
/usr/bin/c++ -I/path/to/Boost/include -std=c++11 -o CMakeFiles/boost_test.dir/main.cpp.o -c /home/test/code/main.cpp
[100%] Linking CXX executable boost_test
/path/to/CMake/bin/cmake -E cmake_link_script CMakeFiles/boost_test.dir/link.txt --verbose=1
/usr/bin/c++ -std=c++11 CMakeFiles/boost_test.dir/main.cpp.o -o boost_test /path/to/Boost/lib/libboost_program_options.so
CMakeFiles/boost_test.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x6d): undefined reference to `boost::program_options::options_description::options_description(std::string const&, unsigned int, unsigned int)'
CMakeFiles/boost_test.dir/main.cpp.o: In function `boost::program_options::variables_map::operator[](std::string const&) const':
main.cpp:(.text._ZNK5boost15program_options13variables_mapixERKSs[_ZNK5boost15program_options13variables_mapixERKSs]+0x1f): undefined reference to `boost::program_options::abstract_variables_map::operator[](std::string const&) const'
CMakeFiles/boost_test.dir/main.cpp.o: In function `boost::program_options::basic_command_line_parser<char>::basic_command_line_parser(int, char const* const*)':
main.cpp:(.text._ZN5boost15program_options25basic_command_line_parserIcEC2EiPKPKc[_ZN5boost15program_options25basic_command_line_parserIcEC5EiPKPKc]+0x76): undefined reference to `boost::program_options::detail::cmdline::cmdline(std::vector<std::string, std::allocator<std::string> > const&)'
CMakeFiles/boost_test.dir/main.cpp.o: In function `boost::program_options::basic_command_line_parser<char>::extra_parser(boost::function1<std::pair<std::string, std::string>, std::string const&>)':
main.cpp:(.text._ZN5boost15program_options25basic_command_line_parserIcE12extra_parserENS_9function1ISt4pairISsSsERKSsEE[_ZN5boost15program_options25basic_command_line_parserIcE12extra_parserENS_9function1ISt4pairISsSsERKSsEE]+0x33): undefined reference to `boost::program_options::detail::cmdline::set_additional_parser(boost::function1<std::pair<std::string, std::string>, std::string const&>)'
CMakeFiles/boost_test.dir/main.cpp.o: In function `std::vector<std::string, std::allocator<std::string> > boost::program_options::to_internal<std::string>(std::vector<std::string, std::allocator<std::string> > const&)':
main.cpp:(.text._ZN5boost15program_options11to_internalISsEESt6vectorISsSaISsEERKS2_IT_SaIS5_EE[_ZN5boost15program_options11to_internalISsEESt6vectorISsSaISsEERKS2_IT_SaIS5_EE]+0x46): undefined reference to `boost::program_options::to_internal(std::string const&)'
CMakeFiles/boost_test.dir/main.cpp.o:(.rodata._ZTVN5boost15program_options11typed_valueISscEE[_ZTVN5boost15program_options11typed_valueISscEE]+0x40): undefined reference to `boost::program_options::value_semantic_codecvt_helper<char>::parse(boost::any&, std::vector<std::string, std::allocator<std::string> > const&, bool) const'
CMakeFiles/boost_test.dir/main.cpp.o: In function `boost::program_options::typed_value<std::string, char>::name() const':
main.cpp:(.text._ZNK5boost15program_options11typed_valueISscE4nameEv[_ZNK5boost15program_options11typed_valueISscE4nameEv]+0x32): undefined reference to `boost::program_options::arg'
CMakeFiles/boost_test.dir/main.cpp.o: In function `boost::program_options::typed_value<std::string, char>::xparse(boost::any&, std::vector<std::string, std::allocator<std::string> > const&) const':
main.cpp:(.text._ZNK5boost15program_options11typed_valueISscE6xparseERNS_3anyERKSt6vectorISsSaISsEE[_ZNK5boost15program_options11typed_valueISscE6xparseERNS_3anyERKSt6vectorISsSaISsEE]+0x7a): undefined reference to `boost::program_options::validate(boost::any&, std::vector<std::string, std::allocator<std::string> > const&, std::string*, int)'
collect2: error: ld returned 1 exit status
make[2]: *** [boost_test] Error 1
make[2]: Leaving directory `/home/test/build'
make[1]: *** [CMakeFiles/boost_test.dir/all] Error 2
make[1]: Leaving directory `/home/test/build'
make: *** [all] Error 2
【问题讨论】:
-
您知道 Boost 安装在“集群的哪个位置”?而且您已经阅读了有关 the FindBoost module 的信息,尤其是有关告诉它在哪里可以找到 Boost 的“提示”?
-
通常
libboost_program_options.so是一个符号链接。你确定它没有坏吗? -
@some 程序员老兄:是的,我愿意。我可能没有明确指出:cmake 找到了 boost 安装,并且 Boost_INCLUDE_DIRS 和 Boost_LIBRARY_DIRS 包含正确的路径。但是,链接失败...
-
这是有道理的。如果您运行详细的 make (
make VERBOSE=1) 并查看正在执行的实际命令,链接时是否使用了正确的标志和库? -
@Amadeus:似乎 libboost_program_options.so 不是符号链接。我试过 if [ -L libboost_program_options.so ];然后回显“是”;否则回显“否”; fi (有没有更好的方法?;))我得到“不”。