【问题标题】:linking boost libaries using cmake 2.8.8使用 cmake 2.8.8 链接 boost 库
【发布时间】:2014-06-18 01:40:37
【问题描述】:

我正在努力解决我在 stackoverflow 和其他论坛上搜索的 cmake-baed boost 链接问题,但无济于事。

我正在一个已经安装了 Boost 的集群上编译一个 C++ 程序套件(取决于不同的库,除了 Boost)(我知道完整路径)。在编译时遇到奇怪的 boost 与 cmake 的链接错误后,我想到了首先编译一个非常简单的 boost-cmake 示例来解决问题。

代码如下。

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/option.hpp>
using namespace std;
#include <iostream>

namespace po = boost::program_options;

int main(int argc, char** argv) {

po::options_description desc("Allowed options");
desc.add_options()
    ("help", "produce help message")
    ;

return 0;
}

我正在使用以下 CMakeLists.txt 文件进行构建。

cmake_minimum_required(VERSION 2.8)
set(Boost_INCLUDE_DIR /software/apps/boost/1.55.0/build06/include) 
set(Boost_LIBRARY_DIR /software/apps/boost/1.55.0/build06/lib)

find_package(Boost COMPONENTS program_options REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
link_directories(${Boost_LIBRARY_DIR})

message("Boost include dir is ${Boost_INCLUDE_DIR}")
message("Boost library dir is ${Boost_LIBRARY_DIR}")
message("Boost libraries are at ${Boost_LIBRARIES}")

add_executable(main main.cpp)
target_link_libraries( main ${Boost_LIBRARIES} )

当我使用 cmake 编译时,我得到以下输出

    x_ikrul@ikramu build]$  emacs ../CMakeLists.txt
Display localhost:39.0 unavailable, simulating -nw
[x_ikrul@triolith1 build]$ rm -rf *
[x_ikrul@triolith1 build]$ cmake ..
-- The C compiler identification is GNU 4.7.2
-- The CXX compiler identification is GNU 4.7.2
-- Check for working C compiler: /software/apps/comp_wrapper/gnu/gcc
-- Check for working C compiler: /software/apps/comp_wrapper/gnu/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /software/apps/comp_wrapper/gnu/c++
-- Check for working CXX compiler: /software/apps/comp_wrapper/gnu/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
Boost  found.
Found Boost components:
program_options
Boost include dir is /usr/include
Boost library dir is /software/apps/boost/1.55.0/build06/lib
Boost libraries are at optimized;boost_program_options-mt-shared;debug;boost_program_options-mt-shared-debug
-- Configuring done
-- Generating done
-- Build files have been written to: /home/x_ikrul/Downloads/boost_example/build

当我“制作”下面给出的代码时,问题就来了。

    x_ikrul@ikramu build]$make 
Scanning dependencies of target main
[100%] Building CXX object CMakeFiles/main.dir/main.cpp.o
make[2]: *** No rule to make target `/usr/lib64/lib64/libboost_program_options-mt.so.5', needed by `main'.  Stop.
make[1]: *** [CMakeFiles/main.dir/all] Error 2
make: *** [all] Error 2

如您所见,尽管 CMake 显示 boost 的 lib 目录为 /software/apps/boost/1.55​​.0/build06/lib,但奇怪的是,在链接时,它指的是另一个不存在的目录。

有人遇到过这样的错误吗?集群运行 CentOS 6.5 版,boost(我指的地方)是 1.55.0,我使用的 cmake 是 2.8.8。

【问题讨论】:

  • 您的 boost 包含目录也未正确找到? Boost include dir is /usr/include
  • 你是对的。事实上,当我在具有相同版本的 cmake/boost 的不同集群上尝试此示例时,一切都很顺利,但在当前机器上,它给出了这些奇怪的错误。

标签: c++ boost centos cmake


【解决方案1】:

您没有正确设置提示路径。

来自FindBoost module docs

