将Boost构建为ExternalProject_Add和FindBoost或导出结果

时间:2017-10-19 07:50:01

标签: cmake

我有许多外部依赖项我想用ExternalProject_Add加入我的项目。诀窍是以最干净的方式导出包含目录和生成的静态链接库。

是否可以使FindBoost依赖于ExternalProject_Add,或者至少使用target_link_libraries使项目和库中的项目成为可能?

升压

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 )

1 个答案:

答案 0 :(得分:2)

ExternalProject_Add创建一个目标,驱动拉动外部项目。这意味着在构建步骤期间会发生外部项目的下载,构建和安装。因此,在配置步骤中不知道外部项目的属性,因此您不能直接依赖(或find_package)它。

解决方案是使用所谓的 super build 。我们的想法是在项目中使用find_package作为依赖项,就像它们已安装在系统上一样。然后,您创建另一个CMakeLists.txt,其中包含所有依赖项和项目ExternalProject_Add说明。

当你在super build的CMakeLists.txt上调用cmake时,它只会设置一个构建系统来下载和构建所有项目,但什么都不做。调用构建时,将逐个下载,配置,构建和安装项目。因此,当涉及到您的项目时,所有依赖项都将已安装,配置步骤将成功。

可以在这里找到超级构建的示例(我没有尝试过,但至少你可以得到这个想法):https://github.com/Sarcasm/cmake-superbuild。注意,cmake / SuperBuild.cmake中的最后一条指令是主CMakeLists.txt(也就是你的项目)的ExternalProject_Add。

另见https://cmake.org/cmake/help/v3.10/module/ExternalProject.html中的CMake文档,了解如何在ExternalProject级别定义依赖项。