add_library¶
使用指定的原始碼檔案將函式庫新增至專案。
普通函式庫¶
- add_library(<名稱> [<類型>] [EXCLUDE_FROM_ALL] <原始碼>...)¶
新增一個名為
<名稱>
的函式庫目標,該目標將從命令調用中列出的原始碼檔案建置。可選的
<類型>
指定要建立的函式庫類型STATIC
物件檔案的封存檔,用於連結其他目標時使用。
SHARED
動態函式庫,可由其他目標連結並在執行階段載入。
MODULE
外掛程式,可能無法由其他目標連結,但可以在執行階段使用類似 dlopen 的功能動態載入。
如果未給定
<類型>
,則預設值為STATIC
或SHARED
,具體取決於BUILD_SHARED_LIBS
變數的值。選項為
EXCLUDE_FROM_ALL
自動設定
EXCLUDE_FROM_ALL
目標屬性。 有關詳細資訊,請參閱該目標屬性的文件。
<名稱>
對應於邏輯目標名稱,並且在專案中必須是全域唯一的。 建立的函式庫的實際檔案名稱是根據原生平台的慣例建立的(例如 lib<名稱>.a
或 <名稱>.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 版本中新增:可以使用 FRAMEWORK
目標屬性標記 STATIC
函式庫,以建立靜態 Framework。
如果函式庫未匯出任何符號,則不得將其宣告為 SHARED
函式庫。 例如,Windows 資源 DLL 或未匯出任何非受管理符號的受管理 C++/CLI DLL 將需要為 MODULE
函式庫。 這是因為 CMake 期望 SHARED
函式庫在 Windows 上始終具有關聯的匯入函式庫。
依預設,函式庫檔案將在命令調用所在來源樹目錄對應的建置樹目錄中建立。 請參閱 ARCHIVE_OUTPUT_DIRECTORY
、LIBRARY_OUTPUT_DIRECTORY
和 RUNTIME_OUTPUT_DIRECTORY
目標屬性的文件,以變更此位置。 請參閱 OUTPUT_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(<名稱> 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
目標不能被安裝或匯出。