【问题标题】:Build a boost project using cmake in msvc在 msvc 中使用 cmake 构建一个 boost 项目
【发布时间】:2018-11-26 14:53:19
【问题描述】:

我写了一个代码来直接读取压缩文件。我必须使用 Cmake 构建它。这是我唯一的源文件,uncompress.cpp

#include <iostream>
#include <vector>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
// cl /EHsc uncompress.cpp

std::vector<char> & readline(std::istream & stream, std::vector<char> & container) {
    char c;
    container.clear();
    while (stream && stream.get(c)) {
        container.push_back(c);
        if (c == '\n') break;
    }
    return container;
}

int main () {
    boost::iostreams::filtering_istream in;
    boost::iostreams::filtering_istream cinn(std::cin);
    in.push(boost::iostreams::bzip2_decompressor());
    in.push(cinn);

    std::vector<char> line;
    while (readline(in, line).size() != 0) {
        std::string str(line.begin(), line.end());
        std::cout << "--" << str ;
    }
}

我的 CMakeLists.txt 包括

cmake_minimum_required (VERSION 2.8.9)
project (reader-demo CXX C)

find_package (Boost COMPONENTS iostreams zlib REQUIRED)
include_directories (${Boost_INCLUDE_DIR} )

add_executable(reader uncompress.cpp)
target_link_libraries(reader ${Boost_LIBRARIES})

我的 cmake 命令是:

cmake -G "NMake Makefiles" .

这会抛出错误 boost_zlib not found during cmake

找不到以下 Boost 库:
boost_zlib

我已正确设置所有路径中内置的以下 zlib 库:

注意 如果我将 CMakeLists.txt 更改为此。它工作正常。但我不明白如何:/

cmake_minimum_required (VERSION 2.8.9)
project (reader-demo CXX C)

add_executable(reader uncompress.cpp)

它按预期工作正常。 reader.exe 是 make 并且运行良好。

我的问题是:为什么我在 cmake 中提到它时找不到 boost_zlib,为什么当我删除 target_link_libraries() 时它工作正常。

【问题讨论】:

  • 您找到的库是静态库而不是 DLL。要使用静态库,您需要将set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) 添加到您的CMakeLists.txt 文件之前 find_package(Boost ...) 调用。并且您应该将-DBOOST_ROOT=&lt;path_to_your_Boost_installation&gt; 添加到您的 CMake 命令行调用中,以确保无论非标准安装目录如何都能找到 Boost。
  • 顺便说一句,您在 Boost 1.67 中使用的是哪个版本的 CMake?
  • 我的 cmake 版本是 3.11.2 @vre
  • 在对CMakeLists.txt 进行更改后,您是否总是删除CMakeCache.txt 文件? Boost 搜索的值缓存在 CMake 中,您不会直接在 cpp 文件中引用任何与 boost_zlib 相关的内容。这可能是它在第二次调用中起作用的原因。
  • zlib 不是已注册的 Boost 组件,尽管 boost_iostreams 库的 Boost 构建过程会生成 boost_zlib 和 boost_bzip2 库。所以 FindBoost.cmake 不知道这些(它们是内部的)。

标签: c++ visual-c++ boost cmake


【解决方案1】:

将我的 cmets 扩展为答案:

zlib 不是注册的Boost 组件,尽管Boostboost_iostreams 构建过程会生成boost_zlibboost_bzip2 库。两者都是内部生成并链接到的。将find_package(Boost COMPONENTS iostreams zlib REQUIRED) 添加到CMakeLists.txt 文件时调用的CMake 模块FindBoost.cmake 不知道这些库。

  • 回答问题的第一部分:

    从您的 find_package 通话中删除 zlib

这样做后删除CMakeCache.txt 文件,因为Boost 搜索的值缓存在CMake 中。

  • 回答问题的第二部分:

    您从CMakeLists.txt 中删除了Boost 内容,但大概没有删除CMakeCache.txt。它可能仍然包含编译器/链接器所需的Boost 条目,这可能是它在第二次调用中起作用的原因。

图片中显示的库是(多线程)静态库 DLL 的导入库。

  • 使用静态库

    您需要在调用find_package(Boost ...) 之前将set(Boost_USE_STATIC_LIBS ON) 添加到您的CMakeLists.txt 文件中。

  • 使用共享对象 (SO)/动态链接库 (DLL)

    在调用find_package(Boost ...) 之前,您无需在CMakeLists.txt 文件中添加任何内容,因为默认情况下会选择动态链接库。但要运行可执行文件,必须将包含 DLL 的目录添加到 PATH 环境变量中。

注意:

请删除对include_directories(${Boost_INCLUDE_DIR})的调用并在你的目标定义之后添加

add_executable(reader uncompress)
target_include_directories(reader PRIVATE ${Boost_INCLUDE_DIRS})

注意变量名中的结尾S。这个变量在find_package(Boost ..)调用中被赋值,另一个变量用于查找Boost的包含目录并且是FindBoost模块的输入。这样做只会将包含目录添加到目标而不是全局环境。

最后,您应该将-DBOOST_ROOT=&lt;path_to_your_Boost_installation&gt; 添加到您的CMake 命令行调用中,以确保无论非标准安装目录如何都能找到Boost

有关find_package(Boost ...) 的更多信息,请参阅documentation

【讨论】:

    猜你喜欢
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多