CMake的FetchContent具有Makefile构建的依赖性

时间:2019-10-31 13:33:05

标签: cmake external-dependencies

我当前的项目需要一个用Makefile构建的库。我想在项目编译期间编译该库;此功能是FetchContent的主要卖点,并且与CMake依赖项配合得很好。但是,我无法使它与Makefiles一起使用,也找不到如何使用它的示例。

FetchContent_Declare(
    make_lib
    URL http://url/library_code.tar.gz 
    BUILD_COMMAND ${CMAKE_COMMAND} -E env make -j 8
    BUILD_IN_SOURCE true  
    BINARY_DIR ""
)

FetchContent_GetProperties(make_lib)
if (NOT make_lib_POPULATED)
    FetchContent_Populate(make_lib)

    # here I would like to declare imported libraries:
    add_library(make_lib::libA STATIC IMPORTED GLOBAL)
    target_include_directories(make_lib::libA INTERFACE ${make_lib_SOURCE_DIR}/include)
    set_property(TARGET make_lib::libA   PROPERTY IMPORTED_LOCATION <path to "to be built" lib>)

endif()
  • 是否可以完全make的“编译时”执行?
  • 如果是这样,可以并行吗?
  • 是否可以使用依赖项编译库声明导入的目标?

1 个答案:

答案 0 :(得分:1)

FetchContent_*命令仅从特定外部资源中获取内容或元数据,并填充CMake变量;他们实际上并不执行任何配置,构建或安装步骤。因此,在调用FetchContent_Declare()时,与这些步骤相关的所有选项均被明确忽略。其中包括以下选项:

  • CONFIGURE_COMMAND
  • BUILD_COMMAND
  • INSTALL_COMMAND
  • TEST_COMMAND

摘自FetchContent文档:

  

此模块允许通过ExternalProject模块支持的任何方法在配置时填充内容。 ExternalProject_Add()在构建时下载,而FetchContent模块使内容立即可用,允许配置步骤在诸如add_subdirectory()include()或{{1}之类的命令中使用内容}操作。

这不适用于您的用例,因为外部库中没有CMake文件,因此诸如file()之类的调用将失败。

this帖子中所述,ExternalProject_Add()在您的情况下更有意义。您的通话可能看起来像这样:

add_subdirectory()

请注意,此处的ExternalProject_Add(make_lib DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR} URL http://url/library_code.tar.gz UPDATE_COMMAND "" SOURCE_DIR ${make_lib_SOURCE_DIR} BUILD_IN_SOURCE 1 CONFIGURE_COMMAND "" BUILD_COMMAND "make -j8" INSTALL_COMMAND "${make_lib_install_commands}" ) add_library(make_lib_libA STATIC IMPORTED GLOBAL) set_property(TARGET make_lib_libA PROPERTY IMPORTED_LOCATION ${make_lib_SOURCE_DIR}/path/to/make_lib_libA.a ) add_dependencies(myOtherLib make_lib) 不会被忽略,但会在编译时运行BUILD_COMMAND。您还应该能够将导入的库声明为代码布局。但是重要的是,请记住要调用make -j8,它告诉CMake您的add_dependencies()被另一个目标使用;否则,make_lib构建。

调用make-lib之后,可以使用ExternalProject_Get_Property()查询有关外部项目目标的信息。链接的示例显示了如何获取项目的源目录,这对于获取已构建库的位置可能很有用。