2017-01-13 68 views
3

我有一点你好,世界我希望使用CMake以更加端到端的方式工作的样式程序。在这种情况下,这意味着我可以下载Boost库,编译它们,最后编译我的小小的Hello,World并将Boost库链接到它。HelloWorld:使用CMake下载,建立和链接Boost

的目录布局看起来像这样目前

 
cmaketest 
|- build //I would like to have here the CMake generated IDE files. 
|- src 
    |- main.cpp 
    |- hello.cpp 
    |- hello.hpp 
|- depends //I would like to have here the built Boost libraries and headers. 
|- downloads //This contains the downloaded zip file. 
|- temp //Temporary files. 

我有以下CMakeLists.txt,目前我生成在Visual Studio 2015年项目文件,如下所示:cmake build -G "Visual Studio 14 2015 Win64"。一切顺利,我将开始解决方案,CMake抱怨它无法找到Boost,去下载它开始建立(在下面的代码中,我已经设置为获取先前获取的文件)。但之后,建设一段时间后,问题出现...

  1. Boost文件似乎出现在\cmaketest\CMakeFiles\build\Boost-prefix\src\Boost作为根。我怎么能这些,所以他们会被建立到\depends\boost(或为此),以及如何将库链接到解决方案?这个链接是一个单独的问题,我知道如何从这个奇怪的目录中包含头文件,但这不是我想要的。
  2. 它看起来像VS IDE第一次警告Boost标题不会被发现(见主程序很快),然后启动Boost构建。这可以避免吗?
  3. 如何使Boost库从VS解决方案中消失?即不是为了制作它的项目,而只是依赖头文件和库?
  4. 如果Boost软件包已经在磁盘上,是否有内置的方法来避免下载?它看起来会在任何情况下被检索到,并且我想过检查文件的存在。

main.cpp(我想这是在这种情况下,相关的文件)

//The Boost headers are included just to check the linker. 
#include "hello.hpp" 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/date_time/posix_time/posix_time_io.hpp> 
#include <iostream> 
using std::cout; 
using std::endl; 

int main() 
{ 
    hello helloer; 
    cout << helloer.greet("World here") << endl; 

    return EXIT_SUCCESS; 
} 

然后是CMakeLists.txt文件。

cmake_minimum_required(VERSION 3.6 FATAL_ERROR) 
set(CMAKE_VERBOSE_MAKEFILE ON) 
project(Cmaketest) 

if(POLICY CMP0042) 
    cmake_policy(SET CMP0042 NEW) 
endif() 

if(POLICY CMP0066) 
    cmake_policy(SET CMP0066 NEW) 
endif() 

# Default build type if none was specified. 
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 
    set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) 
    message(STATUS "Setting build type to '${CMAKE_BUILD_TYPE} as none was specified.") 

    # Possible values of build type for CMake GUI. 
    set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") 
endif() 

# The path to extra modules. 
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) 

# Setup build locations. 
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) 
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 
endif() 
set(CMAKE_CURRENT_BINARY_DIR  
${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/build) 

set(CMAKE_CXX_STANDARD 11) 
set(CMAKE_CXX_STANDARD_REQUIRED ON) 
set(CMAKE_CXX_EXTENSIONS OFF) 

include(ExternalProject) 
include(ProcessorCount) 
ProcessorCount(N) 
if(NOT N EQUAL 0) 
    set(CMAKE_BUILD_FLAGS -j${N}) 
endif() 
# set(BOOST_VERSION 1.63.0) 
# Boost related settings:  
# https://cmake.org/cmake/help/v3.6/module/FindBoost.html. 
# Should one check the environment variables and flags here explicitly 
# to remove the complaint about missing Boost library? Or should perhaps 
# BOOST_ROOT be set? Point to what? 
find_package(Boost) 
if(NOT Boost_FOUND) 
    # It shouldn't hurt to enable extensive diagnostics, just in case. 
    # Also, a different set of files is downloaded for UNIX and WIN32 
    # due to file permissions and line-feeds (Windows should handle 
    # also Unix style line-feeds). 
    set(Boost_DETAILED_FAILURE_MSG on) 
    add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS}) 
    set(Boost_Bootstrap_Command) 
    if(UNIX) 
     set(Boost_Url  "http://sourceforge.net/projects/boost/files/boost/1.63.0/boost_1_63_0.tar.gz") 
     set(Boost_Sha1 "2cecf1848a813de55e5770f324f084c568abca0a") 
     set(Boost_Bootstrap_Command ./bootstrap.sh) 
     set(Boost_b2_Command ./b2) 
    elseif(WIN32) 
     set(Boost_Url "http://sourceforge.net/projects/boost/files/boost/1.63.0/boost_1_63_0.zip") 
     set(Boost_Sha1 "4364989afbe6b11f2d5e59df902c3ca4d7851824") 
     set(Boost_Bootstrap_Command bootstrap.bat) 
     set(Boost_b2_Command b2.exe) 
    endif() 
     set(Config_Libraries "chrono,filesystem,program_options,system,thread,test") 
