我有一个 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,下载它开始构建(在下面的代码中我设置为获取以前获取的文件)。但是经过一段时间的建设,问题就出现了......
\cmaketest\CMakeFiles\build\Boost-prefix\src\Boost
的形式出现在根目录中。我怎么能这些它们被构建到\depends\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 :(得分: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.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)。
答案 1 :(得分:0)
请参阅CMaker_Boost,在配置时使用CMake构建Boost。现在它在Linux和Android,gcc和clang上进行了测试。其他系统未经过测试。我希望这会有所帮助。