我当前的项目需要一个用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
的“编译时”执行?答案 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()
查询有关外部项目目标的信息。链接的示例显示了如何获取项目的源目录,这对于获取已构建库的位置可能很有用。