【发布时间】:2017-05-29 10:07:24
【问题描述】:
我有一个 Hello, World 风格的小程序,我想使用 CMake 以端到端的方式进行更多工作。在这种情况下,这意味着我可以下载 Boost 库,编译它们,最后编译我的小 Hello, World 并将 Boost 库链接到它。
目录布局目前看起来像这样
cmaketest |- build //我希望这里有 CMake 生成的 IDE 文件。 |- 源 |- 主.cpp |- 你好.cpp |- 你好.hpp |- 依赖 //我想在这里有内置的 Boost 库和头文件。 |- downloads //这包含下载的 zip 文件。 |- temp //临时文件。我有以下 CMakeLists.txt,目前我生成 Visual Studio 2015 项目文件,如下所示:cmake build -G "Visual Studio 14 2015 Win64"。一切都好,我将开始解决方案,CMake 抱怨它找不到 Boost,去下载它开始构建(在下面的代码中,我设置为获取以前获取的文件)。但是建了一段时间后,问题就出现了……
- Boost 文件似乎以根目录出现在
\cmaketest\CMakeFiles\build\Boost-prefix\src\Boost中。我如何才能将它们构建为\depends\boost(或达到此效果)以及如何包含要链接到解决方案的库?这个链接是我遇到的另一个问题,我知道如何包含这个奇怪目录中的标题,但这并不是我真正想要的。 - 看起来 VS IDE 首先警告找不到 Boost 标头(请参阅主程序),然后开始 Boost 构建。这可以避免吗?
- 如何让Boost库从VS解决方案中消失? IE。不做一个项目,而只是依赖于头文件和库?
- 如果 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})
【问题讨论】:
-
您的意图和目标是从源代码构建 Boost,还是只想在您的应用程序中使用 Boost,而您的应用程序是使用 CMake 构建的?在后一种情况下,我建议下载预构建的 Boost,例如从这里sourceforge.net/projects/boost/files/boost-binaries/1.63.0 然后在您的 CMake 中使用 find_package(Boost 1.63 REQUIRED),它将设置变量(请参阅 FindBoost 模块文档)以及 Boost 库和头文件的位置。您可能需要通过在您调用 find_package() 的 CMakeLists.txt 中提供 BOOST_ROOT 变量来帮助 FindBoost
-
我想从源代码构建它,以学习在 Boost 的上下文中做到这一点。接下来的事情是从 vspkg、Nuget、Conan 或类似的地方获取二进制依赖项。我也试探性地看了一下。无论如何,我有这个我想解决的当前问题。 @fedepad 写的内容有助于了解我的方式错误,但仍有一段路要走。我相信我稍后(目前在移动设备上)将问题更新为最新尝试。
-
@ivan_onys 我还可以想象如何根据构建决定是否包含调试和发布二进制文件存在问题。但也许以后的时间。 :)
-
@ivan_onys 我想说这个想法是让下载源代码的人只下载
cmake、make和make install,而不用担心大量的依赖关系(尤其是 boost,这是一个地狱般的依赖);这可以帮助技术含量较低的用户构建和使用应用程序。