HelloWorld:使用CMake

时间:2017-01-13 22:54:50

标签: c++ boost cmake

我有一个 Hello,World 风格的程序,我希望使用CMake以端到端的方式开展更多工作。在这种情况下,这意味着我可以下载Boost库,编译它们,最后编译我的小 Hello,World 并将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软件包(如果已经在磁盘上)?看起来它将在任何情况下被检索,我已经考虑过检查文件是否存在。
  5. 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})
    

2 个答案:

答案 0 :(得分: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)为了解决在找不到Boost的情况下你会得到的警告,你应该写:

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 ..  

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

答案 1 :(得分:0)

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

相关问题