以非常简单的形式:选项FIND_PACKAGE_ARGS
makes FetchContent
使用结果find_package
。但对于制作find_package
使用结果FetchContent
,你需要传递另一个选项:OVERRIDE_FIND_PACKAGE
.
Both FetchContent
and find_package
旨在引入一个 3d 方项目,以便在主项目的构建过程中使用它。然而,这两种方法使用不同的机制:
-
FetchContent
从源代码构建 3d 方项目以及主项目,但是
-
find_package
适用于已安装的 3d 方项目。
CMake 提供了两个集成的“方向”FetchContent
and find_package
;每个“方向”都有其自己独立的目的。
1. 编写一个新项目,在源和安装中均消耗 3d 方项目。
假设您编写一个项目,该项目使用一些 3d 方项目。假设您想支持两种变体:
- 使用已安装的 3d 方项目变体(如果已可用),或者
- 从源代码中与主项目一起构建 3d 方项目。
范围FIND_PACKAGE_ARGS
for FetchContent_Declare
告诉 CMake 使用find_package
用于查找已安装的 3D 方项目,如果可用,请勿从源构建它。
仅当主项目通过接口使用 3d 方项目时,此类集成才会起作用,前提是both通过 3d 方项目的来源和find_package
.
例如。 GTest 的来源create https://github.com/google/googletest/blob/main/googletest/cmake/internal_utils.cmake#L155命名空间中的 ALIAS 目标GTest
(like GTest::gtest_main
) and find_package(GTest)
creates https://github.com/google/googletest/blob/main/googletest/CMakeLists.txt#L103具有相同命名空间的导入目标。因此,外部项目可以安全地链接GTest::gtest_main
只要 GTest 已经安装或正在从源代码构建,这就会起作用。
2. 使现有项目能够与从源代码构建的 3d 方项目一起使用
假设您正在创建一个超级项目,它结合了多个已经存在的子项目。该子项目之一执行find_package
用于 3d 方项目并使用其结果。假设您希望从源代码构建 3d 方项目。
大多数特定于项目的脚本,由find_package
,仅与已安装的软件包并且不适用于当前正在构建的版本。需要一些特殊的力量..
忽略“find_package”
范围OVERRIDE_FIND_PACKAGE
for FetchContent_Declare
指ignore更远find_package
之所以会调用,是因为 3d 方项目是从源代码构建的。
如果子项目仅使用以下结果,则此方法有效find_package
,也可以从 3d 方项目的来源获得。
例如。如果子项目使用目标,它将起作用GTest::gtest_main
用于链接。但如果子项目使用它就不起作用GTEST_MAIN_LIBRARIES
变量,未在 GTest 源中设置。
更改“find_package”执行的脚本
但是,如果子项目使用了部分接口,而该接口只能从find_package
(及其特定于项目的脚本),但无法从 3d 方项目的源中获得?在这种情况下,可以创建一个假剧本,这将由执行find_package
而不是普通的。
file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-extra.cmake
[=[
set(GTEST_MAIN_LIBRARIES GTest::gtest_main)
]=])
之间的线[=[
and ]=]
成为创建的脚本的一部分,该脚本定义GTEST_MAIN_LIBRARIES
适合子项目中链接的变量。
(注意,该文件gtest-extra.cmake
只有当OVERRIDE_FIND_PACKAGE
参数已指定为FetchContent_Declare
.)