【问题标题】:Cannot link boost libraries with CMake无法将 boost 库与 CMake 链接
【发布时间】:2019-01-31 08:47:51
【问题描述】:

我有一个使用 boost(程序选项模块)的示例 C++ 代码,如下所示:

#include <iostream>

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

namespace po = boost::program_options;

int main(int argc, const char* argv[]){
    po::options_description description("MyTool Usage");

    description.add_options()
        ("help,h", "Display this help message")
        ("version,v", "Display the version number");

    po::positional_options_description p;

    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm);
    po::notify(vm);

    if(vm.count("help")){
        std::cout << description;

        return 0;
    }

    if(vm.count("version")){
        std::cout << "MyTool Version 1.0" << std::endl;

        return 0;
    }

    return 0;
}

我尝试使用 cmake 进行编译。对应的CMakeLists.txt文件如下:

cmake_minimum_required(VERSION 2.6)

set(CMAKE_CXX_LINK_FLAGS "-std=c++11 -g -Wall -fsigned-char -lboost_program_options-mt")

set(BOOST_ROOT /opt/local/include/boost)
set(BOOST_LIBRARYDIR /opt/local/lib)
find_package(Boost COMPONENTS program_options system filesystem REQUIRED)
include_directories(${BOOST_INCLUDE_DIR})
link_libraries(${BOOST_LIBRARIES})

add_executable(testboostpo testboostpo_simple.cpp)
target_link_libraries(testboostpo ${Boost_LIBRARIES})

虽然cmake . 似乎成功了,而且它还检测到了我通常使用的所有 boost 模块(程序选项、系统、文件系统),

$ cmake .
-- The C compiler identification is GNU 5.5.0
-- The CXX compiler identification is GNU 5.5.0
-- Checking whether C compiler has -isysroot
-- Checking whether C compiler has -isysroot - yes
-- Checking whether C compiler supports OSX deployment target flag
-- Checking whether C compiler supports OSX deployment target flag - yes
-- Check for working C compiler: /opt/local/bin/gcc-mp-5
-- Check for working C compiler: /opt/local/bin/gcc-mp-5 -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Checking whether CXX compiler has -isysroot
-- Checking whether CXX compiler has -isysroot - yes
-- Checking whether CXX compiler supports OSX deployment target flag
-- Checking whether CXX compiler supports OSX deployment target flag - yes
-- Check for working CXX compiler: /opt/local/bin/g++-mp-5
-- Check for working CXX compiler: /opt/local/bin/g++-mp-5 -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Boost version: 1.66.0
-- Found the following Boost libraries:
--   program_options
--   system
--   filesystem
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/params/libraries/coding_interview/every_test/boost_test

下一步 make 失败并出现以下错误: $ 制作

Scanning dependencies of target testboostpo
[ 50%] Building CXX object CMakeFiles/testboostpo.dir/testboostpo_simple.cpp.o
[100%] Linking CXX executable testboostpo
ld: library not found for -lboost_program_options-mt
collect2: error: ld returned 1 exit status
make[2]: *** [testboostpo] Error 1
make[1]: *** [CMakeFiles/testboostpo.dir/all] Error 2
make: *** [all] Error 2

链接程序选项的 boost 库似乎有问题。但是,我可以看到该库安装在/opt/local/lib/libboost_program_options-mt.dylib

另外,我也尝试隔离编译,但它也失败了。

$ g++ -L/opt/local/lib testboostpo_simple.cpp -lboost_program_options-mt
Undefined symbols for architecture x86_64:
  "boost::program_options::to_internal(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)", referenced from:
      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> > > > boost::program_options::to_internal<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(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&) in ccg8tggM.o
  ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

$ g++ -L/opt/local/lib testboostpo_simple.cpp /opt/local/lib/libboost_program_options-mt.dylib
Undefined symbols for architecture x86_64:
  "boost::program_options::to_internal(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)", referenced from:
      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> > > > boost::program_options::to_internal<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(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&) in ccg8tggM.o
  ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

