ExternalProject

外部專案定義

ExternalProject_Add

ExternalProject_Add() 函數建立一個自訂目標,以驅動外部專案的下載、更新/修補、設定、建置、安裝和測試步驟

ExternalProject_Add(<name> [<option>...])

如果需要(例如,用於 CDash 提交),可以獨立驅動流程中的個別步驟,並且可以定義額外的自訂步驟,以及控制步驟依賴項的能力。用於管理外部專案的目錄結構也可以自訂。此函數支援大量選項,可用於調整外部專案的行為。

目錄選項

在大多數情況下,預設目錄佈局已足夠。這很大程度上是一個實作細節,主專案通常不需要變更。然而,在某些情況下,控制目錄佈局可能是有用或必要的。從主要建置可以使用 ExternalProject_Get_Property() 命令來檢索其值的角度來看,目錄選項可能更有用,從而允許主專案參考外部專案的建置產物。

PREFIX <dir>

外部專案的根目錄。除非另有說明,否則與外部專案相關的所有其他目錄都將在此目錄下建立。

TMP_DIR <dir>

用於儲存臨時檔案的目錄。

STAMP_DIR <dir>

用於儲存每個步驟的時間戳記的目錄。除非被 LOG_DIR 覆蓋(請參閱下方的 *記錄選項*),否則來自個別步驟的日誌檔案也會在此目錄中建立。

LOG_DIR <dir>

在版本 3.14 中新增。

用於儲存每個步驟的日誌的目錄。

DOWNLOAD_DIR <dir>

用於在解壓縮下載檔案之前儲存它們的目錄。此目錄僅供 URL 下載方法使用,所有其他下載方法都直接使用 SOURCE_DIR

SOURCE_DIR <dir>

來源目錄,下載的內容將解壓縮到其中,或者對於非 URL 下載方法,儲存庫應簽出、複製等的目錄。如果未指定下載方法,則此目錄必須指向外部專案已解壓縮或複製/簽出的現有目錄。

注意

如果指定了下載方法,則可能會刪除來源目錄的任何現有內容。只有 URL 下載方法會檢查此目錄是否遺失或為空,然後才啟動下載,如果目錄不為空,則會停止並顯示錯誤。所有其他下載方法都會靜默捨棄來源目錄的任何先前內容。

BINARY_DIR <dir>

指定建置目錄位置。如果啟用 BUILD_IN_SOURCE,則會忽略此選項。

INSTALL_DIR <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 目錄屬性,則外部專案的組件將儲存在指定的基礎目錄下

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>

如果未指定 PREFIXEP_PREFIXEP_BASE,則預設值是將 PREFIX 設定為 <name>-prefix。相對路徑是相對於呼叫 CMAKE_CURRENT_BINARY_DIR 時的 CMAKE_CURRENT_BINARY_DIR 來解釋。

下載步驟選項

如果使用 SOURCE_DIR 選項指向現有的非空目錄,則可以省略下載方法。否則,必須指定以下下載方法之一(不應給出多個下載方法)或提供自訂的 DOWNLOAD_COMMAND

DOWNLOAD_COMMAND <cmd>...

覆寫用於下載步驟的命令(支援 產生器 表達式)。如果指定了此選項,則所有其他下載選項都將被忽略。為 <cmd> 提供空字串實際上會停用下載步驟。

URL

URL <url1> [<url2>...]

外部專案來源的路徑和/或 URL 清單。當給出多個 URL 時,將依次嘗試它們,直到其中一個成功。URL 可以是本機檔案系統中的普通路徑(在這種情況下,它必須是唯一提供的 URL)或 file(DOWNLOAD) 命令支援的任何可下載 URL。本機檔案系統路徑可以指向現有目錄或封存檔案,而 URL 預期指向可以視為封存的檔案。當使用封存時,除非設定了 DOWNLOAD_NO_EXTRACT 選項以防止解壓縮,否則將自動解壓縮封存。封存類型是透過檢查實際內容而不是使用基於檔案副檔名的邏輯來確定的。

在版本 3.7 中變更:允許多個 URL。

URL_HASH <algo>=<hashValue>

要下載的封存檔案的雜湊值。引數的格式應為 <algo>=<hashValue>,其中 algo 可以是 file() 命令支援的任何雜湊演算法。強烈建議為 URL 下載指定此選項,因為它可以確保下載內容的完整性。它也用作先前下載檔案的檢查,如果本機目錄中已經有來自較早下載且與指定雜湊值相符的檔案,則可以完全避免連線到遠端位置。

