外部项目¶
命令¶
外部项目定义¶
- ExternalProject_Add¶
ExternalProject_Add()函数创建一个自定义目标来驱动外部项目的下载、更新/补丁、配置、构建、安装和测试步骤:ExternalProject_Add(<name> [<option>...])
如果需要(例如,对于 CDash 提交),流程中的各个步骤可以独立驱动,并且可以定义额外的自定义步骤,以及控制步骤依赖性的能力。也可以自定义用于管理外部项目的目录结构。该功能支持大量选项,可用于定制外部项目行为。
- 目录选项:
大多数时候,默认的目录布局就足够了。它主要是主要项目通常不需要更改的实现细节。然而,在某些情况下,控制目录布局可能是有用的或必要的。从主构建可以使用 ExternalProject_Get_Property 命令检索它们的值的角度来看,目录选项可能更有用,从而允许主项目引用外部项目的构建工件。
前缀<目录>外部项目的根目录。除非下面另有说明,否则与外部项目关联的所有其他目录都将在此处创建。
TMP_DIR <目录>存储临时文件的目录。
STAMP_DIR <目录>存储每个步骤的时间戳的目录。来自各个步骤的日志文件也在这里创建,除非被 LOG_DIR 覆盖(参见下面的*日志选项*)。
LOG_DIR <目录>在 3.14 版本加入.
存放每一步日志的目录。
DOWNLOAD_DIR <目录>解压前存储下载文件的目录。此目录仅供 URL 下载方法使用,所有其他下载方法直接使用
SOURCE_DIR代替。SOURCE_DIR <目录>下载的内容将被解压到的源目录,或者对于非 URL 下载方法,存储库应该被检出、克隆等的目录。如果没有指定下载方法,这必须指向一个现有的目录,其中外部项目已经解压或克隆/签出。
备注
如果指定了下载方法,则可能会删除源目录中的任何现有内容。只有 URL 下载方法会在开始下载之前检查此目录是否丢失或为空,如果不为空则停止并报错。所有其他下载方法都会默默地丢弃源目录中以前的任何内容。
BINARY_DIR <目录>指定构建目录位置。如果启用“BUILD_IN_SOURCE”,则忽略此选项。
INSTALL_DIR <目录>安装前缀放在
<INSTALL_DIR>占位符中。这实际上并没有配置外部项目安装到给定的前缀。这必须通过将适当的参数传递给外部项目配置步骤来完成,例如使用``<INSTALL_DIR>``。
如果未指定上述任何
..._DIR选项,则它们的默认值计算如下。如果给出了PREFIX选项或设置了EP_PREFIX目录属性,那么将在指定的前缀下构建和安装外部项目TMP_DIR = <prefix>/tmp STAMP_DIR = <prefix>/src/<name>-stamp DOWNLOAD_DIR = <prefix>/src SOURCE_DIR = <prefix>/src/<name> BINARY_DIR = <prefix>/src/<name>-build INSTALL_DIR = <prefix> LOG_DIR = <STAMP_DIR>
否则,如果设置了
EP_BASE目录属性,则外部项目的组件将存储在指定的 base:TMP_DIR = <base>/tmp/<name> STAMP_DIR = <base>/Stamp/<name> DOWNLOAD_DIR = <base>/Download/<name> SOURCE_DIR = <base>/Source/<name> BINARY_DIR = <base>/Build/<name> INSTALL_DIR = <base>/Install/<name> LOG_DIR = <STAMP_DIR>
如果未指定
PREFIX、EP_PREFIX或EP_BASE,则默认设置PREFIX为<name>-prefix。相对路径在调用 ExternalProject_Add() 时根据 CMAKE_CURRENT_BINARY_DIR 进行解释。- 下载步骤选项:
如果
SOURCE_DIR选项用于指向现有的非空目录,则可以省略下载方法。否则,必须指定以下下载方法之一(不应提供多种下载方法)或提供自定义的“DOWNLOAD_COMMAND”。DOWNLOAD_COMMAND <cmd> ...覆盖用于下载步骤的命令(支持
generator expressions)。如果指定此选项,所有其他下载选项将被忽略。为<cmd>提供一个空字符串可以有效地禁用下载步骤。- 网址下载
URL <url1> [<url2>...]外部项目源的路径和/或 URL 列表。当给出多个 URL 时,将依次尝试,直到一个成功。 URL 可以是本地文件系统中的普通路径(在这种情况下,它必须是唯一提供的 URL)或
file(DOWNLOAD)命令支持的任何可下载 URL。本地文件系统路径可以引用现有目录或存档文件,而 URL 应指向可被视为存档的文件。使用存档时,它将自动解压缩,除非设置了DOWNLOAD_NO_EXTRACT选项来阻止它。存档类型是通过检查实际内容而不是使用基于文件扩展名的逻辑来确定的。在 3.7 版本发生变更: 允许多个 URL。
URL_HASH <算法>=<哈希值>要下载的存档文件的哈希值。参数的形式应为``<algo>=<hashValue>``,其中``algo`` 可以是
file()命令支持的任何哈希算法。强烈建议为 URL 下载指定此选项,因为它可确保下载内容的完整性。它还用于检查先前下载的文件,如果本地目录已经有来自较早下载的与指定哈希匹配的文件,则允许完全避免连接到远程位置。URL_MD5 <md5>相当于
URL_HASH MD5=<md5>。DOWNLOAD_NAME <fname>用于下载文件的文件名。如果未给出,则 URL 的末尾用于确定文件名。很少需要这个选项,默认名称通常是合适的,通常不会在
ExternalProject模块的内部代码之外使用。DOWNLOAD_EXTRACT_TIMESTAMP <bool>在 3.24 版本加入.
当使用真值指定时,提取文件的时间戳将与存档中的时间戳匹配。如果为 false,提取文件的时间戳将反映执行提取的时间。如果下载 URL 发生变化,基于存档中时间戳的时间戳可能会导致依赖目标在可能应该重建时未重建。因此,除非文件时间戳在某种程度上对项目很重要,否则请为此选项使用假值。如果未给出
DOWNLOAD_EXTRACT_TIMESTAMP,则默认为 false。请参阅政策:policy:CMP0135。DOWNLOAD_NO_EXTRACT <bool>在 3.6 版本加入.
允许通过为此选项传递一个布尔真值来禁用下载步骤的提取部分。如果没有给出这个选项,下载的内容将在需要时自动解压。如果已禁用提取,则下载文件的完整路径可在后续步骤中作为“<DOWNLOADED_FILE>”使用,或作为属性“DOWNLOADED_FILE”使用 :command:“ExternalProject_Get_Property”命令使用。
DOWNLOAD_NO_PROGRESS <bool>可用于禁用记录下载进度。如果未给出此选项,将记录下载进度消息。
超时<秒>文件下载操作允许的最长时间。
INACTIVITY_TIMEOUT <秒数>在 3.19 版本加入.
一段时间不活动后终止操作。
HTTP_USERNAME <用户名>在 3.7 版本加入.
如果需要身份验证,则为下载操作的用户名。
HTTP_PASSWORD <密码>在 3.7 版本加入.
如果需要身份验证,则为下载操作的密码。
HTTP_HEADER <header1> [<header2>...]在 3.7 版本加入.
为下载操作提供任意 HTTP 标头列表。这对于访问 AWS 等系统中的内容很有用。
TLS_VERIFY <bool>指定是否应对 https URL 执行证书验证。如果未提供此选项,则默认行为由
CMAKE_TLS_VERIFY变量确定(参见file(DOWNLOAD))。如果也没有设置,则不会执行证书验证。在无法提供URL_HASH的情况下,此选项可以作为替代验证措施。在 3.6 版本发生变更: 此选项也适用于
git clone调用。TLS_CAINFO <文件>如果启用了“TLS_VERIFY”,请指定要使用的自定义证书颁发机构文件。如果未指定此选项,则将使用
CMAKE_TLS_CAINFO变量的值(参见file(DOWNLOAD))NETRC <级别>在 3.11 版本加入.
指定是否使用
.netrc文件进行操作。如果未指定此选项,则将使用CMAKE_NETRC变量的值(参见file(DOWNLOAD))。有效级别是:忽略.netrc文件被忽略。这是默认设置。可选的.netrc文件是可选的,URL 中的信息是首选。将扫描文件以查找 URL 中未指定的信息。需要.netrc文件是必需的,URL 中的信息将被忽略。
NETRC_FILE <文件>在 3.11 版本加入.
如果
NETRC级别是OPTIONAL或REQUIRED,请在您的主目录中指定一个替代的.netrc文件。如果未指定此选项,将使用CMAKE_NETRC_FILE变量的值(参见file(DOWNLOAD))
在 3.1 版本加入: 添加了对“tbz2”、“.tar.xz”、“.txz”和“.7z”扩展名的支持。
- 混帐
注意:如果使用这种下载方式,则需要 git 1.6.5 或更高版本。
GIT_REPOSITORY <url>git 存储库的 URL。可以使用
git命令理解的任何 URL。GIT_TAG <标签>Git 分支名称、标记或提交哈希。请注意,分支名称和标签通常应指定为远程名称(即
origin/myBranch而不是简单的myBranch)。这确保了如果远程端的标签被移动或分支变基或历史重写,本地克隆仍将正确更新。但是,一般来说,出于多种原因,应该首选指定提交哈希:如果本地克隆已经有哈希对应的提交,则每次重新运行 CMake 时都不需要执行
git fetch来检查更改。如果使用许多外部项目,这可能会显着加快速度。使用特定的 git hash 可确保主项目自身的历史完全可追溯至外部项目演变中的特定点。如果改用分支或标记名称,则签出主项目的特定提交不一定会将整个构建固定到外部项目生命周期中的特定点。这种确定性行为的缺乏使得主项目失去了可追溯性和可重复性。
如果启用了
GIT_SHALLOW则GIT_TAG仅适用于分支名称和标签。不允许提交哈希。请注意,如果未提供,
GIT_TAG默认为master,而不是默认的 Git 分支名称。GIT_REMOTE_NAME <名称>遥控器的可选名称。如果未指定此选项,则默认为
origin。GIT_SUBMODULES <模块>...还应更新的特定 git 子模块。如果未提供此选项,将更新所有 git 子模块。
在 3.16 版本发生变更: 当 CMP0097 设置为 NEW 时,如果此值设置为空字符串,则不会初始化或更新任何子模块。
GIT_SUBMODULES_RECURSE <bool>在 3.17 版本加入.
通过将
--recursive标志传递给git submodule update来指定 git 子模块(如果有的话)是否应该递归更新。如果未指定,则默认为打开。GIT_SHALLOW <bool>在 3.6 版本加入.
启用此选项后,
git clone操作将被赋予``--depth 1`` 选项。这执行了一个浅克隆,避免下载整个历史,而是只检索由GIT_TAG选项表示的提交。GIT_PROGRESS <bool>在 3.8 版本加入.
启用后,此选项指示
git clone操作通过将--progress选项传递给它来报告其进度。如果没有此选项,大型项目的克隆步骤可能会使构建停滞,因为在克隆操作完成之前不会记录任何内容。虽然此选项可用于提供进度以防止构建出现停滞,但如果使用大量外部项目,它也可能使构建过于嘈杂。GIT_CONFIG <option1> [<option2>...]在 3.8 版本加入.
指定要传递给
git clone的配置选项列表。列出的每个选项都将在git clone命令行上转换为它自己的--config <option>,每个选项都需要采用key=value的形式。GIT_REMOTE_UPDATE_STRATEGY <策略>在 3.18 版本加入.
当
GIT_TAG引用远程分支时,此选项可用于指定更新步骤的行为方式。<strategy>必须是以下之一:结帐忽略本地分支并始终检查由
GIT_TAG指定的分支。重置尝试将当前分支变基为
GIT_TAG指定的分支。如果有本地未提交的更改,它们将首先被隐藏并在 rebase 后再次弹出。如果变基或弹出隐藏的更改失败,则中止变基并因错误而停止。当GIT_REMOTE_UPDATE_STRATEGY不存在时,这是默认策略,除非默认策略已被CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY覆盖(见下文)。请注意,如果GIT_TAG中指定的分支与当前正在跟踪的上游分支不同,则执行 rebase 是不安全的。在这种情况下,REBASE将被默默地视为CHECKOUT。REBASE_CHECKOUT与
REBASE相同,除非变基失败,将在变基之前的原始HEAD位置创建带注释的标签,然后像CHECKOUT策略一样检出GIT_TAG。存储在注释标签上的消息将提供有关尝试的信息,标签名称将包含时间戳,以便每次失败的运行都会添加一个新标签。此策略确保不会丢失任何更改,但如果GIT_TAG引用有效引用,则更新应该始终成功,除非存在无法成功弹出的未提交更改。
可以设置变量“CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY”来覆盖默认策略。此变量不应由项目设置,它旨在供用户设置。它主要用于持续集成脚本,以确保在远程分支上重写历史时,构建不会以意外更改或因变基操作期间的冲突而导致构建失败而告终。
- 颠覆
SVN_REPOSITORY <url>Subversion 存储库的 URL。
SVN_REVISION -r<rev>从 Subversion 存储库中检出的修订。
SVN_USERNAME <用户名>Subversion 检出和更新的用户名。
SVN_PASSWORD <密码>Subversion 检出和更新的密码。
SVN_TRUST_CERT <bool>指定是否信任 Subversion 服务器站点证书。如果启用,
--trust-server-cert选项将传递给svncheckout 和 update 命令。
- 水银
HG_REPOSITORY <url>Mercurial 存储库的 URL。
HG_TAG <标签>Mercurial 分支名称、标记或提交 ID。
- 简历
CVS_REPOSITORY <cvsroot>CVS 存储库的 CVSROOT。
CVS_MODULE <mod>从 CVS 存储库检出的模块。
CVS_TAG <标签>从 CVS 存储库签出的标记。
- 更新步骤选项:
每当重新运行 CMake 时,如果下载方法支持更新,默认情况下将更新外部项目的源代码(例如,如果
GIT_TAG未引用特定提交,将检查 git 存储库)。UPDATE_COMMAND <cmd> ...使用自定义命令覆盖下载方法的更新步骤。该命令可以使用
generator expressions。UPDATE_DISCONNECTED <bool>在 3.2 版本加入.
启用后,此选项会导致跳过更新步骤。但是,它不会阻止下载步骤。更新步骤仍然可以添加为步骤目标(请参阅
ExternalProject_Add_StepTargets())并手动调用。如果您希望允许开发人员在断开网络连接时构建项目(尽管下载步骤可能仍需要网络),这将很有用。当存在此选项时,通常建议将该值设为开发人员控制下的缓存变量,而不是对其进行硬编码。如果此选项不存在,则默认值取自
EP_UPDATE_DISCONNECTED目录属性。如果也未定义,则更新将照常执行。EP_UPDATE_DISCONNECTED目录属性旨在方便地控制项目目录层次结构的整个部分的``UPDATE_DISCONNECTED`` 行为,并且可能是让开发人员控制是否执行更新的更方便的方法(假设该项目还提供了一个缓存变量或其他一些方便的方法来设置目录属性)。这可能会导致为“下载”步骤自动创建一个步骤目标。请参阅政策:policy:CMP0114。
- 补丁步骤选项:
PATCH_COMMAND <cmd>...指定自定义命令以在更新后修补源。缺省情况下,没有定义补丁命令。请注意,定义一个能够稳健执行的适当补丁命令可能非常困难,特别是对于下载方法,例如 git,其中更改
GIT_TAG不会丢弃先前补丁的更改,但补丁命令将在之后再次调用更新到新标签。
- 配置步骤选项:
配置步骤在下载和更新步骤之后运行。默认情况下,外部项目被假定为 CMake 项目,但如果需要可以覆盖它。
CONFIGURE_COMMAND <cmd>...默认配置命令使用基于主项目的一些选项运行 CMake。添加的选项通常只是那些需要使用与主项目相同的生成器的选项,但是可以给出
CMAKE_GENERATOR选项来覆盖它。该项目负责添加任何工具链详细信息、标志或其他它想从主项目中重用或以其他方式指定的设置(请参阅下面的“CMAKE_ARGS”、“CMAKE_CACHE_ARGS”和“CMAKE_CACHE_DEFAULT_ARGS”)。对于非 CMake 外部项目,必须使用
CONFIGURE_COMMAND选项来覆盖默认的配置命令(支持:manual:generator expressions <cmake-generator-expressions(7)>)。对于不需要配置步骤的项目,请使用空字符串指定此选项作为要执行的命令。CMAKE_COMMAND /.../cmake为配置步骤指定一个替代的 cmake 可执行文件(使用绝对路径)。通常不推荐这样做,因为通常希望在整个构建过程中使用相同的 CMake 版本。如果使用“CONFIGURE_COMMAND”指定了自定义配置命令,则忽略此选项。
CMAKE_GENERATOR <gen>覆盖用于配置步骤的 CMake 生成器。如果没有此选项,将使用与主构建相同的生成器。如果使用
CONFIGURE_COMMAND选项指定了自定义配置命令,则忽略此选项。CMAKE_GENERATOR_PLATFORM <平台>在 3.1 版本加入.
将特定于生成器的平台名称传递给 CMake 命令(请参阅
CMAKE_GENERATOR_PLATFORM)。在没有CMAKE_GENERATOR选项的情况下提供此选项是错误的。CMAKE_GENERATOR_TOOLSET <工具集>将特定于生成器的工具集名称传递给 CMake 命令(请参阅
CMAKE_GENERATOR_TOOLSET)。在没有CMAKE_GENERATOR选项的情况下提供此选项是错误的。CMAKE_GENERATOR_INSTANCE <实例>在 3.11 版本加入.
将特定于生成器的实例选择传递给 CMake 命令(请参阅
CMAKE_GENERATOR_INSTANCE)。在没有CMAKE_GENERATOR选项的情况下提供此选项是错误的。CMAKE_ARGS <参数>...指定的参数被传递到 cmake 命令行。它们可以是 cmake 命令理解的任何参数,而不仅仅是缓存由
-D...参数定义的值(另请参见CMake Options)。在 3.3 版本加入: 参数可以使用
generator expressions。CMAKE_CACHE_ARGS <arg>...这是指定缓存变量的替代方法,其中命令行长度问题可能成为问题。参数应采用“-Dvar:STRING=value”的形式,然后使用“FORCE”选项将其转换为 CMake:command:set 命令。这些
set()命令被写入预加载脚本,然后使用cmake -C命令行选项应用该脚本。在 3.3 版本加入: 参数可以使用
generator expressions。CMAKE_CACHE_DEFAULT_ARGS <arg>...在 3.2 版本加入.
这与
CMAKE_CACHE_ARGS选项相同,只是set()命令不包含FORCE关键字。这意味着这些值仅用作初始默认值,不会覆盖上一次运行时已设置的任何变量。请谨慎使用此选项,因为它会导致不同的行为,具体取决于构建是从新的构建目录开始还是重新使用以前的构建内容。在 3.15 版本加入: 如果 CMake 生成器是
Green Hills MULTI且未被覆盖,则 GHS 工具集和目标系统自定义缓存变量的原始项目设置将传播到外部项目。SOURCE_SUBDIR <目录>在 3.7 版本加入.
当没有指定
CONFIGURE_COMMAND选项时,配置步骤假定外部项目在其源代码树的顶部有一个CMakeLists.txt文件(即在SOURCE_DIR中)。SOURCE_SUBDIR选项可用于指向源代码树中的替代目录,以用作 CMake 源代码树的顶部。这必须是一个相对路径,它将被解释为相对于SOURCE_DIR。在 3.14 版本加入: 当启用“BUILD_IN_SOURCE”选项时,“BUILD_COMMAND”用于指向源代码树中的替代目录。
CONFIGURE_HANDLED_BY_BUILD <bool>在 3.20 版本加入.
启用此选项可将配置步骤对其他外部项目的依赖性放宽为仅排序。这意味着配置步骤将在构建其外部项目依赖项后执行,但在重建其外部项目依赖项之一时不会将其标记为脏。当构建步骤足够智能以确定是否需要重新运行配置步骤时,可以启用此选项。 CMake 和 Meson 是构建系统的示例,它们的构建步骤足够智能,可以知道是否需要重新运行配置步骤。
- 构建步骤选项:
如果配置步骤假定外部项目使用 CMake 作为其构建系统,则构建步骤也将如此。否则,构建步骤将假定基于 Makefile 的构建,并简单地运行不带参数的“make”作为默认构建步骤。如果需要,可以使用自定义构建命令覆盖它。
如果主项目和外部项目都使用 make 作为它们的构建工具,则外部项目的构建步骤将作为使用 $(MAKE) 的递归 make 调用。这会将一些构建工具设置从主项目传递到外部项目。如果主项目或外部项目没有使用 make,除了配置步骤建立的那些之外,没有构建工具设置将传递给外部项目(即在主项目中运行
ninja -v将不会传递 ` -v` 到外部项目的构建步骤,即使它也使用ninja作为其构建工具)。BUILD_COMMAND <cmd>...覆盖默认构建命令(支持
generator expressions)。如果未给出此选项,将选择默认构建命令以最合适的方式与主构建集成(例如,对 Makefile 生成器使用递归make或:option:cmake --build 如果项目使用 CMake 构建)。可以使用空字符串指定此选项作为使构建步骤不执行任何操作的命令。BUILD_IN_SOURCE <bool>启用此选项后,构建将直接在外部项目的源代码树中完成。通常应该避免这种情况,通常首选使用单独的构建目录,但当外部项目采用源代码构建时,它会很有用。如果在源代码中构建,则不应指定
BINARY_DIR选项。BUILD_ALWAYS <bool>启用此选项会强制构建步骤始终运行。这可能是稳健地确保评估外部项目自己的构建依赖项而不是依赖默认的基于成功时间戳的方法的最简单方法。通常不需要此选项,除非希望开发人员以通过步骤目标依赖项无法检测到的方式修改外部项目构建所依赖的某些内容(例如,在没有下载方法的情况下使用
SOURCE_DIR,并且开发人员可能会修改源代码在SOURCE_DIR中)。BUILD_BYPRODUCTS <文件>...在 3.2 版本加入.
指定将由构建命令生成但可能会或可能不会由后续构建更新其修改时间的文件。在使用 Ninja 生成器时,也可能需要显式声明依赖项。这些最终作为“BYPRODUCTS”传递给构建步骤自己对 add_custom_command 的底层调用,它有额外的文档。
- 安装步骤选项:
如果配置步骤假定外部项目使用 CMake 作为其构建系统,则安装步骤也将如此。否则,安装步骤将采用基于 Makefile 的构建,并简单地运行“make install”作为默认构建步骤。如果需要,可以使用自定义安装命令覆盖它。
INSTALL_COMMAND <cmd>...外部项目自己的安装步骤作为主项目*build* 的一部分被调用。它在外部项目的构建步骤之后完成,可能在外部项目的测试步骤之前或之后完成(请参阅下面的
TEST_BEFORE_INSTALL选项)。外部项目的安装规则不是主项目安装规则的一部分,所以如果外部项目的任何东西应该作为主构建的一部分安装,这些需要在主构建中指定为额外的install()命令.默认安装步骤构建外部项目的“install”目标,但可以使用此选项使用自定义命令覆盖它(支持:manual:generator expressions <cmake-generator-expressions(7)>) .传递空字符串作为<cmd>会使安装步骤不执行任何操作。INSTALL_BYPRODUCTS <文件>...在 3.26 版本加入.
指定将由安装命令生成但可能会或可能不会由后续安装更新其修改时间的文件。在使用 Ninja 生成器时,也可能需要显式声明依赖项。这些最终作为“BYPRODUCTS”传递给安装步骤自己对 add_custom_command 的底层调用,它有额外的文档。
备注
如果在构建主工程时设置了
CMAKE_INSTALL_MODE环境变量,只有满足以下条件才会生效:主项目的配置步骤假定外部项目使用 CMake 作为其构建系统。
外部项目的安装命令实际运行。请注意,由于 ExternalProject 可能在内部使用时间戳的方式,如果不需要重新执行安装步骤所依赖的任何内容,则安装命令也可能不需要运行。
另请注意,
ExternalProject不会检查CMAKE_INSTALL_MODE环境变量是否从一次运行更改为另一次运行。- 测试步骤选项:
仅当至少提供以下“TEST_...”选项之一时才定义测试步骤。
TEST_COMMAND <cmd> ...覆盖默认测试命令(支持
generator expressions)。如果未给出此选项,则测试步骤的默认行为是构建外部项目自己的“测试”目标。此选项可以用<cmd>指定为空字符串,这允许仍然定义测试步骤,但它什么都不做。如果提供空字符串作为测试命令,请不要指定任何其他TEST_...选项,但如果不需要测试步骤目标,则最好完全省略所有TEST_...选项。TEST_BEFORE_INSTALL <bool>启用此选项后,测试步骤将在安装步骤之前执行。默认行为是在安装步骤之后运行测试步骤。
TEST_AFTER_INSTALL <bool>此选项主要用作指示需要测试步骤但所有默认行为都足够的方式。使用布尔真值指定此选项可确保定义测试步骤并且它在安装步骤之后进行。如果同时启用了
TEST_BEFORE_INSTALL和TEST_AFTER_INSTALL,后者将被静默忽略。TEST_EXCLUDE_FROM_MAIN <bool>在 3.2 版本加入.
如果启用,主构建的默认 ALL 目标将不依赖于测试步骤。这可能是确保测试步骤已定义但仅在手动请求时才被调用的有用方法。这可能会导致为“安装”或“构建”步骤自动创建一个步骤目标。请参阅政策:policy:CMP0114。
- 输出记录选项:
以下每个
LOG_...选项都可用于将相关步骤包装在脚本中以将其输出捕获到文件中。如果提供,日志文件将在LOG_DIR中创建,否则将在具有特定步骤文件名的STAMP_DIR目录中创建。LOG_DOWNLOAD <bool>启用后,下载步骤的输出将记录到文件中。
LOG_UPDATE <bool>启用后,更新步骤的输出将记录到文件中。
LOG_PATCH <bool>在 3.14 版本加入.
启用后,补丁步骤的输出将记录到文件中。
LOG_CONFIGURE <bool>启用后,配置步骤的输出将记录到文件中。
LOG_BUILD <bool>启用后,构建步骤的输出将记录到文件中。
LOG_INSTALL <bool>启用后,安装步骤的输出将记录到文件中。
LOG_TEST <bool>启用后,测试步骤的输出将记录到文件中。
LOG_MERGED_STDOUTERR <bool>在 3.14 版本加入.
启用后,stdout 和 stderr 将合并到输出被记录到文件的任何步骤。
LOG_OUTPUT_ON_FAILURE <bool>在 3.14 版本加入.
此选项仅在至少启用其他
LOG_<step>选项之一时才有效。如果启用了记录到文件的步骤发生错误,如果LOG_OUTPUT_ON_FAILURE设置为 true,则该步骤的输出将打印到控制台。对于记录大量输出的情况,可能只将输出的末尾打印到控制台。
- 终端访问选项:
在 3.4 版本加入.
在某些情况下,步骤可以直接访问终端。授予对终端的步骤访问权限可以允许它在需要时接收终端输入,例如其他选项未提供的身份验证详细信息。使用
Ninja生成器,这些选项将步骤放在consolejob pool中。每个步骤都可以通过以下选项单独访问终端:USES_TERMINAL_DOWNLOAD <bool>授予下载步骤访问终端的权限。
USES_TERMINAL_UPDATE <bool>授予更新步骤访问终端的权限。
USES_TERMINAL_PATCH <bool>在 3.23 版本加入.
授予补丁步骤对终端的访问权限。
USES_TERMINAL_CONFIGURE <bool>授予配置步骤对终端的访问权限。
USES_TERMINAL_BUILD <bool>授予构建步骤对终端的访问权限。
USES_TERMINAL_INSTALL <bool>授予安装步骤对终端的访问权限。
USES_TERMINAL_TEST <bool>授予测试步骤访问终端的权限。
- 目标选项:
取决于 <目标>...指定外部项目依赖的其他目标。在执行任何外部项目的步骤之前,其他目标将被更新。因为外部项目在内部为每个步骤使用额外的自定义目标,所以
DEPENDS选项是确保所有这些步骤都依赖于其他目标的最方便的方法。简单地执行add_dependencies(<name> <targets>)不会使任何步骤依赖于<targets>。EXCLUDE_FROM_ALL <bool>启用后,此选项会从主构建的默认 ALL 目标中排除外部项目。
STEP_TARGETS <step-target>...为指定步骤生成自定义目标。如果需要手动触发这些步骤,或者如果它们需要用作其他目标的依赖项,则这是必需的。如果未指定此选项,则默认值取自
EP_STEP_TARGETS目录属性。有关此选项的影响的进一步讨论,请参阅下面的 ExternalProject_Add_StepTargets。INDEPENDENT_STEP_TARGETS <step-target>...自 3.19 版本弃用: 仅当政策:policy:CMP0114 未设置为``NEW`` 时才允许这样做。
为指定步骤生成自定义目标并防止这些目标应用通常的依赖项。如果未指定此选项,则默认值取自
EP_INDEPENDENT_STEP_TARGETS目录属性。此选项最适用于允许独立驱动各个步骤,例如对于 CDash 设置,其中每个步骤都应单独启动和报告,而不是作为一个整体构建。有关此选项的影响的进一步讨论,请参阅下面的 ExternalProject_Add_StepTargets。
- 杂项选项:
LIST_SEPARATOR <sep>对于各种“..._COMMAND”选项和“CMAKE_ARGS”中的任何一个,在指定的命令行中将“;”替换为“<sep>”。这在命令中给出列表变量时很有用,它们应该以空格分隔的参数结尾(在这种情况下,
<sep>将是单个空格字符串)。命令 <cmd>...任何其他
..._COMMAND选项都可以根据需要在它们后面加上尽可能多的COMMAND ...选项来附加额外的命令(generator expressions被支持)。例如:ExternalProject_Add(example ... # Download options, etc. BUILD_COMMAND ${CMAKE_COMMAND} -E echo "Starting $<CONFIG> build" COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --config $<CONFIG> COMMAND ${CMAKE_COMMAND} -E echo "$<CONFIG> build complete" )
还应注意,每个构建步骤都是通过调用 ExternalProject_Add_Step 来创建的。有关某些选项支持的自动替换,请参阅该命令的文档。
获取项目属性¶
- ExternalProject_Get_Property¶
ExternalProject_Get_Property()函数检索外部项目目标属性:ExternalProject_Get_Property(<name> <prop1> [<prop2>...])
该函数将属性值存储在同名变量中。属性名称对应于
ExternalProject_Add()的关键字参数名称。例如,可以像这样检索源目录:ExternalProject_Get_property(myExtProj SOURCE_DIR) message("Source dir of myExtProj = ${SOURCE_DIR}")
显式步骤管理¶
ExternalProject_Add() 函数本身通常足以将外部项目合并到主构建中。某些场景需要额外的工作来实现所需的行为,例如添加自定义步骤或使步骤可用作可手动触发的目标。 ExternalProject_Add_Step()、ExternalProject_Add_StepTargets() 和 ExternalProject_Add_StepDependencies 函数提供了实现这种步级功能所需的较低级别的控制。
- ExternalProject_Add_Step¶
ExternalProject_Add_Step()函数为之前调用 ExternalProject_Add 定义的外部项目指定了一个额外的自定义步骤:ExternalProject_Add_Step(<name> <step> [<option>...])
<name>与传递给 ExternalProject_Add 的原始调用的名称相同。指定的<step>不能是预定义的步骤之一(mkdir、download、update、patch、configure、build、install或test)。支持的选项是:命令 <cmd>...此自定义步骤要执行的命令行(支持
generator expressions)。该选项可以重复多次以指定要按顺序执行的多个命令。评论“<文本> ...”执行自定义步骤时要打印的文本。
DEPENDEES <step>...此步骤所依赖的其他步骤(自定义或预定义)。
DEPENDERS <step>...依赖于此新自定义步骤的其他步骤(自定义或预定义)。
取决于 <文件>...此自定义步骤所依赖的文件。
独立 <bool>在 3.19 版本加入.
指定此步骤是否独立于由
ExternalProject_Add()的DEPENDS选项指定的外部依赖项。默认值为“假”。标记为独立的步骤可能仅依赖于其他标记为独立的步骤。请参阅政策:policy:CMP0114。请注意,术语“独立”的使用仅指独立于“DEPENDS”选项指定的外部目标,并且与一个步骤对其他步骤的依赖关系是正交的。
如果通过
ExternalProject_Add()STEP_TARGETS选项或ExternalProject_Add_StepTargets()函数为独立步骤创建步骤目标,它将不依赖于外部目标,但可能依赖于目标其他步骤。副产品 <文件>...在 3.2 版本加入.
将由此自定义步骤生成的文件,但其修改时间可能会或可能不会被后续构建更新。在使用 Ninja 生成器时,也可能需要显式声明依赖项。此文件列表最终将作为
BYPRODUCTS选项传递给add_custom_command()用于在内部实现自定义步骤,它有额外的文档。总是 <bool>启用后,此选项指定应始终运行自定义步骤(即它始终被视为过时)。
EXCLUDE_FROM_MAIN <bool>启用时,此选项指定外部项目的主要目标不依赖于自定义步骤。这可能会导致为该步骤所依赖的步骤自动创建步骤目标。请参阅政策:policy:CMP0114。
WORKING_DIRECTORY <目录>指定在运行自定义步骤的命令之前要设置的工作目录。如果未指定此选项,则目录将是调用 ExternalProject_Add_Step() 时 CMAKE_CURRENT_BINARY_DIR 的值。
日志 <bool>如果设置,这会导致自定义步骤的输出被捕获到外部项目的“LOG_DIR”(如果提供)或“STAMP_DIR”中的文件。
USES_TERMINAL <bool>如果启用,这将允许自定义步骤在可能的情况下直接访问终端。
处理每个标准和自定义步骤的命令行、注释、工作目录和副产品以替换标记``<SOURCE_DIR>``、
<SOURCE_SUBDIR>、<BINARY_DIR>、<INSTALL_DIR ><TMP_DIR>、<DOWNLOAD_DIR>和<DOWNLOADED_FILE>及其在对ExternalProject_Add()的原始调用中定义的相应属性值。在 3.3 版本加入: 令牌替换扩展到副产品。
在 3.11 版本加入:
<DOWNLOAD_DIR>替换标记。
- ExternalProject_Add_StepTargets¶
ExternalProject_Add_StepTargets()函数为列出的步骤生成目标。每个创建的目标的名称将采用“<name>-<step>”的形式:ExternalProject_Add_StepTargets(<name> <step1> [<step2>...])
为步骤创建目标允许它用作另一个目标的依赖项或手动触发。拥有特定步骤的目标还允许通过在构建命令行上指定目标来相互独立地驱动它们。例如,您可能正在提交到一个基于子项目的仪表板,您希望在其中驱动构建的配置部分,然后提交到仪表板,然后是构建部分,然后是测试。如果您调用一个自定义目标,该目标依赖于步骤依赖链中途的一个步骤,那么所有先前的步骤也将运行以确保一切都是最新的。
在内部,
ExternalProject_Add()调用ExternalProject_Add_Step()来创建每个步骤。如果指定了任何“STEP_TARGETS”,那么“ExternalProject_Add_StepTargets()”也会在 ExternalProject_Add_Step 之后被调用。即使在STEP_TARGETS选项中未提及某个步骤,稍后仍然可以调用ExternalProject_Add_StepTargets()来手动定义该步骤的目标。ExternalProject_Add 的 STEP_TARGETS 选项通常是确保为感兴趣的特定步骤创建目标的最简单方法。对于自定义步骤,如果还应为该自定义步骤创建目标,则必须显式调用“ExternalProject_Add_StepTargets()”。这两个选项的替代方法是填充
EP_STEP_TARGETS目录属性。它充当步骤目标选项的默认值,并且可以避免在定义多个外部项目时重复指定同一组步骤目标。在 3.19 版本加入: 如果
CMP0114设置为NEW,步骤目标完全负责保存实现其步骤的自定义命令。ExternalProject_Add创建的主要目标依赖于步骤目标,步骤目标相互依赖。目标级依赖项与每个步骤的自定义命令使用的文件级依赖项相匹配。使用ExternalProject_Add_Step()的INDEPENDENT选项创建的步骤的目标不依赖于ExternalProject_Add()的DEPENDS选项指定的外部目标。预定义的步骤“mkdir”、“download”、“update”和“patch”是独立的。如果
CMP0114不是NEW,则可以使用以下已弃用的行为:可以在 <name> 之后和第一步之前立即指定已弃用的 NO_DEPENDS 选项。如果指定了
NO_DEPENDS选项,则步骤目标将不依赖于外部项目的依赖项(即依赖于由ExternalProject_Add()创建的<name>自定义目标的任何依赖项)。这对于“下载”、“更新”和“补丁”步骤通常是安全的,因为它们通常不需要更新和构建依赖项。但是,对任何其他预定义步骤使用“NO_DEPENDS”可能会破坏并行构建。仅在确定命名步骤真正没有依赖性的情况下使用NO_DEPENDS。对于自定义步骤,请考虑自定义命令是否需要配置、构建和安装依赖项。ExternalProject_Add()的INDEPENDENT_STEP_TARGETS选项,或EP_INDEPENDENT_STEP_TARGETS目录属性,告诉函数使用NO_DEPENDS选项在内部调用ExternalProject_Add_StepTargets()指定步骤.
- ExternalProject_Add_StepDependencies¶
在 3.2 版本加入.
ExternalProject_Add_StepDependencies()函数可用于向步骤添加依赖项。添加的依赖项必须是 CMake 已知的目标(这些可以是普通的可执行文件或库目标、自定义目标甚至是另一个外部项目的步骤目标):ExternalProject_Add_StepDependencies(<name> <step> <target1> [<target2>...])
此函数负责设置目标和文件级别的依赖关系,并将确保并行构建不会中断。每当为
ExternalProject模块生成的某些步骤目标添加依赖项时,都应该使用它而不是 add_dependencies 。
例子¶
以下示例展示了如何从 github 下载并构建一个名为 FooBar 的假设项目:
include(ExternalProject)
ExternalProject_Add(foobar
GIT_REPOSITORY git@github.com:FooCo/FooBar.git
GIT_TAG origin/release/1.2.3
)
为了示例,还定义了第二个假设的外部项目,称为 SecretSauce,它是从 Web 服务器下载的。提供了两个 URL 以利用更快的内部网络(如果可用),并回退到速度较慢的外部服务器。该项目是一个典型的“Makefile”项目,没有配置步骤,因此一些默认命令被覆盖。构建只需要构建 sauce 目标:
find_program(MAKE_EXE NAMES gmake nmake make)
ExternalProject_Add(secretsauce
URL http://intranet.somecompany.com/artifacts/sauce-2.7.tgz
https://www.somecompany.com/downloads/sauce-2.7.zip
URL_HASH MD5=d41d8cd98f00b204e9800998ecf8427e
CONFIGURE_COMMAND ""
BUILD_COMMAND ${MAKE_EXE} sauce
)
假设 secretsauce 的构建步骤要求必须已经构建了 foobar。这可以像这样强制执行:
ExternalProject_Add_StepDependencies(secretsauce build foobar)
另一种选择是为“foobar”的构建步骤创建一个自定义目标,并使“secretsauce”依赖于该目标而不是整个“foobar”项目。这意味着 foobar 只需要构建,在构建 secretsauce 之前不需要运行它的安装或测试步骤。依赖项也可以与“secretsauce”项目一起定义:
ExternalProject_Add_StepTargets(foobar build)
ExternalProject_Add(secretsauce
URL http://intranet.somecompany.com/artifacts/sauce-2.7.tgz
https://www.somecompany.com/downloads/sauce-2.7.zip
URL_HASH MD5=d41d8cd98f00b204e9800998ecf8427e
CONFIGURE_COMMAND ""
BUILD_COMMAND ${MAKE_EXE} sauce
DEPENDS foobar-build
)
除了调用 ExternalProject_Add_StepTargets(),目标可以与 foobar 项目本身一起定义:
ExternalProject_Add(foobar
GIT_REPOSITORY git@github.com:FooCo/FooBar.git
GIT_TAG origin/release/1.2.3
STEP_TARGETS build
)
如果许多外部项目应该有相同的步骤目标集,设置目录属性可能更方便。在使用 ExternalProject_Add() 创建外部项目之前,可以通过设置 EP_STEP_TARGETS` 目录属性来自动创建 build 步骤目标:
set_property(DIRECTORY PROPERTY EP_STEP_TARGETS build)
最后,假设“secretsauce”提供了一个名为“makedoc”的脚本,可用于生成自己的文档。进一步假设脚本期望输出目录作为唯一参数提供,并且它应该从“secretsauce”源目录运行。可以像这样定义一个自定义步骤和一个自定义目标来触发脚本:
ExternalProject_Add_Step(secretsauce docs
COMMAND <SOURCE_DIR>/makedoc <BINARY_DIR>
WORKING_DIRECTORY <SOURCE_DIR>
COMMENT "Building secretsauce docs"
ALWAYS TRUE
EXCLUDE_FROM_MAIN TRUE
)
ExternalProject_Add_StepTargets(secretsauce docs)
然后可以从主构建中触发自定义步骤,如下所示:
cmake --build . --target secretsauce-docs