此模块从变量中读取有关搜索位置的提示:

BOOST_ROOT - 首选安装前缀 (或 BOOSTROOT)

BOOST_INCLUDEDIR - 首选包含目录,例如&lt;prefix&gt;/include

BOOST_LIBRARYDIR - 首选库目录,例如&lt;prefix&gt;/lib

Boost_NO_SYSTEM_PATHS - 设置为 ON 以禁用在不搜索的位置进行搜索 由这些提示变量指定。默认为OFF

...

并将搜索结果永久保存在 CMake 缓存条目中:

Boost_INCLUDE_DIR - 包含 Boost 标头的目录

Boost_LIBRARY_DIR - 包含 Boost 库的目录

那么,你的台词:

set(Boost_INCLUDE_DIR /software/apps/boost/1.55.0/build06/include) 
set(Boost_LIBRARY_DIR /software/apps/boost/1.55.0/build06/lib)

实际上并没有设置提示变量——你想设置BOOST_INCLUDEDIRBOOST_LIBRARYDIR;也可能是Boost_NO_SYSTEM_PATHS

最好不要在 CMakeLists.txt 中硬编码,因为它不可移植。而是在调用 CMake 时在命令行上传递这些:

cmake . -DBOOST_INCLUDEDIR=/software/apps/boost/1.55.0/build06/include -DBOOST_LIBRARYDIR=/software/apps/boost/1.55.0/build06/lib -DBoost_NO_SYSTEM_PATHS=ON

如果您将Boost_DEBUG 设置为ON,您还可以更好地了解正在发生的事情。

顺便说一句,您不应该需要 link_directories 调用,因为 Boost 库的完整路径在 target_link_libraries 调用中传递。

【讨论】:

  • 我试过了,当我打印 BOOST_INCLUDEDIR 和 BOOST_LIBRARYDIR 时,它们没有输出这个路径。我尝试使用 BOOST_LIBRARY_DIR/BOOST_LIBRARY_DIRS 和 BOOST_INCLUDE_DIR/BOOST_INCLUDE_DIRS 但无法成功。我在不同的集群上尝试了代码/脚本,它们在那里编译得很愉快。您认为可能与其他加载的库发生冲突吗?感谢您的帮助:-)
  • 这些值可能在控制到达 FindCMake 模块之前在其他地方设置/覆盖。您能否更新您的问题,说明您是如何设置这些的,在 CMakeLists.txt 中的哪个位置打印它们,以及cmake . -DBoost_DEBUG=ON 的输出是什么?
  • 我终于能够使用 BOOST_ROOT、BOOST_INCLUDEDIR 和 BOOST_LIBRARYDIR 链接预期的路径。我最初很困惑是使用 BOOST_INCLUDE_DIRS 还是 BOOST_INCLUDE_DIRS(输入和输出变量)。这个答案说得很清楚。非常感谢人...
  • 就我而言,另一个潜在的问题来源可能是集群上存在 GCC 和 intel 编译器(以及每种情况下的许多版本)。我认为我还需要非常严格地跟踪版本(构建不同库的版本)。
【解决方案2】:

这个stackoverflow answer 建议在cmake 命令行上添加-DBoost_NO_BOOST_CMAKE=ON

这似乎是由于某些 CMake 版本与某些 Boost 版本不能很好地配合造成的。

我同意用户弗雷泽所说的。这些行没有意义

set(Boost_INCLUDE_DIR /software/apps/boost/1.55.0/build06/include) 
set(Boost_LIBRARY_DIR /software/apps/boost/1.55.0/build06/lib)

因为 CMake 使用这些变量来存储 Boost 搜索的结果。在他的回答中了解更多信息。

【讨论】:

  • 你说得对,我现在已经从 CMakeLists.txt 中删除了 set(.) 行以使其更加透明。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 2018-09-25
  • 1970-01-01
  • 2019-01-31
  • 1970-01-01
相关资源
最近更新 更多