URL_MD5 <md5>

等效於 URL_HASH MD5=<md5>

DOWNLOAD_NAME <fname>

用於下載檔案的檔案名稱。如果未給定,則使用 URL 的結尾來確定檔案名稱。此選項很少需要,預設名稱通常適用,並且通常不在 ExternalProject 模組內部的程式碼之外使用。

DOWNLOAD_EXTRACT_TIMESTAMP <bool>

在版本 3.24 中新增。

當指定為 true 值時,解壓縮檔案的時間戳記將與封存中的時間戳記相符。當為 false 時,解壓縮檔案的時間戳記將反映執行解壓縮的時間。如果下載 URL 變更,則基於封存中的時間戳記可能會導致相依目標在可能應該重建時未重建。因此,除非檔案時間戳記在某些方面對專案很重要,否則請使用 false 值作為此選項。如果未給定 DOWNLOAD_EXTRACT_TIMESTAMP,則預設為 false。請參閱原則 CMP0135

DOWNLOAD_NO_EXTRACT <bool>

在版本 3.6 中新增。

允許透過為此選項傳遞布林值 true 來停用下載步驟的解壓縮部分。如果未給定此選項,則下載的內容將在需要時自動解壓縮。如果已停用解壓縮,則下載檔案的完整路徑在後續步驟中或作為具有 ExternalProject_Get_Property() 命令的 DOWNLOADED_FILE 屬性可用為 <DOWNLOADED_FILE>

DOWNLOAD_NO_PROGRESS <bool>

可用於停用記錄下載進度。如果未給定此選項,則將記錄下載進度訊息。

TIMEOUT <seconds>

檔案下載操作允許的最長時間。

INACTIVITY_TIMEOUT <seconds>

在版本 3.19 中新增。

在一段非活動時間後終止操作。

HTTP_USERNAME <username>

在版本 3.7 中新增。

如果需要驗證,則用於下載操作的使用者名稱。

HTTP_PASSWORD <password>

在版本 3.7 中新增。

如果需要驗證,則用於下載操作的密碼。

HTTP_HEADER <header1> [<header2>...]

在版本 3.7 中新增。

為下載操作提供任意 HTTP 標頭清單。這對於存取 AWS 等系統中的內容可能很有用。

TLS_VERSION <min>

在版本 3.30 中新增。

https:// URL 指定最小 TLS 版本。如果未提供此選項,則將改為使用 CMAKE_TLS_VERSION 變數或 CMAKE_TLS_VERSION 環境變數的值(請參閱 file(DOWNLOAD))。

此選項也適用於 git clone 叫用,儘管預設行為有所不同。如果未指定 TLS_VERSION 選項、CMAKE_TLS_VERSION 變數或 CMAKE_TLS_VERSION 環境變數,則行為將由 git 的預設值或使用者可能在全域層級設定的 http.sslVersion git config 選項決定。

TLS_VERIFY <bool>

指定是否應為 https:// URL 執行憑證驗證。如果未提供此選項,則將改為使用 CMAKE_TLS_VERIFY 變數或 CMAKE_TLS_VERIFY 環境變數的值(請參閱 file(DOWNLOAD))。如果這兩者都未設定,則不會執行憑證驗證。在無法提供 URL_HASH 的情況下,此選項可以是替代的驗證措施。

此選項也適用於 git clone 叫用,儘管預設行為有所不同。如果未指定 TLS_VERIFY 選項、CMAKE_TLS_VERIFY 變數或 CMAKE_TLS_VERIFY 環境變數,則行為將由 git 的預設值 (true) 或使用者可能在全域層級設定的 http.sslVerify git config 選項決定。

在版本 3.6 中變更:先前此選項不適用於 git clone 叫用。

在版本 3.30 中變更:先前未檢查 CMAKE_TLS_VERIFY 環境變數。

TLS_CAINFO <file>

