Cmake 将Boost构建为一个ExternalProject\u添加并查找Boost或导出结果

Cmake 将Boost构建为一个ExternalProject\u添加并查找Boost或导出结果,cmake,Cmake,我有许多外部依赖项,我想通过ExternalProject\u Add将它们引入到我的项目中。诀窍是以尽可能干净的方式导出include目录和生成的静态链接库 是否可以使FindBoost依赖于ExternalProject\u Add,或者至少使用target\u link\u libraries将项目拉入库和标题 促进 include(外部项目) 设置(boost_URL)http://sourceforge.net/projects/boost/files/boost/1.63.0/boo

我有许多外部依赖项,我想通过
ExternalProject\u Add
将它们引入到我的项目中。诀窍是以尽可能干净的方式导出include目录和生成的静态链接库

是否可以使
FindBoost
依赖于
ExternalProject\u Add
,或者至少使用
target\u link\u libraries
将项目拉入库和标题

促进
include(外部项目)
设置(boost_URL)http://sourceforge.net/projects/boost/files/boost/1.63.0/boost_1_63_0.tar.bz2" )
套件(增压泵1“9f1dd4fa364a3e3156a77dc17aa562ef06404ff6”)
设置(boost\u安装${CMAKE\u CURRENT\u BINARY\u DIR}/third\u party/boost)
设置(boost_INCLUDE_DIR${boost_INSTALL}/INCLUDE)
set(boost_LIB_DIR${boost_INSTALL}/LIB)
外部项目添加(外部项目)
前缀增强
URL${boost_URL}
URL_HASH SHA1=${boost_SHA1}
在\u源1中生成\u
配置_命令。/bootstrap.sh
--带库=文件系统
--带库=系统
--带库=日期\时间
--前缀=
生成命令
./b2安装链接=静态变量=发布线程=多运行时链接=静态
安装命令“”
INSTALL_DIR${boost_INSTALL})
集合(boost\u LIBRARY\u后缀.a)
添加库(boost::date\u time静态导入)
set_属性(目标boost::日期_时间属性导入_位置${boost_LIB_DIR}/libboost_日期_时间${boost_库_后缀})
set_属性(TARGET boost::date_time属性接口_INCLUDE_目录${boost_INCLUDE_DIR})
添加依赖项(boost::date\u time外部\u boost)
添加_库(boost::系统静态导入)
set_属性(目标boost::系统属性导入_位置${boost_LIB_DIR}/libboost_系统${boost_库_后缀})
set_属性(目标boost::系统属性接口_INCLUDE_目录${boost_INCLUDE_DIR})
添加依赖项(boost::系统外部\u boost)
添加_库(boost::文件系统静态导入)
set_属性(目标boost::文件系统属性导入_位置${boost_LIB_DIR}/libboost_文件系统${boost_LIBRARY_SUFFIX})
设置属性(目标boost::文件系统属性接口\u链接\u库boost::系统)
set_属性(目标boost::文件系统属性接口_INCLUDE_目录${boost_INCLUDE_DIR})
添加依赖项(boost::文件系统外部\u boost)

外部项目\u Add创建一个目标,该目标将驱动外部项目。这意味着下载、构建和安装外部项目是在构建步骤中进行的。因此,外部项目的属性在配置步骤中是未知的,所以您不能直接依赖它(或查找_包)

解决方案是使用所谓的超级构建。我们的想法是在项目中使用
find_-package
作为依赖项,就像它们安装在系统上一样。然后创建另一个CMakeLists.txt,其中包含所有依赖项和项目的
ExternalProject\u Add
说明

当您在super build的CMakeLists.txt上调用cmake时,它只会设置一个用于下载和构建所有项目的构建系统,但还没有执行任何操作。当您调用build时,将逐个下载、配置、构建和安装项目。因此,当涉及到您的项目时,所有依赖项都已安装,配置步骤将成功

超级构建的例子可以在这里找到(我没有尝试过,但至少你可以得到这个想法):。请注意,cmake/SuperBuild.cmake中的最后一条指令是主CMakeLists.txt(也称为您的项目)的ExternalProject\u Add


另请参阅的CMake文档,了解如何定义外部项目级别的依赖项。

可以使用build_命令在配置时获取CMake build命令,并在配置阶段启动该命令,并使用强制缓存手动填充Boost_INCLUDE_DIR,以使find_包与此内容一起工作。更新_命令“”。
include( ExternalProject )

set( boost_URL "http://sourceforge.net/projects/boost/files/boost/1.63.0/boost_1_63_0.tar.bz2" )
set( boost_SHA1 "9f1dd4fa364a3e3156a77dc17aa562ef06404ff6" )
set( boost_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/third_party/boost )
set( boost_INCLUDE_DIR ${boost_INSTALL}/include )
set( boost_LIB_DIR ${boost_INSTALL}/lib )

ExternalProject_Add( external_boost
        PREFIX boost
        URL ${boost_URL}
        URL_HASH SHA1=${boost_SHA1}
        BUILD_IN_SOURCE 1
        CONFIGURE_COMMAND ./bootstrap.sh
            --with-libraries=filesystem
            --with-libraries=system
            --with-libraries=date_time
            --prefix=<INSTALL_DIR>
        BUILD_COMMAND
        ./b2 install link=static variant=release threading=multi runtime-link=static
        INSTALL_COMMAND ""
        INSTALL_DIR ${boost_INSTALL} )

set( boost_LIBRARY_SUFFIX .a )

add_library( boost::date_time STATIC IMPORTED )
set_property( TARGET boost::date_time PROPERTY IMPORTED_LOCATION ${boost_LIB_DIR}/libboost_date_time${boost_LIBRARY_SUFFIX} )
set_property( TARGET boost::date_time PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${boost_INCLUDE_DIR} )
add_dependencies( boost::date_time external_boost )

add_library( boost::system STATIC IMPORTED )
set_property( TARGET boost::system PROPERTY IMPORTED_LOCATION ${boost_LIB_DIR}/libboost_system${boost_LIBRARY_SUFFIX} )
set_property( TARGET boost::system PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${boost_INCLUDE_DIR} )
add_dependencies( boost::system external_boost )

add_library( boost::filesystem STATIC IMPORTED )
set_property( TARGET boost::filesystem PROPERTY IMPORTED_LOCATION ${boost_LIB_DIR}/libboost_filesystem${boost_LIBRARY_SUFFIX} )
set_property( TARGET boost::filesystem PROPERTY INTERFACE_LINK_LIBRARIES boost::system )
set_property( TARGET boost::filesystem PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${boost_INCLUDE_DIR} )
add_dependencies( boost::filesystem external_boost )