使用msvc中的cmake构建一个boost项目

时间:2018-06-17 15:17:24

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

我编写了一个代码来直接读取压缩文件。我必须使用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" .

这会抛出在cmake

期间找不到的错误boost_zlib
  

无法找到以下Boost库:
               boost_zlib

我在所有路径中内置了以下zlib库:

enter image description here

注意如果我将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()时它工作正常。

1 个答案:

答案 0 :(得分:0)

将我的评论扩展到答案:

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

  • 回答问题的第一部分:

    从您的zlib电话中

    删除 find_package

执行此操作后,请删除CMakeCache.txt文件,因为Boost搜索的值已缓存在CMake中。

  • 回答问题的第二部分:

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

您在映像中显示的库是(多线程)静态库 DLL的导入库。

  • 使用静态库

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

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

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

<强> NB:

请取消对include_directories(${Boost_INCLUDE_DIR})的通话,并在目标定义后添加

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

请注意变量名称中的尾随S。此变量在find_package(Boost ..)调用中分配了一个值,另一个变量用于查找Boost的include目录,并且是FindBoost模块的输入。这样做只会将include目录添加到目标,但不会添加到全局环境。

最后,您应该在-DBOOST_ROOT=<path_to_your_Boost_installation>命令行调用中添加CMake,以确保找到Boost,无论非标准安装目录如何。

有关find_package(Boost ...)的详细信息,请参阅documentation