指定自訂憑證授權單位檔案,以在啟用 TLS_VERIFY 時使用。如果未指定此選項,則將改為使用 CMAKE_TLS_CAINFO 變數的值(請參閱 file(DOWNLOAD)

NETRC <level>

在版本 3.11 中新增。

指定是否要將 .netrc 檔案用於操作。如果未指定此選項,則將改為使用 CMAKE_NETRC 變數的值(請參閱 file(DOWNLOAD))。有效層級為

IGNORED

.netrc 檔案被忽略。這是預設值。

OPTIONAL

.netrc 檔案是可選的,並且 URL 中的資訊是首選。將掃描檔案以尋找 URL 中未指定的任何資訊。

REQUIRED

.netrc 檔案是必要的,並且 URL 中的資訊被忽略。

NETRC_FILE <file>

在版本 3.11 中新增。

如果 NETRC 層級為 OPTIONALREQUIRED,則指定替代的 .netrc 檔案,而不是您主目錄中的檔案。如果未指定此選項,則將改為使用 CMAKE_NETRC_FILE 變數的值(請參閱 file(DOWNLOAD)

在版本 3.1 中新增:新增了對 tbz2.tar.xz.txz.7z 副檔名的支援。

Git

注意:如果使用此下載方法,則需要 1.6.5 或更高版本的 git。

GIT_REPOSITORY <url>

git 儲存庫的 URL。git 命令理解的任何 URL 都可以使用。

在版本 3.27 中變更:相對 URL 將根據父專案的遠端解析,但受 CMP0150 限制。請參閱原則文件,瞭解如何選取遠端,包括遠端選取可能會失敗的條件。本機檔案系統遠端應始終使用絕對路徑。

GIT_TAG <tag>

Git 分支名稱、標籤或提交雜湊。請注意,分支名稱和標籤通常應指定為遠端名稱(即 origin/myBranch 而不是簡單的 myBranch)。這可確保如果遠端端點的標籤已移動或分支已重新基準化或歷史記錄已重寫,則本機複製仍將正確更新。但是,一般而言,出於多種原因,應優先指定提交雜湊

  • 如果本機複製已經具有與雜湊對應的提交,則每次重新執行 CMake 時都不需要執行 git fetch 來檢查變更。如果使用許多外部專案,這可以顯著加快速度。

  • 使用特定的 git 雜湊可確保主專案本身的歷史記錄可以完全追溯到外部專案演進中的特定點。如果改為使用分支或標籤名稱,則簽出主專案的特定提交不一定將整個建置釘選到外部專案生命週期中的特定點。缺乏這種確定性行為會使主專案失去可追溯性和可重複性。

如果啟用了 GIT_SHALLOW,則 GIT_TAG 僅適用於分支名稱和標籤。不允許使用提交雜湊。

請注意,如果未提供,GIT_TAG 預設為 master,而不是預設的 Git 分支名稱。

GIT_REMOTE_NAME <name>

遠端的選用名稱。如果未指定此選項,則預設為 origin

GIT_SUBMODULES <module>...

也應更新的特定 git 子模組。如果未提供此選項,則將更新所有 git 子模組。

在版本 3.16 中變更:CMP0097 設定為 NEW 時,如果此值設定為空字串,則不會初始化或更新子模組。

GIT_SUBMODULES_RECURSE <bool>

在版本 3.17 中新增。

指定 git 子模組(如果有的話)是否應透過將 --recursive 旗標傳遞給 git submodule update 來遞迴更新。如果未指定,則預設為開啟。

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 <strategy>

在版本 3.18 中新增。

GIT_TAG 引用遠端分支時,可以使用此選項來指定更新步驟的行為方式。<strategy> 必須是以下其中之一

CHECKOUT

忽略本機分支,並始終簽出由 GIT_TAG 指定的分支。

REBASE

嘗試將當前分支重新基準化到由 GIT_TAG 指定的分支。如果存在本機未提交的變更,它們將首先被暫存,並在重新基準化後再次彈出。如果重新基準化或彈出暫存的變更失敗,則中止重新基準化並停止並顯示錯誤。當不存在 GIT_REMOTE_UPDATE_STRATEGY 時,這是預設策略,除非預設值已被 CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY 覆寫(請參閱下文)。請注意,如果 GIT_TAG 中指定的分支與當前正在追蹤的上游分支不同,則執行重新基準化是不安全的。在這種情況下,REBASE 將靜默地被視為 CHECKOUT

REBASE_CHECKOUT

REBASE 相同,但如果重新基準化失敗,則將在重新基準化之前的原始 HEAD 位置建立帶註解的標籤,然後像 CHECKOUT 策略一樣簽出 GIT_TAG。儲存在帶註解標籤上的訊息將提供有關嘗試的資訊,並且標籤名稱將包含時間戳記,以便每次失敗的執行都會新增一個新標籤。此策略可確保不會遺失任何變更,但如果 GIT_TAG 引用有效的 ref,則更新應始終成功,除非存在無法成功彈出的未提交變更。

可以設定變數 CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY 以覆寫預設策略。專案不應設定此變數,它旨在供使用者設定。它主要用於持續整合腳本中,以確保當遠端分支上的歷史記錄被重寫時,建置不會以意外的變更或由於重新基準化操作期間的衝突而導致的建置失敗結束。

Subversion

SVN_REPOSITORY <url>

Subversion 儲存庫的 URL。

SVN_REVISION -r<rev>

要從 Subversion 儲存庫簽出的修訂版本。

SVN_USERNAME <username>

Subversion 簽出和更新的使用者名稱。

SVN_PASSWORD <password>

Subversion 簽出和更新的密碼。

SVN_TRUST_CERT <bool>

指定是否信任 Subversion 伺服器站點憑證。如果啟用,則 --trust-server-cert 選項將傳遞到 svn 簽出和更新命令。

Mercurial

HG_REPOSITORY <url>

mercurial 儲存庫的 URL。

HG_TAG <tag>

Mercurial 分支名稱、標籤或提交 ID。

CVS

CVS_REPOSITORY <cvsroot>

CVS 儲存庫的 CVSROOT。

CVS_MODULE <mod>

要從 CVS 儲存庫簽出的模組。

CVS_TAG <tag>

要從 CVS 儲存庫簽出的標籤。

更新步驟選項

每當重新執行 CMake 時,預設情況下,如果下載方法支援更新(例如,如果 GIT_TAG 未引用特定提交,則會檢查 git 儲存庫),則外部專案的來源將會更新。

UPDATE_COMMAND <cmd>...

覆寫下載方法 (download method) 的更新步驟 (update step),使用自訂命令。此命令可使用 產生器 表達式

UPDATE_DISCONNECTED <bool>

在版本 3.2 中新增。

啟用後,此選項會略過更新步驟(但請參閱下文瞭解變更行為,在某些情況下並非如此)。它不會阻止下載步驟。更新步驟仍然可以作為步驟目標新增(請參閱 ExternalProject_Add_StepTargets()),並手動呼叫。如果您希望允許開發人員在斷開網路連線時建置專案,這會很有用(儘管下載步驟可能仍然需要網路連線)。

在版本 3.27 中變更:UPDATE_DISCONNECTED 為 true 時,如果更新或下載步驟的任何詳細資訊變更,則將會執行更新步驟。此外,如果使用 git 下載/更新方法,更新邏輯將會修改為略過連線遠端伺服器的嘗試。如果 GIT_TAG 提及本機未知的 ref,更新步驟將會停止並出現嚴重錯誤。

當此選項存在時,通常建議將該值設為開發人員可控制的快取變數,而不是硬式編碼。如果未提供此選項,則預設值取自 EP_UPDATE_DISCONNECTED 目錄屬性。如果該屬性也未定義,則更新會照常執行。EP_UPDATE_DISCONNECTED 目錄屬性旨在方便控制專案目錄階層中整個區段的 UPDATE_DISCONNECTED 行為,並且可能是讓開發人員控制是否執行更新的更方便方法(假設專案也提供快取變數或一些其他方便的方法來設定目錄屬性)。

這可能會導致自動為 download 步驟建立步驟目標。請參閱政策 CMP0114

修補步驟選項

PATCH_COMMAND <cmd>...

指定自訂命令,在更新後修補來源。預設情況下,未定義修補命令。請注意,定義適當且穩健執行的修補命令可能非常困難,尤其是對於 git 等下載方法,其中變更 GIT_TAG 不會捨棄先前修補程式的變更,但在更新到新標籤後,修補命令將再次被呼叫。

設定步驟選項

設定步驟在下載和更新步驟之後執行。預設情況下,外部專案會被假定為 CMake 專案,但如果需要,可以覆寫此設定。

CONFIGURE_COMMAND <cmd>...

預設設定命令會執行 CMake,並帶有一些基於主要專案的選項。新增的選項通常僅是使用與主要專案相同產生器所需的選項,但可以指定 CMAKE_GENERATOR 選項來覆寫此設定。專案負責新增任何工具鏈詳細資訊、旗標或它想要從主要專案重複使用或以其他方式指定的設定(請參閱下文的 CMAKE_ARGSCMAKE_CACHE_ARGSCMAKE_CACHE_DEFAULT_ARGS)。

對於非 CMake 外部專案,必須使用 CONFIGURE_COMMAND 選項來覆寫預設設定命令(支援 產生器 表達式)。對於不需要設定步驟的專案,請指定此選項,並使用空字串作為要執行的命令。

CMAKE_COMMAND /.../cmake

為設定步驟指定替代的 cmake 可執行檔(使用絕對路徑)。通常不建議這樣做,因為通常希望在整個建置過程中使用相同的 CMake 版本。如果已使用 CONFIGURE_COMMAND 指定自訂設定命令,則會忽略此選項。

CMAKE_GENERATOR <gen>

覆寫用於設定步驟的 CMake 產生器。如果沒有此選項,將會使用與主要建置相同的產生器。如果已使用 CONFIGURE_COMMAND 選項指定自訂設定命令,則會忽略此選項。

CMAKE_GENERATOR_PLATFORM <platform>

在版本 3.1 中新增。

將產生器特定的平台名稱傳遞給 CMake 命令(請參閱 CMAKE_GENERATOR_PLATFORM)。如果沒有 CMAKE_GENERATOR 選項就提供此選項,則會發生錯誤。

CMAKE_GENERATOR_TOOLSET <toolset>

將產生器特定的工具集名稱傳遞給 CMake 命令(請參閱 CMAKE_GENERATOR_TOOLSET)。如果沒有 CMAKE_GENERATOR 選項就提供此選項,則會發生錯誤。

CMAKE_GENERATOR_INSTANCE <instance>

在版本 3.11 中新增。

將產生器特定的執行個體選取傳遞給 CMake 命令(請參閱 CMAKE_GENERATOR_INSTANCE)。如果沒有 CMAKE_GENERATOR 選項就提供此選項,則會發生錯誤。

CMAKE_ARGS <arg>...

指定的引數會傳遞至 cmake 命令列。它們可以是 cmake 命令可理解的任何引數,而不僅限於由 -D... 引數定義的快取值(另請參閱 CMake 選項)。

在版本 3.3 中新增:引數可以使用 產生器 表達式

CMAKE_CACHE_ARGS <arg>...

這是指定快取變數的替代方法,在命令列長度問題可能成為問題時使用。引數應為 -Dvar:STRING=value 格式,然後將其轉換為 CMake set() 命令,並使用 FORCE 選項。這些 set() 命令會寫入預先載入指令碼,然後使用 cmake -C 命令列選項套用。

在版本 3.3 中新增:引數可以使用 產生器 表達式

CMAKE_CACHE_DEFAULT_ARGS <arg>...

在版本 3.2 中新增。

這與 CMAKE_CACHE_ARGS 選項相同,只是 set() 命令不包含 FORCE 關鍵字。這表示這些值僅作為初始預設值,並且不會覆寫先前執行中已設定的任何變數。請謹慎使用此選項,因為它可能會導致不同的行為,具體取決於建置是從全新的建置目錄開始,還是重複使用先前的建置內容。

在版本 3.15 中新增:如果 CMake 產生器是 Green Hills MULTI 且未被覆寫,則原始專案的 GHS 工具集和目標系統自訂快取變數的設定會傳播到外部專案中。

SOURCE_SUBDIR <dir>

在版本 3.7 中新增。

當未指定 CONFIGURE_COMMAND 選項時,設定步驟會假定外部專案在其來源樹狀結構的頂層(即在 SOURCE_DIR 中)具有 CMakeLists.txt 檔案。SOURCE_SUBDIR 選項可用於指向來源樹狀結構中的替代目錄,以用作 CMake 來源樹狀結構的頂層。這必須是相對路徑,並且將被解釋為相對於 SOURCE_DIR

在版本 3.14 中新增:當啟用 BUILD_IN_SOURCE 選項時,BUILD_COMMAND 用於指向來源樹狀結構中的替代目錄。

CONFIGURE_HANDLED_BY_BUILD <bool>

在版本 3.20 中新增。

啟用此選項會放寬設定步驟對其他外部專案的依賴性,使其僅為順序依賴 (order-only)。這表示設定步驟將在建置其外部專案依賴項之後執行,但當其外部專案依賴項之一重建時,它不會被標記為 dirty。當建置步驟足夠聰明,可以判斷設定步驟是否需要重新執行時,可以啟用此選項。CMake 和 Meson 是建置系統的範例,其建置步驟足夠聰明,可以知道設定步驟是否需要重新執行。

建置步驟選項

如果設定步驟假定外部專案使用 CMake 作為其建置系統,則建置步驟也將如此。否則,建置步驟將假定為基於 Makefile 的建置,並且僅執行不帶引數的 make 作為預設建置步驟。如果需要,可以使用自訂建置命令覆寫此設定。

如果主要專案和外部專案都使用 make 作為其建置工具,則外部專案的建置步驟會使用 $(MAKE) 作為遞迴 make 呼叫。這會將一些建置工具設定從主要專案傳遞到外部專案。如果主要專案或外部專案都沒有使用 make,則除了設定步驟建立的設定之外,不會將任何建置工具設定傳遞到外部專案(即,即使主要專案也使用 ninja 作為其建置工具,在主要專案中執行 ninja -v 也**不會**將 -v 傳遞到外部專案的建置步驟)。

BUILD_COMMAND <cmd>...

覆寫預設建置命令(支援 產生器 表達式)。如果未提供此選項,將會選擇預設建置命令,以便以最合適的方式與主要建置整合(例如,對於 Makefile 產生器使用遞迴 make,或者如果專案使用 CMake 建置,則使用 cmake --build)。可以將此選項指定為空字串作為命令,使建置步驟不執行任何操作。

BUILD_IN_SOURCE <bool>

啟用此選項後,建置將直接在外部專案的來源樹狀結構中完成。通常應避免這樣做,通常首選使用單獨的建置目錄,但當外部專案假定為 in-source 建置時,它可能很有用。如果在 in-source 建置,則不應指定 BINARY_DIR 選項。

BUILD_ALWAYS <bool>

啟用此選項會強制始終執行建置步驟。這可能是穩健地確保評估外部專案自身建置依賴項的最簡單方法,而不是依賴基於預設成功時間戳記的方法。除非開發人員預期會以無法透過步驟目標依賴性檢測到的方式修改外部專案建置所依賴的某些內容,否則通常不需要此選項(例如,SOURCE_DIR 在沒有下載方法的情況下使用,並且開發人員可能會修改 SOURCE_DIR 中的來源)。

BUILD_BYPRODUCTS <file>...

在版本 3.2 中新增。

指定將由建置命令產生的檔案,但這些檔案的修改時間可能會或可能不會在後續建置中更新。當使用 Ninja 產生器時,這也可能是顯式宣告依賴項所必需的。這些最終會作為 BYPRODUCTS 傳遞到建置步驟自身對 add_custom_command() 的底層呼叫,其中有其他文件記錄。

BUILD_JOB_SERVER_AWARE <bool>

在版本 3.28 中新增。

指定建置步驟知道 GNU Make 工作伺服器。請參閱 add_custom_command() 文件中關於其 JOB_SERVER_AWARE 選項的詳細資訊。此選項僅在指定顯式 BUILD_COMMAND 時相關。

安裝步驟選項

如果設定步驟假定外部專案使用 CMake 作為其建置系統,則安裝步驟也將如此。否則,安裝步驟將假定為基於 Makefile 的建置,並且僅執行 make install 作為預設建置步驟。如果需要,可以使用自訂安裝命令覆寫此設定。

INSTALL_COMMAND <cmd>...

外部專案自身的安裝步驟會作為主要專案的建置一部分被呼叫。它在外部專案的建置步驟之後完成,並且可能在外部專案的測試步驟之前或之後(請參閱下文的 TEST_BEFORE_INSTALL 選項)。外部專案的安裝規則不是主要專案安裝規則的一部分,因此如果主要建置中應安裝來自外部專案的任何內容,則需要在主要建置中將這些內容指定為額外的 install() 命令。預設安裝步驟會建置外部專案的 install 目標,但可以使用此選項的自訂命令覆寫此設定(支援 產生器 表達式)。將空字串作為 <cmd> 傳遞會使安裝步驟不執行任何操作。

INSTALL_BYPRODUCTS <file>...

在版本 3.26 中新增。

指定將由安裝命令產生的檔案,但這些檔案的修改時間可能會或可能不會在後續安裝中更新。當使用 Ninja 產生器時,這也可能是顯式宣告依賴項所必需的。這些最終會作為 BYPRODUCTS 傳遞到安裝步驟自身對 add_custom_command() 的底層呼叫,其中有其他文件記錄。

INSTALL_JOB_SERVER_AWARE <bool>

在版本 4.0 中新增。

指定安裝步驟知道 GNU Make 工作伺服器。請參閱 add_custom_command() 文件中關於其 JOB_SERVER_AWARE 選項的詳細資訊。此選項僅在指定顯式 INSTALL_COMMAND 時相關。

注意

如果在建置主要專案時設定了 CMAKE_INSTALL_MODE 環境變數,則只有在滿足以下條件時才會生效:

  • 主要專案的設定步驟假定外部專案使用 CMake 作為其建置系統。

  • 外部專案的安裝命令實際上會執行。請注意,由於 ExternalProject 可能在內部使用時間戳記的方式,如果安裝步驟依賴的任何內容都不需要重新執行,則安裝命令也可能不需要執行。

另請注意,ExternalProject 不會檢查 CMAKE_INSTALL_MODE 環境變數是否從一次執行變更為另一次執行。

測試步驟選項

僅當提供至少一個以下 TEST_... 選項時,才會定義測試步驟。

TEST_COMMAND <cmd>...

覆寫預設測試命令(支援 產生器 表達式)。如果未提供此選項,測試步驟的預設行為是建置外部專案自身的 test 目標。可以將此選項指定為 <cmd> 作為空字串,這允許仍然定義測試步驟,但它將不執行任何操作。如果提供空字串作為測試命令,請勿指定任何其他 TEST_... 選項,但如果不需要測試步驟目標,則最好完全省略所有 TEST_... 選項。

TEST_BEFORE_INSTALL <bool>

啟用此選項後,測試步驟將在安裝步驟之前執行。預設行為是測試步驟在安裝步驟之後執行。

TEST_AFTER_INSTALL <bool>

此選項主要用作指示需要測試步驟但所有預設行為都已足夠的方式。使用布林值 true 值指定此選項可確保定義測試步驟,並且它在安裝步驟之後執行。如果同時啟用 TEST_BEFORE_INSTALLTEST_AFTER_INSTALL,則後者會被靜默忽略。

TEST_EXCLUDE_FROM_MAIN <bool>

在版本 3.2 中新增。

如果啟用,主要建置的預設 ALL 目標將不依賴於測試步驟。這可能是確保定義測試步驟但僅在手動請求時才呼叫它的有用方法。這可能會導致自動為 installbuild 步驟建立步驟目標。請參閱政策 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 產生器,這些選項將步驟放置在 console 工作 中。可以透過以下選項單獨讓每個步驟存取終端機:

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 <targets>...

指定外部專案所依賴的其他目標。其他目標將在執行外部專案的任何步驟之前更新到最新狀態。由於外部專案在內部為每個步驟使用額外的自訂目標,因此 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 起已棄用:僅當政策 CMP0114 未設定為 NEW 時,才允許使用。

為指定的步驟產生自訂目標,並阻止將通常的依賴項套用至這些目標。如果未指定此選項,則預設值取自 EP_INDEPENDENT_STEP_TARGETS 目錄屬性。此選項主要用於允許獨立驅動個別步驟,例如對於 CDash 設定,其中每個步驟應單獨啟動和報告,而不是作為一個完整的建置。請參閱下文的 ExternalProject_Add_StepTargets(),以進一步討論此選項的效果。

雜項選項

LIST_SEPARATOR <sep>

對於任何各種 ..._COMMAND 選項,以及 CMAKE_ARGSExternalProject 將在指定的命令列中將 <sep> 替換為 ;。這可用於確保命令中包含文字 ;,在直接使用時,否則會被解釋為 CMake API 的引數分隔符號。請注意,應選擇分隔符號以避免與序列的非清單分隔符號用法混淆。例如,使用 LIST_SEPARATOR 允許將清單值傳遞到命令列上的 CMake 快取變數

ExternalProject_Add(example
  ... # Download options, etc.
  LIST_SEPARATOR ","
  CMAKE_ARGS "-DCMAKE_PREFIX_PATH:STRING=${first_prefix},${second_prefix}"
)
COMMAND <cmd>...

任何其他 ..._COMMAND 選項都可以透過在它們後面加上所需數量的 COMMAND ... 選項來附加其他命令(支援 產生器 表達式)。例如

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> 不得為預定義步驟之一 (mkdirdownloadupdatepatchconfigurebuildinstalltest)。支援的選項如下

COMMAND <cmd>...

此自訂步驟要執行的命令列 (支援 generator expressions)。此選項可以重複多次以指定要依序執行的多個命令。

COMMENT "<text>..."

自訂步驟執行時要列印的文字。

DEPENDEES <step>...

此步驟所依賴的其他步驟 (自訂或預定義)。

DEPENDERS <step>...

依賴此新自訂步驟的其他步驟 (自訂或預定義)。

DEPENDS <file>...

此自訂步驟所依賴的檔案。

INDEPENDENT <bool>

在版本 3.19 中新增。

指定此步驟是否獨立於 ExternalProject_Add()DEPENDS 選項指定的外部依賴項。預設值為 FALSE。標記為獨立的步驟可能僅依賴於其他標記為獨立的步驟。請參閱政策 CMP0114

請注意,此處「獨立」一詞的使用僅指獨立於 DEPENDS 選項指定的外部目標,並且與步驟對其他步驟的依賴性正交。

如果透過 ExternalProject_Add() STEP_TARGETS 選項或 ExternalProject_Add_StepTargets() 函數為獨立步驟建立步驟目標,則它將不依賴於外部目標,但可能依賴於其他步驟的目標。

BYPRODUCTS <file>...

在版本 3.2 中新增。

此自訂步驟將產生的檔案,但這些檔案的修改時間可能或可能不會在後續建置中更新。當使用 Ninja 產生器時,也可能需要明確宣告依賴項。此檔案清單最終將作為 BYPRODUCTS 選項傳遞給用於在內部實作自訂步驟的 add_custom_command(),該函數具有額外的文件說明。

ALWAYS <bool>

啟用後,此選項指定自訂步驟應始終執行 (即始終被視為過時)。

JOB_SERVER_AWARE <bool>

在版本 3.28 中新增。

指定自訂步驟知道 GNU Make 工作伺服器。請參閱 add_custom_command() 文件中關於其 JOB_SERVER_AWARE 選項的詳細資訊。

EXCLUDE_FROM_MAIN <bool>

啟用後,此選項指定外部專案的主要目標不依賴於自訂步驟。這可能會導致自動為此步驟所依賴的步驟建立步驟目標。請參閱政策 CMP0114

WORKING_DIRECTORY <dir>

指定在執行自訂步驟命令之前要設定的工作目錄。如果未指定此選項,則目錄將為呼叫 ExternalProject_Add_Step()CMAKE_CURRENT_BINARY_DIR 的值。

LOG <bool>

如果設定,這會導致自訂步驟的輸出被捕獲到外部專案的 LOG_DIR (如果提供) 或 STAMP_DIR 中的檔案。

USES_TERMINAL <bool>

如果啟用,這會讓自訂步驟在可能的情況下直接存取終端機。

每個標準和自訂步驟的命令列、註解、工作目錄和副產品都會經過處理,以將符記 <SOURCE_DIR><SOURCE_SUBDIR><BINARY_DIR><INSTALL_DIR> <TMP_DIR><DOWNLOAD_DIR><DOWNLOADED_FILE> 替換為原始 ExternalProject_Add() 呼叫中定義的對應屬性值。

Added in version 3.3: 符記替換擴展到副產品。

Added in version 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_Step() 之後也會呼叫 ExternalProject_Add_StepTargets()。即使 STEP_TARGETS 選項中未提及步驟,仍然可以在稍後呼叫 ExternalProject_Add_StepTargets() 以手動定義步驟的目標。

ExternalProject_Add()STEP_TARGETS 選項通常是確保為感興趣的特定步驟建立目標的最簡單方法。對於自訂步驟,如果也應為該自訂步驟建立目標,則必須明確呼叫 ExternalProject_Add_StepTargets()。這兩個選項的替代方案是填入 EP_STEP_TARGETS 目錄屬性。它充當步驟目標選項的預設值,並且可以節省在定義多個外部專案時必須重複指定相同的步驟目標集。

Added in version 3.19: 如果 CMP0114 設定為 NEW,步驟目標完全負責保存實作其步驟的自訂命令。ExternalProject_Add 建立的主要目標依賴於步驟目標,而步驟目標彼此依賴。目標級依賴性與每個步驟的自訂命令使用的檔案級依賴性相符。使用 ExternalProject_Add_Step()INDEPENDENT 選項建立的步驟目標不依賴於 ExternalProject_Add()DEPENDS 選項指定的外部目標。預定義步驟 mkdirdownloadupdatepatch 是獨立的。

如果 CMP0114 不是 NEW,則可以使用以下已棄用的行為

  • 可以在 <name> 之後和第一個步驟之前立即指定已棄用的 NO_DEPENDS 選項。如果指定了 NO_DEPENDS 選項,則步驟目標將不依賴於外部專案的依賴項 (即不依賴於 ExternalProject_Add() 建立的 <name> 自訂目標的任何依賴項)。對於 downloadupdatepatch 步驟,這通常是安全的,因為它們通常不需要更新和建置依賴項。但是,為任何其他預定義步驟使用 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
)

目標可以與 foobar 專案本身一起定義,而不是呼叫 ExternalProject_Add_StepTargets()

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