我试图理解以下文档:
所以我尝试了一个简单的 cmakelists.txt 文件,例如:
% cat CMakeLists.txt
cmake_minimum_required(VERSION 3.24)
project(p)
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
FIND_PACKAGE_ARGS NAMES gtest
)
# This will try calling find_package()
FetchContent_MakeAvailable(googletest)
find_package(GTest)
message(${GTest_DIR})
Run Code Online (Sandbox Code Playgroud)
如果我运行它,我会得到以下结果:
$ cmake ..
[...]
/usr/lib/x86_64-linux-gnu/cmake/GTest
Run Code Online (Sandbox Code Playgroud)
由于某种原因,find_package(GTest)仍然尝试检查系统中的 GTest,而不是 FetchContent 代码块中声明的 GTest。
我从 cmake 文档中误解了什么?我认为该功能FetchContent 正是针对用户无法使用的情况,ExternalProject因为它不与find_package.
以供参考:
% cmake --version
cmake version 3.24.1
Run Code Online (Sandbox Code Playgroud)
以非常简单的形式:该选项FIND_PACKAGE_ARGS使用FetchContent的结果find_package。但要让 makefind_package使用 的结果FetchContent,您需要传递另一个选项:OVERRIDE_FIND_PACKAGE。
和FetchContent都find_package旨在引入一个 3d 方项目,以便在主项目的构建过程中使用它。然而,这两种方法使用不同的机制:
FetchContent从源代码构建 3d 方项目以及主项目,但是find_package适用于已安装的 3d 方项目。FetchContentCMake 提供了和之间集成的两个“方向” find_package;每个“方向”都有其自己独立的目的。
假设您编写一个项目,该项目使用一些 3d 方项目。假设您想支持两种变体:
参数FIND_PACKAGE_ARGSforFetchContent_Declare告诉 CMake 用于find_package查找已安装的 3d 方项目,并且如果可用,请勿从源构建它。
仅当主项目通过接口使用 3d 方项目(由3d 方项目源和find_package.
例如,GTest 的源在命名空间中创建ALIAS 目标GTest(如GTest::gtest_main),并使用相同的命名空间find_package(GTest) 创建IMPORTED 目标。因此,外部项目可以安全地链接GTest::gtest_main,并且只要 GTest 已经安装或正在从源代码构建,这就会起作用。
假设您正在创建一个超级项目,它结合了几个已经存在的子项目。该子项目之一find_package为 3d 方项目执行并使用其结果。假设您希望从源代码构建 3d 方项目。
所使用的大多数特定于项目的脚本find_package仅适用于已安装的软件包,不适用于当前正在构建的软件包。需要一些特殊的力量..
参数OVERRIDE_FIND_PACKAGEforFetchContent_Declare意味着忽略进一步的find_package调用,因为 3d 方项目是从源构建的。
如果子项目仅使用来自 的结果find_package(也可以从 3d 方项目的源中获得),则此方法有效。GTest::gtest_main例如,如果子项目使用目标进行链接,它将起作用。但如果子项目使用GTEST_MAIN_LIBRARIES变量,而 GTest 源中未设置该变量,则它将不起作用。
但是,如果子项目使用部分接口,该部分接口只能从find_package(及其特定于项目的脚本)获得,但不能从 3D 方项目的源中获得,该怎么办?在这种情况下,可以创建一个假脚本,该脚本将由find_package,该脚本将代替正常脚本
file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-extra.cmake
[=[
set(GTEST_MAIN_LIBRARIES GTest::gtest_main)
]=])
Run Code Online (Sandbox Code Playgroud)
[=[和之间的线]=]成为创建的脚本的一部分,它定义了
GTEST_MAIN_LIBRARIES适合子项目中链接的变量。
(请注意,仅当为 指定参数时,该文件gtest-extra.cmake才有意义。)OVERRIDE_FIND_PACKAGEFetchContent_Declare
| 归档时间: |
|
| 查看次数: |
1611 次 |
| 最近记录: |