cmake-packages(7)¶
簡介¶
套件為基於 CMake 的建置系統提供相依性資訊。套件透過 find_package()
指令尋找。使用 find_package()
的結果可能是一組 IMPORTED
目標,或是一組對應於建置相關資訊的變數。
使用套件¶
CMake 直接支援兩種形式的套件:設定檔套件 和 Find-module 套件。透過 FindPkgConfig
模組,也間接支援 pkg-config
套件。在所有情況下,find_package()
呼叫的基本形式是相同的
find_package(Qt4 4.7.0 REQUIRED) # CMake provides a Qt4 find-module
find_package(Qt5Core 5.1.0 REQUIRED) # Qt provides a Qt5 package config file.
find_package(LibXml2 REQUIRED) # Use pkg-config via the LibXml2 find-module
在已知上游提供套件設定檔,且僅應使用該設定檔的情況下,可以將 CONFIG
關鍵字傳遞給 find_package()
find_package(Qt5Core 5.1.0 CONFIG REQUIRED)
find_package(Qt5Gui 5.1.0 CONFIG)
同樣地,MODULE
關鍵字表示僅使用 find-module
find_package(Qt4 4.7.0 MODULE REQUIRED)
明確指定套件類型可以改善在找不到套件時向使用者顯示的錯誤訊息。
兩種套件類型也都支援指定套件的組件,可以在 REQUIRED
關鍵字之後
find_package(Qt5 5.1.0 CONFIG REQUIRED Widgets Xml Sql)
或作為單獨的 COMPONENTS
列表
find_package(Qt5 5.1.0 COMPONENTS Widgets Xml Sql)
或作為單獨的 OPTIONAL_COMPONENTS
列表
find_package(Qt5 5.1.0 COMPONENTS Widgets
OPTIONAL_COMPONENTS Xml Sql
)
COMPONENTS
和 OPTIONAL_COMPONENTS
的處理方式由套件定義。
透過將 CMAKE_DISABLE_FIND_PACKAGE_<PackageName>
變數設定為 TRUE
,將不會搜尋 <PackageName>
套件,且永遠為 NOTFOUND
。同樣地,將 CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>
設定為 TRUE
將使套件成為 REQUIRED。
設定檔套件¶
設定檔套件是由上游提供,供下游使用的一組檔案。如 find_package()
文件說明中所述,CMake 在許多位置搜尋套件設定檔。對於 CMake 使用者來說,告訴 cmake(1)
在非標準前綴中搜尋套件最簡單的方法是設定 CMAKE_PREFIX_PATH
快取變數。
設定檔套件由上游供應商作為開發套件的一部分提供,也就是說,它們與標頭檔和任何其他用於協助下游使用套件的檔案放在一起。
使用設定檔套件時,也會自動設定一組提供套件狀態資訊的變數。<PackageName>_FOUND
變數會根據是否找到套件設定為 true 或 false。<PackageName>_DIR
快取變數設定為套件設定檔的位置。
Find-module 套件¶
Find-module 是一個檔案,其中包含一組用於尋找相依性所需部分的規則,主要是標頭檔和程式庫。通常,當上游不是使用 CMake 建置,或是不夠 CMake-aware 以提供套件設定檔時,才需要 find-module。與套件設定檔不同,它不是隨上游一起發布,而是由下游使用,透過猜測檔案位置和平台特定的提示來尋找檔案。
與上游提供的套件設定檔的情況不同,沒有單一參考點可以識別套件是否已找到,因此 <PackageName>_FOUND
變數不會由 find_package()
指令自動設定。但是,仍然可以期望按照慣例設定它,並且應該由 Find-module 的作者設定。同樣地,沒有 <PackageName>_DIR
變數,但是每個產出物(例如程式庫位置和標頭檔位置)都提供單獨的快取變數。
請參閱 cmake-developer(7)
文件說明,以取得有關建立 Find-module 檔案的更多資訊。
套件佈局¶
設定檔套件包含一個 套件設定檔,以及可選的 套件版本檔,它們與專案發行版一起提供。
套件設定檔¶
考慮一個專案 Foo
,它安裝了以下檔案
<prefix>/include/foo-1.2/foo.h
<prefix>/lib/foo-1.2/libfoo.a
它也可能提供 CMake 套件設定檔
<prefix>/lib/cmake/foo-1.2/FooConfig.cmake
其內容定義了 IMPORTED
目標,或定義變數,例如
# ...
# (compute PREFIX relative to file location)
# ...
set(Foo_INCLUDE_DIRS ${PREFIX}/include/foo-1.2)
set(Foo_LIBRARIES ${PREFIX}/lib/foo-1.2/libfoo.a)
如果另一個專案想要使用 Foo
,它只需要找到 FooConfig.cmake
檔案並載入它,即可取得它所需的所有關於套件內容位置的資訊。由於套件設定檔是由套件安裝提供的,因此它已經知道所有檔案位置。
可以使用 find_package()
指令來搜尋套件設定檔。此指令會建立一組安裝前綴,並在每個前綴下的多個位置進行搜尋。給定名稱 Foo
,它會尋找名為 FooConfig.cmake
或 foo-config.cmake
的檔案。完整的位置集合在 find_package()
指令文件中指定。其中一個搜尋位置是
<prefix>/lib/cmake/Foo*/
其中 Foo*
是不區分大小寫的 globbing 表達式。在我們的範例中,globbing 表達式將匹配 <prefix>/lib/cmake/foo-1.2
,並且將找到套件設定檔。
一旦找到,套件設定檔會立即載入。它與套件版本檔一起,包含專案使用套件所需的所有資訊。
套件版本檔¶
當 find_package()
指令找到候選套件設定檔時,它會在旁邊尋找版本檔。載入版本檔以測試套件版本是否與請求的版本可接受地匹配。如果版本檔聲稱相容,則接受設定檔。否則,將忽略它。
套件版本檔的名稱必須與套件設定檔的名稱匹配,但在 .cmake
副檔名之前,名稱後附加 -version
或 Version
。例如,檔案
<prefix>/lib/cmake/foo-1.3/foo-config.cmake
<prefix>/lib/cmake/foo-1.3/foo-config-version.cmake
和
<prefix>/lib/cmake/bar-4.2/BarConfig.cmake
<prefix>/lib/cmake/bar-4.2/BarConfigVersion.cmake
各自是套件設定檔和對應套件版本檔的配對。
當 find_package()
指令載入版本檔時,它首先設定以下變數
PACKAGE_FIND_NAME
<PackageName>
PACKAGE_FIND_VERSION
完整請求的版本字串
PACKAGE_FIND_VERSION_MAJOR
如果請求,則為主要版本,否則為 0
PACKAGE_FIND_VERSION_MINOR
如果請求,則為次要版本,否則為 0
PACKAGE_FIND_VERSION_PATCH
如果請求,則為修補程式版本,否則為 0
PACKAGE_FIND_VERSION_TWEAK
如果請求,則為調整版本,否則為 0
PACKAGE_FIND_VERSION_COUNT
版本組件的數量,0 到 4
版本檔必須使用這些變數來檢查它是否與請求的版本相容或完全匹配,並使用結果設定以下變數
PACKAGE_VERSION
完整提供的版本字串
PACKAGE_VERSION_EXACT
如果版本完全匹配,則為 True
PACKAGE_VERSION_COMPATIBLE
如果版本相容,則為 True
PACKAGE_VERSION_UNSUITABLE
如果作為任何版本都不合適,則為 True
版本檔在巢狀作用域中載入,因此它們可以自由設定它們希望作為其計算一部分的任何變數。find_package
指令在版本檔完成並檢查輸出變數後,會清除作用域。當版本檔聲稱與請求的版本可接受地匹配時,find_package
指令會設定以下變數供專案使用
<PackageName>_VERSION
完整提供的版本字串
<PackageName>_VERSION_MAJOR
如果提供,則為主要版本,否則為 0
<PackageName>_VERSION_MINOR
如果提供,則為次要版本,否則為 0
<PackageName>_VERSION_PATCH
如果提供,則為修補程式版本,否則為 0
<PackageName>_VERSION_TWEAK
如果提供,則為調整版本,否則為 0
<PackageName>_VERSION_COUNT
版本組件的數量,0 到 4
這些變數報告實際找到的套件版本。它們名稱的 <PackageName>
部分與給定 find_package()
指令的參數匹配。
建立套件¶
通常,上游依賴於 CMake 本身,並且可以使用一些 CMake 功能來建立套件檔案。考慮一個上游,它提供單一共享程式庫
project(UpstreamLib)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
set(Upstream_VERSION 3.4.1)
include(GenerateExportHeader)
add_library(ClimbingStats SHARED climbingstats.cpp)
generate_export_header(ClimbingStats)
set_property(TARGET ClimbingStats PROPERTY VERSION ${Upstream_VERSION})
set_property(TARGET ClimbingStats PROPERTY SOVERSION 3)
set_property(TARGET ClimbingStats PROPERTY
INTERFACE_ClimbingStats_MAJOR_VERSION 3)
set_property(TARGET ClimbingStats APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING ClimbingStats_MAJOR_VERSION
)
install(TARGETS ClimbingStats EXPORT ClimbingStatsTargets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include
)
install(
FILES
climbingstats.h
"${CMAKE_CURRENT_BINARY_DIR}/climbingstats_export.h"
DESTINATION
include
COMPONENT
Devel
)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfigVersion.cmake"
VERSION ${Upstream_VERSION}
COMPATIBILITY AnyNewerVersion
)
export(EXPORT ClimbingStatsTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsTargets.cmake"
NAMESPACE Upstream::
)
configure_file(cmake/ClimbingStatsConfig.cmake
"${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfig.cmake"
COPYONLY
)
set(ConfigPackageLocation lib/cmake/ClimbingStats)
install(EXPORT ClimbingStatsTargets
FILE
ClimbingStatsTargets.cmake
NAMESPACE
Upstream::
DESTINATION
${ConfigPackageLocation}
)
install(
FILES
cmake/ClimbingStatsConfig.cmake
"${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfigVersion.cmake"
DESTINATION
${ConfigPackageLocation}
COMPONENT
Devel
)
CMakePackageConfigHelpers
模組提供了一個巨集,用於建立簡單的 ConfigVersion.cmake
檔案。此檔案設定套件的版本。當呼叫 find_package()
時,CMake 會讀取此檔案,以確定與請求版本的相容性,並設定一些版本特定的變數,例如 <PackageName>_VERSION
、<PackageName>_VERSION_MAJOR
、<PackageName>_VERSION_MINOR
等。install(EXPORT)
指令用於匯出 ClimbingStatsTargets
匯出集中 (export-set) 的目標,該匯出集先前由 install(TARGETS)
指令定義。此指令產生 ClimbingStatsTargets.cmake
檔案,以包含 IMPORTED
目標,適用於下游使用,並安排將其安裝到 lib/cmake/ClimbingStats
。產生的 ClimbingStatsConfigVersion.cmake
和 cmake/ClimbingStatsConfig.cmake
安裝在相同的位置,完成套件。
產生的 IMPORTED
目標設定了適當的屬性,以定義其 使用需求,例如 INTERFACE_INCLUDE_DIRECTORIES
、INTERFACE_COMPILE_DEFINITIONS
和其他相關的內建 INTERFACE_
屬性。在 COMPATIBLE_INTERFACE_STRING
和其他 相容介面屬性 中列出的使用者定義屬性的 INTERFACE
變體也會傳播到產生的 IMPORTED
目標。在上述情況下,ClimbingStats_MAJOR_VERSION
定義為一個字串,該字串在任何依賴者的相依性之間必須是相容的。透過在此版本和下一個版本的 ClimbingStats
中設定此自訂定義的使用者屬性,如果嘗試將版本 3 與版本 4 一起使用,cmake(1)
將發出診斷訊息。如果套件的不同主要版本設計為不相容,則套件可以選擇採用這種模式。
在匯出目標以進行安裝時,指定帶有雙冒號的 NAMESPACE
。雙冒號的慣例給予 CMake 提示,當下游使用 target_link_libraries()
指令時,該名稱是 IMPORTED
目標。這樣,如果尚未找到提供它的套件,CMake 可以發出診斷訊息。
在這種情況下,當使用 install(TARGETS)
時,指定了 INCLUDES DESTINATION
。這會導致 IMPORTED
目標的 INTERFACE_INCLUDE_DIRECTORIES
填入 CMAKE_INSTALL_PREFIX
中的 include
目錄。當下游使用 IMPORTED
目標時,它會自動使用該屬性中的條目。
建立套件設定檔¶
在這種情況下,ClimbingStatsConfig.cmake
檔案可以像這樣簡單
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
因為這允許下游使用 IMPORTED
目標。如果 ClimbingStats
套件應提供任何巨集,則它們應位於單獨的檔案中,該檔案安裝在與 ClimbingStatsConfig.cmake
檔案相同的位置,並從那裡包含。
這也可以擴展到涵蓋相依性
# ...
add_library(ClimbingStats SHARED climbingstats.cpp)
generate_export_header(ClimbingStats)
find_package(Stats 2.6.4 REQUIRED)
target_link_libraries(ClimbingStats PUBLIC Stats::Types)
由於 Stats::Types
目標是 ClimbingStats
的 PUBLIC
相依性,因此下游也必須找到 Stats
套件並連結到 Stats::Types
程式庫。為了確保這一點,應在 ClimbingStatsConfig.cmake
檔案中找到 Stats
套件。CMakeFindDependencyMacro
中的 find_dependency
巨集透過傳播套件是否為 REQUIRED
或 QUIET
等來提供幫助。套件的所有 REQUIRED
相依性都應在 Config.cmake
檔案中找到
include(CMakeFindDependencyMacro)
find_dependency(Stats 2.6.4)
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsMacros.cmake")
find_dependency
巨集也會在找不到相依性時將 ClimbingStats_FOUND
設定為 False
,並提供診斷訊息,指出沒有 Stats
套件就無法使用 ClimbingStats
套件。
如果在下游使用 find_package()
時指定了 COMPONENTS
,它們會列在 <PackageName>_FIND_COMPONENTS
變數中。如果特定組件是非可選的,則 <PackageName>_FIND_REQUIRED_<comp>
將為 true。這可以使用套件設定檔中的邏輯進行測試
include(CMakeFindDependencyMacro)
find_dependency(Stats 2.6.4)
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsMacros.cmake")
set(_ClimbingStats_supported_components Plot Table)
foreach(_comp ${ClimbingStats_FIND_COMPONENTS})
if (NOT ";${_ClimbingStats_supported_components};" MATCHES ";${_comp};")
set(ClimbingStats_FOUND False)
set(ClimbingStats_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStats${_comp}Targets.cmake")
endforeach()
在這裡,ClimbingStats_NOT_FOUND_MESSAGE
設定為診斷訊息,指出由於指定了無效的組件而找不到套件。對於 _FOUND
變數設定為 False
的任何情況,都可以設定此訊息變數,並將其顯示給使用者。
為建置樹狀結構建立套件設定檔¶
export(EXPORT)
指令建立一個 IMPORTED
目標定義檔案,該檔案特定於建置樹狀結構,且不可重定位。這同樣可以與適當的套件設定檔和套件版本檔一起使用,以定義用於建置樹狀結構的套件,該套件可以在不安裝的情況下使用。建置樹狀結構的使用者可以簡單地確保 CMAKE_PREFIX_PATH
包含建置目錄,或在快取中將 ClimbingStats_DIR
設定為 <build_dir>/ClimbingStats
。
建立可重定位的套件¶
可重定位的套件不得參考套件建置所在機器上檔案的絕對路徑,這些路徑在可能安裝套件的機器上將不存在。
由 install(EXPORT)
建立的套件設計為可重定位,使用相對於套件本身位置的路徑。當為 EXPORT
定義目標的介面時,請記住,包含目錄應指定為相對於 CMAKE_INSTALL_PREFIX
的相對路徑
target_include_directories(tgt INTERFACE
# Wrong, not relocatable:
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/TgtName>
)
target_include_directories(tgt INTERFACE
# Ok, relocatable:
$<INSTALL_INTERFACE:include/TgtName>
)
$<INSTALL_PREFIX>
產生器 表達式
可以用作安裝前綴的佔位符,而不會導致不可重定位的套件。如果使用複雜的產生器表達式,則這是必要的
target_include_directories(tgt INTERFACE
# Ok, relocatable:
$<INSTALL_INTERFACE:$<$<CONFIG:Debug>:$<INSTALL_PREFIX>/include/TgtName>>
)
這也適用於參考外部相依性的路徑。不建議使用與相依性相關的路徑來填入可能包含路徑的任何屬性,例如 INTERFACE_INCLUDE_DIRECTORIES
和 INTERFACE_LINK_LIBRARIES
。例如,此程式碼可能不適用於可重定位的套件
target_link_libraries(ClimbingStats INTERFACE
${Foo_LIBRARIES} ${Bar_LIBRARIES}
)
target_include_directories(ClimbingStats INTERFACE
"$<INSTALL_INTERFACE:${Foo_INCLUDE_DIRS};${Bar_INCLUDE_DIRS}>"
)
引用的變數可能包含程式庫和包含目錄的絕對路徑,如同在建立套件的機器上找到的一樣。這會建立一個具有硬編碼相依性路徑的套件,並且不適合重定位。
理想情況下,此類相依性應透過它們自己的 IMPORTED 目標 使用,這些目標具有自己的 IMPORTED_LOCATION
和使用需求屬性,例如 INTERFACE_INCLUDE_DIRECTORIES
已適當地填入。然後,這些匯入的目標可以與 ClimbingStats
的 target_link_libraries()
指令一起使用
target_link_libraries(ClimbingStats INTERFACE Foo::Foo Bar::Bar)
透過這種方法,套件僅透過 IMPORTED 目標 的名稱參考其外部相依性。當使用者使用已安裝的套件時,使用者將執行適當的 find_package()
指令(透過上面描述的 find_dependency
巨集)來尋找相依性,並使用其自身機器上的適當路徑填入匯入的目標。
不幸的是,許多隨 CMake 提供的 modules
尚未提供 IMPORTED 目標,因為它們的開發早於這種方法。這可能會隨著時間的推移逐步改進。使用此類模組建立可重定位套件的解決方案包括
在建置套件時,將每個
Foo_LIBRARY
快取條目指定為僅程式庫名稱,例如-DFoo_LIBRARY=foo
。這會告訴對應的 find module 使用foo
填入Foo_LIBRARIES
,以要求連結器搜尋程式庫,而不是硬編碼路徑。或者,在安裝套件內容之後,但在建立用於重新發行的套件安裝二進位檔之前,手動將絕對路徑替換為佔位符,以便在安裝套件時由安裝工具替換。
套件註冊表¶
CMake 提供了兩個中心位置來註冊已在系統上任何位置建置或安裝的套件
註冊表特別有用,可以幫助專案在非標準安裝位置或直接在其自己的建置樹狀結構中尋找套件。專案可以填入使用者或系統註冊表(使用自己的方法,請參閱下文)以參考其位置。在任一情況下,套件都應在註冊的位置儲存 套件設定檔 (<PackageName>Config.cmake
) 和可選的 套件版本檔 (<PackageName>ConfigVersion.cmake
)。
find_package()
指令搜尋兩個套件註冊表,作為其文件中指定的兩個搜尋步驟。如果它具有足夠的權限,它也會移除引用不存在或不包含匹配套件設定檔的目錄的過時套件註冊表條目。
使用者套件註冊表¶
使用者套件註冊表儲存在每個使用者的位置。export(PACKAGE)
指令可用於在使用者套件註冊表中註冊專案建置樹狀結構。CMake 目前沒有提供介面將安裝樹狀結構新增到使用者套件註冊表。如果需要,必須手動教導安裝程式註冊其套件。
在 Windows 上,使用者套件註冊表儲存在 Windows 註冊表的 HKEY_CURRENT_USER
金鑰下。
在註冊表金鑰下可能會出現 <PackageName>
HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\<PackageName>
作為 REG_SZ
值,具有任意名稱,指定包含套件設定檔的目錄。
在 UNIX 平台上,使用者套件註冊表儲存在使用者主目錄下的 ~/.cmake/packages
。在目錄下可能會出現 <PackageName>
~/.cmake/packages/<PackageName>
作為一個檔案,具有任意名稱,其內容指定包含套件設定檔的目錄。
系統套件註冊表¶
系統套件註冊表儲存在系統範圍的位置。CMake 目前沒有提供介面來新增到系統套件註冊表。如果需要,必須手動教導安裝程式註冊其套件。
在 Windows 上,系統套件登錄檔儲存在 Windows 登錄檔的 HKEY_LOCAL_MACHINE
機碼下。 <PackageName>
可能會出現在登錄檔機碼下
HKEY_LOCAL_MACHINE\Software\Kitware\CMake\Packages\<PackageName>
作為 REG_SZ
值,具有任意名稱,指定包含套件設定檔的目錄。
在非 Windows 平台上,沒有系統套件登錄檔。
停用套件登錄檔¶
在某些情況下,使用套件登錄檔可能不是理想的做法。CMake 允許使用以下變數來停用它們
當
export(PACKAGE)
命令在CMP0090
設定為NEW
時,不會填充使用者套件登錄檔,除非CMAKE_EXPORT_PACKAGE_REGISTRY
變數明確啟用它。當CMP0090
*未* 設定為NEW
時,export(PACKAGE)
會填充使用者套件登錄檔,除非CMAKE_EXPORT_NO_PACKAGE_REGISTRY
變數明確停用它。當
CMAKE_FIND_USE_PACKAGE_REGISTRY
設定為FALSE
時,會停用所有find_package()
呼叫中的使用者套件登錄檔。已棄用的
CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY
設定為TRUE
時,會停用所有find_package()
呼叫中的使用者套件登錄檔。當已設定CMAKE_FIND_USE_PACKAGE_REGISTRY
時,此變數會被忽略。CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
會停用所有find_package()
呼叫中的系統套件登錄檔。
套件登錄檔範例¶
一個簡單的套件登錄檔條目命名慣例是使用內容雜湊。它們是確定性的且不太可能發生碰撞 (export(PACKAGE)
使用了這種方法)。引用特定目錄的條目名稱只是目錄路徑本身的內容雜湊。
如果專案安排了套件登錄檔條目的存在,例如
> reg query HKCU\Software\Kitware\CMake\Packages\MyPackage
HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\MyPackage
45e7d55f13b87179bb12f907c8de6fc4 REG_SZ c:/Users/Me/Work/lib/cmake/MyPackage
7b4a9844f681c80ce93190d4e3185db9 REG_SZ c:/Users/Me/Work/MyPackage-build
或
$ cat ~/.cmake/packages/MyPackage/7d1fb77e07ce59a81bed093bbee945bd
/home/me/work/lib/cmake/MyPackage
$ cat ~/.cmake/packages/MyPackage/f92c1db873a1937f3100706657c63e07
/home/me/work/MyPackage-build
那麼 CMakeLists.txt
程式碼
find_package(MyPackage)
將會在註冊的位置搜尋套件組態檔 (MyPackageConfig.cmake
)。單一套件的套件登錄檔條目之間的搜尋順序是未指定的,並且條目名稱 (在此範例中為雜湊) 沒有意義。註冊的位置可能包含套件版本檔案 (MyPackageConfigVersion.cmake
),以告知 find_package()
特定位置是否適用於請求的版本。
套件登錄檔所有權¶
套件登錄檔條目由它們引用的專案安裝個別擁有。套件安裝程式負責新增自己的條目,而對應的解除安裝程式負責移除它。
export(PACKAGE)
命令會使用專案建置樹的位置填充使用者套件登錄檔。建置樹往往會被開發人員刪除,並且沒有可以觸發移除其條目的「解除安裝」事件。為了保持登錄檔的整潔,find_package()
命令會在遇到過時的條目時自動移除它們 (如果它具有足夠的權限)。一旦調用 export(PACKAGE)
,CMake 不提供介面來移除引用現有建置樹的條目。但是,如果專案從建置樹中移除其套件組態檔,則引用該位置的條目將被視為過時。