HelloWorld:使用CMake下载、构建和链接Boost

HelloWorld: downloading, building and linking Boost using CMake

本文关键字:构建 链接 Boost 下载 使用 CMake HelloWorld      更新时间:2023-10-16

我有一个Hello,World风格的程序,我想使用CMake以端到端的方式进行更多的工作。在这种情况下,这意味着我可以下载Boost库,编译它们,最后编译我的小Hello,World并将Boost库链接到它。

目录布局看起来像当前的

cmaketest|-build//我希望这里有CMake生成的IDE文件。|-src|-main.cpp|-你好.cpp|-你好.hpp|-dependents//我希望这里有构建的Boost库和头。|-downloads//其中包含已下载的zip文件。|-temp//临时文件

我有以下CMakeLists.txt,目前我生成的Visual Studio 2015项目文件如下:cmake build -G "Visual Studio 14 2015 Win64"。一切都很好,我将启动解决方案,CMake抱怨它找不到Boost,去下载它开始构建(在下面的代码中,我设置了获取之前获取的文件)。但经过一段时间的建设,问题出现了。。。

  1. Boost文件似乎以根目录的形式出现在cmaketestCMakeFilesbuildBoost-prefixsrcBoost中。我如何才能将这些库构建到dependsboost(或达到这种效果),以及如何包含要链接到解决方案的库?这个链接是我遇到的一个单独的问题,我知道如何包含这个奇怪目录中的头,但这并不是我真正想要的
  2. 看起来VSIDE首先发出了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})

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

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.cmake(FindBoost.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)。

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