ExternalProject_Add(Boost 
    TMP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/temp" 
    DOWNLOAD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/downloads" 
    URL "${CMAKE_CURRENT_SOURCE_DIR}/downloads/boost_1_63_0.zip" 
    URL_HASH "SHA1=${Boost_Sha1}" 
    BUILD_IN_SOURCE 1 
    UPDATE_COMMAND "" 
    PATCH_COMMAND "" 
    CONFIGURE_COMMAND ${Boost_Bootstrap_Command} --without-icu --with_libraries=${Config_Libraries} 
    BUILD_COMMAND ${Boost_b2_Command} 
     # --prefix="${CMAKE_CURRENT_SOURCE_DIR}/depends" 
     --without-python 
     --address-model=64 
     --architecture=x64 
     --threading=multi 
     --link=static 
     --variant=release 
     --layout=tagged 
     --build-type=complete 
     -j${N} 
    INSTALL_COMMAND "" 
    # INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/depends" 

    #As it happens, these directories are currently empty... 
    # set(BOOST_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/depends/include/boost-1_63) 
    # set(Boost_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/depends/boost_1_63/include) 
    # set(Boost_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/depends/boost_1_63/lib) 
) 
endif() 

set(Boost_USE_STATIC_LIBS OFF) 
set(Boost_USE_MULTITHREADED ON) 
set(Boost_USE_STATIC_RUNTIME OFF) 
include_directories(${CMAKE_SOURCE_DIR}/src) 

# Grabbing just all the test project files. 
file(GLOB SOURCES "src/*.*") 
add_executable(cmaketest ${SOURCES}) 
# TARGET_LINK_LIBRARIES(cmaketest ${Boost_LIBRARY}) 
+0

您的意图和目标是从源代码构建Boost还是仅仅想在您的应用中使用Boost,而您的应用是使用CMake构建的?在后一种情况下,我建议下载预先构建的Boost例如从这里https://sourceforge.net/projects/boost/files/boost-binaries/1.63.0/然后在你的CMake中使用find_package(Boost 1.63 REQUIRED),这将设置变量(参见FindBoost模块文档)增强库和标题。在你可能需要通过在你的CMakeLists.txt文件中提供BOOST_ROOT变量来帮助FindBoost find_package() –

+0

我想从源代码构建它来学习如何在Boost的上下文中做到这一点。接下来的事情就是从* vspkg *,* Nuget *,* Conan *或者其他的那些中获取二进制依赖关系。我也试探了一下。无论如何,我有这个目前我想解决的问题。 @fedepad写了些什么有助于看到我的方式的错误,但还有一段路要走。我相信我稍后(在手机上)更新这个问题到最新的尝试。 – Veksi

+0

@ivan_onys我也可以想象如何决定如何根据构建包含调试和发布二进制文件。但也许在以后的时间。 :) – Veksi

回答

1

我会尝试给你一些提示,试图回答你的问题。

1)有了这个片段,你应该能够在正确的目录中有源代码和构建文件。我保留TMP_DIR "${Cmaketest_SOURCE_DIR}/temp"但在我的项目中,我不使用该行。

