链接到 CMAKE 中的 ExternalProject_add 依赖项
Posted
技术标签:
【中文标题】链接到 CMAKE 中的 ExternalProject_add 依赖项【英文标题】:Linking against an ExternalProject_add dependency in CMAKE 【发布时间】:2016-10-29 00:15:43 【问题描述】:我在运行 Ninja 时遇到了下面的这个 ninja build 错误。我的 CMAKE 构建命令是cmake -G"Ninja" -DCMAKE_BUILD_TYPE=Release
。
ninja: error: 'ext_deps/api/src/ext_api/build/src/lib/libapi.a', needed by 'Project', missing and no known rule to make it
假设我的项目由一个 API(通过 CMAKE 从 GitHub 下载)和实现(项目)组成。
The layout would look like:
Project/
-- build/
-- cmake/modules
----- ExternalDep.cmake
----- FindAPI.cmake
-- CMakeLists.txt
-- src/
---- CMakeLists.txt
-- include/
假设在***CMakeLists.txt
中,我执行设置构建设置、CXX 标志等的常规业务,然后我调用include(ExternalDep)
,它检查“API”库是否在用户的系统(如果不是,则通过 CMAKE 下载)。
在src/CMakeLists.txt
中,我尝试使用
target_link_libraries($PROJECT_NAME PRIVATE $API_LIBRARY)
我遇到的第一个问题是,在“API”库甚至可以下载和构建之前,我收到了上面发布的 ninja build 错误。在我尝试添加项目可执行文件并链接到“API”库之前,我很肯定 ExternalDep.cmake
已包含在内。
这是ExternalDep.cmake
的简化版:
set(EXT_DEPS_PREFIX "ext_deps")
ExternalProject_Add(ext_lib
GIT_REPOSITORY "https://github.com/fake/api.git"
GIT_TAG "master"
PREFIX "$CMAKE_BINARY_DIR/$EXT_DEPS_PREFIX/api"
TMP_DIR "$CMAKE_BINARY_DIR/$EXT_DEPS_PREFIX/api-tmp"
STAMP_DIR "$CMAKE_BINARY_DIR/$EXT_DEPS_PREFIX/api-stamp"
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release
SOURCE_DIR "$CMAKE_BINARY_DIR/$EXT_DEPS_PREFIX/api/ext_api"
BINARY_DIR "$CMAKE_BINARY_DIR/$EXT_DEPS_PREFIX/api/ext_api-build"
BUILD_ALWAYS true
TEST_COMMAND "")
add_dependencies(ext_projects ext_api)
set(API_LIBRARY "$CMAKE_BINARY_DIR/$EXT_DEPS_PREFIX/api/ext_api-build/src/lib/libapi.a")
【问题讨论】:
ExternalProject_Add
在构建阶段构建项目。但FindXXX.cmake
预计 XXX 项目已在 配置阶段 安装。如果要在配置阶段构建项目,请使用execute_process()
。
@Tsyvarev 因此,经过多次摆弄,我发现我需要做的就是使用Unix Makefiles
作为我生成的构建文件,而不是Ninja
。不知道为什么会这样,但它奏效了。
【参考方案1】:
我遇到了与Ninja
相同的问题,而它与Unix Makefiles
一起工作正常,我设法通过在我的ExternalProject_Add
块中添加BUILD_BYPRODUCTS
行使其与Ninja
一起工作。示例:
ExternalProject_Add(SDL2_PROJECT
PREFIX 3rdparty
URL https://www.libsdl.org/release/SDL2-2.0.5.tar.gz
URL_MD5 d4055424d556b4a908aa76fad63abd3c
CONFIGURE_COMMAND <SOURCE_DIR>/configure $SDL2_configure_args --prefix=<INSTALL_DIR> --disable-shared
INSTALL_COMMAND make install -j9
BUILD_BYPRODUCTS <INSTALL_DIR>/lib/libSDL2.a
)
ExternalProject_Get_Property(SDL2_PROJECT INSTALL_DIR)
set(SDL2_INSTALL_DIR $INSTALL_DIR)
add_library(SDL2_LIBRARY STATIC IMPORTED GLOBAL)
set_property(TARGET SDL2_LIBRARY PROPERTY IMPORTED_LOCATION $SDL2_INSTALL_DIR/lib/libSDL2.a)
add_dependencies(SDL2_LIBRARY SDL2_PROJECT)
【讨论】:
只有忍者需要BUILD_BYPRODUCTS,我在某处读到过。尽管如此,由于构建顺序错误,我在 UNIX Makefile 中遇到了这个错误。我需要我的 cmake 目标的依赖项,该依赖项与外部项目在该外部项目上生成的.a
链接,因此后者将首先构建...
@CarloWood 您是否尝试过创建一个依赖于外部项目的导入库,就像我在上面的代码示例中所做的那样?如果您完全按照我的方式进行操作,您只需针对导入的目标添加您的二进制文件,就可以了...【参考方案2】:
我能够通过生成 Unix Makefiles 而不是 Ninja 来解决这个问题。我仍然不确定这是否是单一问题,但这绝对是问题之一。
【讨论】:
那是因为你需要使用BUILD_BYPRODUCTS
。看看我的回答。以上是关于链接到 CMAKE 中的 ExternalProject_add 依赖项的主要内容,如果未能解决你的问题,请参考以下文章
cmake - 全局链接器标志设置(适用于目录中的所有目标)