我正在使用 gcc5、boost 1.66 和 cmake 3.12(它们都使用 macports 安装)。 boost头文件的位置: /opt/local/include/boost/ 并且 boost 库文件位于: /opt/local/lib

这里有没有人知道尽管提供了路径,但可能导致提升链接仍然失败的原因是什么?这里还有什么遗漏或指定错误吗?

谢谢,

【问题讨论】:

    标签: c++ c++11 gcc boost cmake


    【解决方案1】:

    因为你已经使用了CMAKE_CXX_LINK_FLAGS,并且cmake会先检查它而不是使用你的target_link_libraries,如果你想自己做,你也需要添加-L/opt/local/lib,更简单的方法是让 cmake 为你做。以下是我的例子:

    cmake_minimum_required(VERSION 2.6)
    project(server CXX)
    set(CXX_FLAGS
    -g
    -Wall
    )
    
    # set(Boost_NO_SYSTEM_PATHS ON)
    set(BOOST_ROOT /mnt/d/Code/boost)
    set(BOOST_LIBRARYDIR /mnt/d/Code/boost/stage/lib)
    find_package(Threads REQUIRED)
    find_package(Boost 1.68.0 COMPONENTS program_options REQUIRED)
    file(GLOB SRC 
     "*cpp*"
     )
    if(Boost_FOUND)
      include_directories(${Boost_INCLUDE_DIRS})
      message(${Boost_PROGRAM_OPTIONS_LIBRARIES})
      add_executable(main ${SRC})
      target_link_libraries(main Threads::Threads ${Boost_PROGRAM_OPTIONS_LIBRARIES})
    endif()
    

    另外,如果你单独构建它,你应该先编译对象然后链接,否则它可能会变成未定义的引用。在你的情况下,你应该最后链接,当你把链接放在前面或后面时,结果会有所不同,对不起,我不知道为什么会发生这种情况。

    【讨论】:

    • 谢谢。如上所示,我还尝试了以下两个命令,但似乎都失败了: $ g++ -L/opt/local/lib testboostpo_simple.cpp -lboost_program_options-mt AND $ g++ -L/opt/local/lib testboostpo_simple.cpp /opt/local/lib/libboost_program_options-mt.dylib
    • 我刚刚尝试使用您的 CMakeLists.txt 文件。它仍然失败并出现相同的错误。您对这里可能出现的其他问题有任何想法吗?
    • 我的例子仅供参考。 $ g++ testboostpo_simple.cpp -L/opt/local/lib /opt/local/lib/libboost_program_options-mt.dylib 应该可以工作。
    • 此外,更改配置后,请删除 CMakeCache.txt 以重新创建一个。
    • 谢谢,是的,这个命令应该可以工作,但不能。我有一个清理 CMakeFiles/*、CMakeCache.txt 和 cmake_install.cmake 的脚本。我每次运行 cmake 之前都会运行它。所以我认为这不是问题。它似乎因不同的原因而失败。
    【解决方案2】:

    您似乎正在尝试将 32 位库与 64 位构建链接。提示是ld: symbol(s) not found for architecture x86_64

    链接库要求您匹配确切的构建类型。以下是有关链接过程的更多信息。

    https://www.boost.org/doc/libs/1_63_0/more/getting_started/windows.html

    【讨论】:

    • 看来我确实在使用 64 位库。你怎么看? $ file /opt/local/lib/libboost_filesystem-mt.dylib --&gt; gives the output --&gt; /opt/local/lib/libboost_filesystem-mt.dylib: Mach-O universal binary with 2 architectures: [i386:Mach-O dynamically linked shared library i386] [x86_64:Mach-O 64-bit dynamically linked shared library x86_64] /opt/local/lib/libboost_filesystem-mt.dylib (for architecture i386): Mach-O dynamically linked shared library i386
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    • 2015-09-21
    相关资源
    最近更新 更多