如何将Boost库与CMake链接(如果boost位于非标准位置,则在群集上)?

时间:2017-03-21 14:35:21

标签: c++ boost cmake

当我尝试在群集上构建一个简单的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

1 个答案:

答案 0 :(得分:0)

感谢Amadeus,Someprogrammerdude和Tsyvarev带领我朝着正确的方向前进:)

实际上,这是一个编译器问题:集群上的默认编译器是gcc-4.8.5,它无法处理最新的Boost版本。因此,我们为gcc-5.4加载了一个模块,但/ usr / bin / gcc仍然是gcc-4.8.5。当我们将cmake的cxx编译器设置为gcc-5.4时,构建过程仍然失败,因为我们也使用CUDA,并且默认情况下主机代码不会转发到cxx编译器,而是c编译器,它仍然是gcc-4.8.5。所以在将CUDA_HOST_COMPILER设置为CMAKE_CXX_COMPILER后,它现在可以正常工作。