add_library

使用指定的原始碼檔案將函式庫新增至專案。

普通函式庫

add_library(<名稱> [<類型>] [EXCLUDE_FROM_ALL] <原始碼>...)

新增一個名為 <名稱> 的函式庫目標,該目標將從命令調用中列出的原始碼檔案建置。

可選的 <類型> 指定要建立的函式庫類型

STATIC

物件檔案的封存檔,用於連結其他目標時使用。

SHARED

動態函式庫,可由其他目標連結並在執行階段載入。

MODULE

外掛程式,可能無法由其他目標連結,但可以在執行階段使用類似 dlopen 的功能動態載入。

如果未給定 <類型>,則預設值為 STATICSHARED,具體取決於 BUILD_SHARED_LIBS 變數的值。

選項為

EXCLUDE_FROM_ALL

自動設定 EXCLUDE_FROM_ALL 目標屬性。 有關詳細資訊,請參閱該目標屬性的文件。

<名稱> 對應於邏輯目標名稱,並且在專案中必須是全域唯一的。 建立的函式庫的實際檔案名稱是根據原生平台的慣例建立的(例如 lib<名稱>.a<名稱>.lib)。

在 3.1 版本中新增:add_library 的原始碼引數可以使用具有 $<...> 語法的「產生器運算式」。 有關可用的運算式,請參閱 cmake-generator-expressions(7) 文件。

在 3.11 版本中新增:如果稍後使用 target_sources() 新增原始碼檔案,則可以省略它們。

對於 SHAREDMODULE 函式庫,會自動將 POSITION_INDEPENDENT_CODE 目標屬性設定為 ONSHARED 函式庫可以使用 FRAMEWORK 目標屬性標記,以建立 macOS Framework。

在 3.8 版本中新增:可以使用 FRAMEWORK 目標屬性標記 STATIC 函式庫,以建立靜態 Framework。

如果函式庫未匯出任何符號,則不得將其宣告為 SHARED 函式庫。 例如,Windows 資源 DLL 或未匯出任何非受管理符號的受管理 C++/CLI DLL 將需要為 MODULE 函式庫。 這是因為 CMake 期望 SHARED 函式庫在 Windows 上始終具有關聯的匯入函式庫。

依預設,函式庫檔案將在命令調用所在來源樹目錄對應的建置樹目錄中建立。 請參閱 ARCHIVE_OUTPUT_DIRECTORYLIBRARY_OUTPUT_DIRECTORYRUNTIME_OUTPUT_DIRECTORY 目標屬性的文件,以變更此位置。 請參閱 OUTPUT_NAME 目標屬性的文件,以變更最終檔案名稱的 <名稱> 部分。

請參閱 cmake-buildsystem(7) 文件,以取得有關定義建置系統屬性的更多資訊。

另請參閱 HEADER_FILE_ONLY,以瞭解如果某些來源經過預處理,並且您希望從 IDE 中可以存取原始來源時該怎麼辦。

在 3.30 版本中變更:在不支援共用函式庫的平台上,add_library 現在在建立 SHARED 函式庫的呼叫中會失敗,而不是像以前一樣自動將它們轉換為 STATIC 函式庫。 請參閱原則 CMP0164

物件函式庫

add_library(<名稱> OBJECT <原始碼>...)

新增 物件函式庫,以編譯原始碼檔案,而無需將其物件檔案封存或連結到函式庫中。

add_libraryadd_executable() 建立的其他目標可以使用 $<TARGET_OBJECTS:objlib> 形式的運算式作為來源來參照物件,其中 objlib 是物件函式庫名稱。 例如

add_library(... $<TARGET_OBJECTS:objlib> ...)
add_executable(... $<TARGET_OBJECTS:objlib> ...)

將在函式庫和可執行檔中包含 objlib 的物件檔案,以及從它們自己的來源編譯的檔案。 物件函式庫可能僅包含編譯的來源、標頭檔和其他不會影響正常函式庫連結的檔案(例如 .txt)。 它們可能包含產生此類來源的自訂命令,但不包含 PRE_BUILDPRE_LINKPOST_BUILD 命令。 某些原生建置系統(例如 Xcode)可能不喜歡只有物件檔案的目標,因此請考慮將至少一個真實原始碼檔案新增至任何參考 $<TARGET_OBJECTS:objlib> 的目標。

在 3.12 版本中新增:可以使用 target_link_libraries() 連結物件函式庫。

介面函式庫

add_library(<名稱> INTERFACE)

新增 介面函式庫 目標,該目標可以指定依賴項目的使用要求,但不編譯來源,並且不會在磁碟上產生函式庫成品。

沒有原始碼檔案的介面函式庫不會作為目標包含在產生的建置系統中。 但是,可以在其上設定屬性,並且可以安裝和匯出。 通常,使用以下命令在介面目標上填入 INTERFACE_* 屬性

然後它會像其他目標一樣,作為 target_link_libraries() 的參數使用。

新增於 3.15 版本:介面程式庫可以擁有 PUBLIC_HEADERPRIVATE_HEADER 屬性。 這些屬性指定的標頭可以使用 install(TARGETS) 命令安裝。

add_library(<name> INTERFACE [EXCLUDE_FROM_ALL] <sources>...)

新增於 3.19 版本。

新增一個具有原始檔的 介面程式庫 目標 (除了 上述簽名 所記錄的使用需求和屬性之外)。 原始檔可以直接在 add_library 呼叫中列出,也可以稍後通過使用 PRIVATEPUBLIC 關鍵字的 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> 必須是以下其中之一

STATICSHAREDMODULEUNKNOWN

引用位於專案外部的程式庫檔案。 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 目標不能被安裝或匯出。

另請參閱