我有一个项目A,它将一个静态库导出为目标:
install(TARGETS alib DESTINATION lib EXPORT project_a-targets)
install(EXPORT project_a-targets DESTINATION lib/alib)
现在我想使用项目A作为项目B的外部项目,并包含其构建目标:
ExternalProject_Add(project_a
URL ...project_a.tar.gz
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/project_a
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
)
include(${CMAKE_CURRENT_BINARY_DIR}/lib/project_a/project_a-targets.cmake)
问题是,当运行项目B的CMakeLists时,包含文件还不存在。
是否有一种方法可以使include依赖于正在构建的外部项目?
更新:基于这个问题和我遇到的其他常见问题,我写了一个简短的CMake by Example tutorial。
7条答案
按热度按时间hc2pp10m1#
我觉得你混淆了两种不同的思维模式。
正如您所注意到的,高度灵活的
ExternalProject
模块在构建时运行其命令,因此您不能直接使用项目A的导入文件,因为它仅在安装项目A后创建。如果你想
include
项目A的导入文件,你将 * 必须 * 在调用项目B的CMakeLists.txt之前手动安装项目A-就像通过这种方式或通过find_file
/find_library
/find_package
添加的任何其他第三方依赖一样。如果你想使用
ExternalProject_Add
,你需要在CMakeLists.txt中添加如下内容:shyt4zoc2#
This post有一个合理的答案:
CMakeLists.txt.in
:CMakeLists.txt
:然而,它看起来相当hacky。我想提出一个替代方案-使用Git子模块。
然后在
MyProject/dependencies/gtest/CMakeList.txt
中,你可以这样做:我还没有尝试过这个广泛的,但它似乎更干净。
编辑:这种方法有一个缺点:该子目录可能会运行您不想要的
install()
命令。This post has an approach to disable them但它是buggy和不为我工作。编辑2:如果使用
add_subdirectory("googletest" EXCLUDE_FROM_ALL)
,似乎意味着默认情况下不使用子目录中的install()
命令。bejyjqdl3#
编辑:CMake现在对此有内置支持。请参阅使用FetchContent的new answer。
还可以在辅助make进程中强制生成依赖目标
参见my answer相关主题。
noj0wjuj4#
我正在寻找类似的解决方案。这里的回复和上面的教程是信息丰富的。我研究了这里提到的帖子/博客,以建立我的成功。我张贴完整的CMakeLists.txt为我工作。我想,这将是一个基本的模板,为初学者的帮助。
"CMakeLists.txt"
esyap4oy5#
cmake的
ExternalProject_Add
确实可以使用,但我不喜欢它的地方是它在构建,连续轮询等过程中执行某些操作……我更喜欢在构建阶段构建项目,没有别的。我曾多次尝试覆盖ExternalProject_Add
,不幸的是没有成功。然后我也尝试添加git子模块,但这会拖动整个git存储库,而在某些情况下,我只需要整个git存储库的子集。我已经检查了-确实可以执行稀疏git checkout ,但这需要单独的函数,我在下面写了。
我在下面添加了两个函数调用,只是为了说明如何使用该函数。
有些人可能不喜欢 checkout master / trunk,因为那个可能已经坏了--然后总是可以指定特定的标签。
在清除该高速缓存文件夹之前,将只执行一次 checkout 。
dgiusagp6#
首先使用
FetchContent
:注意,所有
CMake
魔术都按预期工作:你不需要为libsomething
指定glog
的include目录或构建工件。bq9c1y667#
我也会推荐FetchContent用于简单的项目。但是,有时需要对正在下载的库进行更多控制。ExternalProject非常有用,因为它有许多自定义选项。秘诀在于了解您试图下载的库。阅读它的CMakeLists.txt文件,了解如何修改安装目录,或者在构建或安装之前需要什么配置。
以下示例将下载ZeroMQ(A.K.A. zmq)这个库需要在库中运行一个bash脚本来正确配置,它有一些选项可以用来定制你的安装。
我个人不喜欢保存文件的标准位置,以及不需要在我的系统中安装库。所以我想把它安装在我的项目中。因此,您可以根据需要指定目录。
在我的项目中,我覆盖CMAKE_INSTALL_PREFIX和CMAKE_INCLUDE_PREFIX来指向我希望文件所在的文件夹。
请注意,ZeroMQ不是实际的库目标,它是我为ExternalProject目标选择的名称。库目标是zmq。因此库文件将是libzmq.so。
在构建或安装之后,您的主目标需要显示它依赖于外部库,以便按照正确的顺序构建。因此,您需要在目标所在的CMakeLists.txt(或任何父CMakeLists.txt)中添加以下内容:
如果你需要下载另一个依赖于zmq的外部库,你可以在ExternalProject_Add中添加一个DEPENDS参数:
希望这篇文章能对大家有所帮助,虽然这是一篇很老的文章。