ExternalProject_Add(Boost 
    TMP_DIR "${Cmaketest_SOURCE_DIR}/temp" 
    DOWNLOAD_DIR "${Cmaketest_SOURCE_DIR}/downloads" 
    URL "${Cmaketest_SOURCE_DIR}/downloads/boost_1_63_0.zip" 
    URL_HASH "SHA1=${Boost_Sha1}" 
    SOURCE_DIR ${Cmaketest_SOURCE_DIR}/downloads/boost_1_63_0 
    BUILD_IN_SOURCE 1 
    UPDATE_COMMAND "" 
    PATCH_COMMAND "" 
    CONFIGURE_COMMAND ${Boost_Bootstrap_Command} --without-icu --with_libraries=${Config_Libraries} 
    BUILD_COMMAND ${Boost_b2_Command} 
     --prefix="${Cmaketest_SOURCE_DIR}/depends/boost_1_63_0" 
     --without-python 
     --address-model=64 
     --architecture=x64 
     --threading=multi 
     --link=static 
     --variant=release 
     --layout=tagged 
     --build-type=complete 
     -j${N} 
    INSTALL_COMMAND ${Boost_b2_Command} --prefix="${Cmaketest_SOURCE_DIR}/depends/boost_1_63_0" --without-python 
     --address-model=64 
     --architecture=x64 
     --threading=multi 
     --link=static 
     --variant=release 
     --layout=tagged 
     --build-type=complete 
     -j${N} install 
    INSTALL_DIR "${Cmaketest_SOURCE_DIR}/depends/boost_1_63_0" 
) 

set(BOOST_ROOT ${Cmaketest_SOURCE_DIR}/depends/boost_1_63_0) 
set(Boost_LIBRARY ${Cmaketest_SOURCE_DIR}/depends/boost_1_63_0/lib) 
set(Boost_INCLUDE_DIR ${Cmaketest_SOURCE_DIR}/depends/boost_1_63_0/include) 
include_directories(${Boost_INCLUDE_DIR}) 

要注意,您没有调用“install”,因此一旦构建在“奇怪”目录中,文件就不会移动到指定的前缀。还请注意使用${Cmaketest_SOURCE_DIR}而不是以前的。
尝试打印两个,看看是否有区别。

2)为了解决你的情况下,升压得到的是没有找到警告,你应该写:

find_package(Boost QUIET) 

3)为了解决这个问题我想你不能生成项目文件,即而不必

cmake build -G "Visual Studio 14 2015 Win64" 

只是有cmake .cmake ..取决于你是否会做一个在源或外的源的构建。我建议做外源构建,但这是你的选择。
4)FindBoost.cmakeFindBoost.cmake)为您提供了将任意路径传递到Boost目录的可能性。您可以在配置中使用它来提示CMake在您提供的位置寻找Boost,例如您将调用cmake的下列方式:

cmake -DBOOST_ROOT=/path_to_cmaketest_dir/depends/boost_1_63_0 .. 

,如果你的系统可能会挑剔你可以指定所有的东西:

cmake -DBOOST_ROOT=/path_to_cmaketest_dir/depends/boost_1_63_0 -DBOOST_LIBRARYDIR=/path_to_cmaketest_dir/depends/boost_1_63_0/lib DBOOST_INCLUDEDIR=/path_to_cmaketest_dir/depends/boost_1_63_0/include .. 

请注意,在最后两个片段我认为一个OUT-的配置源代码构建。
另外请注意,如果您已经安装或者已经下载了Boost软件包,使用${Cmaketest_SOURCE_DIR}在1)中的剪切代码中也应该解决4)所以当它不会找到Boost时,它会尝试下载,但是现在不会,因为现在cmake应该能够看到文件(.zip)。

+0

嗨! '$ {Cmaketest_SOURCE_DIR}'和'$ {Cmaketest_SOURCE_DIR}'都显示相同的路径:'C:/ projektit/cmaketest'。这看起来很奇怪,因为现在我得到错误信息,而且我认为,C/C++/CMake/share/cmake-3.7/Modules/ExternalProject.cmake中的CMake错误:1117(消息): dir 'C:/ projektit/cmaketest/depend/boost_1_63; set;(; BOOST_ROOT; C:/ projektit/cmaketest/depends/include/boost_1_63;); set;(; Boost_LIBRARY; C:/projektit/cmaketest/devices/include boost_1_63/lib;); include_directories;(; Boost_INCLUDE_DIR-NOTFOUND;)' 不存在后文件(MAKE_DIRECTORY)' – Veksi

+0

我需要调查这一点,自然。我发现我也可能应该添加* SYSTEM *,如'include_directories(SYSTEM $ {Boost_INCLUDE_DIR})',以排除生成的VS解决方案中的头文件。 – Veksi

+0

好的,问题是我脚本中的Boost路径设置在括号内(多么尴尬)。然而,将它们移出并不能解决构建的问题。还是要调查...... – Veksi

0

请参阅CMaker_Boost,在配置时使用CMake构建Boost。现在它已经在Linux和Android,gcc和clang上进行了测试。其他系统未经测试。我希望这有帮助。