c++ - 无法将 boost 库与 CMake 链接
问题描述
我有一个使用 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
失败并出现以下错误:$ 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
尽管提供了路径,这里有没有人知道可能导致提升链接仍然失败的原因?这里还有什么遗漏或指定错误吗?
谢谢,
解决方案
因为你已经使用了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()
此外,如果单独构建,则应先编译对象然后链接,否则可能会变成未定义的引用。在你的情况下,你应该最后链接,当你把链接放在前面或尾部时,结果会有所不同,对不起,我不知道为什么会发生这种情况。
推荐阅读
- sql - 如何按字段过滤包含另一个字段
- android - 如何将文件映射上传到php服务器
- javascript - 如何分别从数组中获取项目
- wpf - 如何将 IAsyncQuickInfoSource 工具提示中的 WPF 文本框的文本复制到剪贴板
- android - Flutter 正在同时安装两个应用
- c# - 运行所有 Start 方法后创建事件链
- php - 将邮件发送给电子邮件地址来自 Mysql 的不同用户
- mysql - 无法在 Redhat Openshift 上部署 MySQL
- linux - Electron Linux:.AppImage 未显示图标,而 .deb 显示
- python - python中的多处理错误'需要1个位置参数,但给出了2个'