add_library¶
使用指定的原始檔將函式庫新增至專案。
一般函式庫¶
- add_library(<name> [<type>] [EXCLUDE_FROM_ALL] <sources>...)¶
新增一個名為
<name>
的函式庫目標,從命令調用中列出的原始檔建置。選用的
<type>
指定要建立的函式庫類型STATIC
靜態函式庫:物件檔的封存檔,用於連結其他目標時。
SHARED
共享函式庫:動態函式庫,可以被其他目標連結並在運行時載入。
MODULE
模組函式庫:外掛程式,可能無法被其他目標連結,但可以使用類似 dlopen 的功能在運行時動態載入。
如果未給定
<type>
,則預設值為STATIC
或SHARED
,具體取決於BUILD_SHARED_LIBS
變數的值。選項為
EXCLUDE_FROM_ALL
自動設定
EXCLUDE_FROM_ALL
目標屬性。 有關詳細資訊,請參閱該目標屬性的文件。
<name>
對應於邏輯目標名稱,並且在專案中必須是全域唯一的。 建置的函式庫的實際檔案名稱是根據原生平台的慣例建構的(例如 lib<name>.a
或 <name>.lib
)。
在 3.1 版本中新增: add_library
的來源引數可以使用「產生器運算式」,語法為 $<...>
。 有關可用的運算式,請參閱 cmake-generator-expressions(7)
手冊。
在 3.11 版本中新增: 如果稍後使用 target_sources()
新增來源檔案,則可以省略來源檔案。
對於 SHARED
和 MODULE
函式庫,POSITION_INDEPENDENT_CODE
目標屬性會自動設定為 ON
。 SHARED
函式庫可以使用 FRAMEWORK
目標屬性標記,以建立 macOS Framework。
在 3.8 版本中新增: STATIC
函式庫可以使用 FRAMEWORK
目標屬性標記,以建立靜態 Framework。
如果函式庫未匯出任何符號,則不得宣告為 SHARED
函式庫。 例如,Windows 資源 DLL 或未匯出任何非託管符號的託管 C++/CLI DLL 需要是 MODULE
函式庫。 這是因為 CMake 期望 SHARED
函式庫在 Windows 上始終具有關聯的匯入函式庫。
預設情況下,函式庫檔案將在建置樹狀目錄中建立,該目錄對應於調用命令的原始碼樹狀目錄。 請參閱 ARCHIVE_OUTPUT_DIRECTORY
、LIBRARY_OUTPUT_DIRECTORY
和 RUNTIME_OUTPUT_DIRECTORY
目標屬性的文件,以變更此位置。 請參閱 OUTPUT_NAME
目標屬性的文件,以變更最終檔案名稱的 <name>
部分。
有關定義建置系統屬性的更多資訊,請參閱 cmake-buildsystem(7)
手冊。
另請參閱 HEADER_FILE_ONLY
,以了解如果某些來源是預先處理的,並且您希望從 IDE 中存取原始來源,該怎麼做。
在 3.30 版本中變更: 在不支援共享函式庫的平台上,add_library
現在在建立 SHARED
函式庫的呼叫時會失敗,而不是像以前一樣自動將它們轉換為 STATIC
函式庫。 請參閱策略 CMP0164
。
物件函式庫¶
由 add_library
或 add_executable()
建立的其他目標可以使用 $<TARGET_OBJECTS:objlib>
形式的運算式作為來源來參照物件,其中 objlib
是物件函式庫名稱。 例如
add_library(... $<TARGET_OBJECTS:objlib> ...)
add_executable(... $<TARGET_OBJECTS:objlib> ...)
將 objlib 的物件檔包含在函式庫和可執行檔中,以及從其自身來源編譯的物件檔。 物件函式庫可能僅包含編譯的來源、標頭檔以及其他不會影響一般函式庫連結的檔案 (例如 .txt
)。 它們可能包含產生此類來源的自訂命令,但不包含 PRE_BUILD
、PRE_LINK
或 POST_BUILD
命令。 某些原生建置系統(例如 Xcode)可能不喜歡只有物件檔的目標,因此請考慮向任何參照 $<TARGET_OBJECTS:objlib>
的目標至少新增一個真實的原始檔。
在 3.12 版本中新增: 物件函式庫可以使用 target_link_libraries()
連結。
介面函式庫¶
- add_library(<name> INTERFACE)¶
新增一個 介面函式庫 目標,該目標可以指定相依項的使用需求,但不編譯來源,也不會在磁碟上產生函式庫成品。
沒有原始檔的介面函式庫不包含在產生的建置系統中作為目標。 但是,可以在其上設定屬性,並且可以安裝和匯出它。 通常,使用以下命令在介面目標上填入
INTERFACE_*
屬性然後像任何其他目標一樣,將其用作
target_link_libraries()
的引數。在 3.15 版本中新增: 介面函式庫可以具有
PUBLIC_HEADER
和PRIVATE_HEADER
屬性。 可以使用install(TARGETS)
命令安裝這些屬性指定的標頭。
- add_library(<name> INTERFACE [EXCLUDE_FROM_ALL] <sources>...)¶
在 3.19 版本中新增。
新增一個 介面函式庫 目標,其中包含原始檔(除了
上述簽章
文件記錄的使用需求和屬性之外)。 原始檔可以直接在add_library
呼叫中列出,也可以稍後透過使用PRIVATE
或PUBLIC
關鍵字的target_sources()
呼叫新增。如果介面函式庫具有原始檔(即設定了
SOURCES
目標屬性),或標頭集(即設定了HEADER_SETS
目標屬性),它將在產生的建置系統中顯示為建置目標,很像由add_custom_target()
命令定義的目標。 它不編譯任何來源,但確實包含由add_custom_command()
命令建立的自訂命令的建置規則。選項為
EXCLUDE_FROM_ALL
自動設定
EXCLUDE_FROM_ALL
目標屬性。 有關詳細資訊,請參閱該目標屬性的文件。
注意
在大多數命令簽章中,
INTERFACE
關鍵字出現的位置,其後列出的項目僅成為該目標的使用需求的一部分,而不是目標自身設定的一部分。 但是,在此add_library
的簽章中,INTERFACE
關鍵字僅指函式庫類型。 在add_library
呼叫中在其後列出的來源是介面函式庫的PRIVATE
,並且不會出現在其INTERFACE_SOURCES
目標屬性中。
匯入函式庫¶
- add_library(<name> <type> IMPORTED [GLOBAL])¶
新增一個名為
<name>
的 匯入函式庫目標。 目標名稱可以像專案中建置的任何目標一樣被參照,但預設情況下,它僅在建立它的目錄及其下方的目錄中可見。<type>
必須是以下之一STATIC
、SHARED
、MODULE
、UNKNOWN
參照專案外部的函式庫檔案。
IMPORTED_LOCATION
目標屬性(或其每個組態變體IMPORTED_LOCATION_<CONFIG>
)指定磁碟上主要函式庫檔案的位置對於大多數非 Windows 平台上的
SHARED
函式庫,主要函式庫檔案是連結器和動態載入器使用的.so
或.dylib
檔案。 如果參照的函式庫檔案具有SONAME
(或在 macOS 上,從@rpath/
開始具有LC_ID_DYLIB
),則應在IMPORTED_SONAME
目標屬性中設定該欄位的值。 如果參照的函式庫檔案沒有SONAME
,但平台支援它,則應設定IMPORTED_NO_SONAME
目標屬性。對於 Windows 上的
SHARED
函式庫,IMPORTED_IMPLIB
目標屬性(或其每個組態變體IMPORTED_IMPLIB_<CONFIG>
)指定磁碟上 DLL 匯入函式庫檔案(.lib
或.dll.a
)的位置,而IMPORTED_LOCATION
是.dll
運行時函式庫的位置(並且是選用的,但TARGET_RUNTIME_DLLS
產生器運算式需要它)。
其他使用需求可以在
INTERFACE_*
屬性中指定。UNKNOWN
函式庫類型通常僅在 尋找模組 的實作中使用。 它允許使用匯入函式庫的路徑(通常使用find_library()
命令找到),而無需知道它是哪種類型的函式庫。 這在 Windows 上特別有用,其中靜態函式庫和 DLL 的匯入函式庫都具有相同的檔案副檔名。OBJECT
參照專案外部的一組物件檔。
IMPORTED_OBJECTS
目標屬性(或其每個組態變體IMPORTED_OBJECTS_<CONFIG>
)指定磁碟上物件檔的位置。 其他使用需求可以在INTERFACE_*
屬性中指定。INTERFACE
不參照磁碟上的任何函式庫或物件檔,但可以在
INTERFACE_*
屬性中指定使用需求。
選項為
GLOBAL
使目標名稱全域可見。
不會產生建置匯入目標的規則,並且 IMPORTED
目標屬性為 True
。 匯入函式庫對於從 target_link_libraries()
等命令中方便地參照非常有用。
有關匯入函式庫的詳細資訊,請參閱以 IMPORTED_
和 INTERFACE_
開頭的屬性的文件。 有關更多資訊,請參閱此類屬性的文件。
別名函式庫¶
- add_library(<name> ALIAS <target>)¶
建立一個 別名目標,以便可以使用
<name>
在後續命令中參照<target>
。<name>
不會作為 make 目標出現在產生的建置系統中。<target>
不得為ALIAS
。
在 3.11 版本中新增: ALIAS
可以以 GLOBAL
匯入目標 為目標
在 3.18 版本中新增: ALIAS
可以以非 GLOBAL
匯入目標為目標。 此類別名限定於建立它的目錄及其下方的目錄。 ALIAS_GLOBAL
目標屬性可用於檢查別名是否為全域別名。
ALIAS
目標可以用作可連結的目標和從中讀取屬性的目標。 它們也可以使用常規 if(TARGET)
子命令測試是否存在。 <name>
不得用於修改 <target>
的屬性,也就是說,它不得用作 set_property()
、set_target_properties()
、target_link_libraries()
等的運算元。 ALIAS
目標不得安裝或匯出。