CMake-scope-PRIVATE-PUBLIC-INTERFACE

這三個屬性在不同命令中有不同的含義。
我把它總結爲一個表格,如果看不太明白,再看下方的翻譯。

在這裏插入圖片描述

下面的內容均來自Cmake英文官方手冊。主要是翻譯了三處CMake手冊的介紹。

對於target_link_libraries()我認爲這三個變量是用來控制庫傳遞過程中,庫所包含的依賴是否也能被連接到這個庫的其他目標所包含。同時,這個手冊建議,根據庫的cpp以及庫的h(注意不是工程)是否用到依賴,來設置這個依賴的scope範圍。

對於target_include_directories()這三個關鍵詞設置了這個目錄A會被包含到目標B的哪個屬性,同時,在使用target_link_libraries()將目標B鏈接給目標C的時候,B所包含的目錄也會因爲關鍵字的設置而決定是否能被C包含。

英文原文:

https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-specification-and-usage-requirements
英文翻譯:

傳遞用法要求
目標的使用要求可以傳遞給依賴對象。 target_link_libraries()命令具有PRIVATE,INTERFACE和PUBLIC關鍵字來控制傳播使用要求。

add_library(archive archive.cpp)
target_compile_definitions(archive INTERFACE USING_ARCHIVE_LIB)

add_library(serialization serialization.cpp)
target_compile_definitions(serialization INTERFACE USING_SERIALIZATION_LIB)

add_library(archiveExtras extras.cpp)
target_link_libraries(archiveExtras PUBLIC archive)
target_link_libraries(archiveExtras PRIVATE serialization)
# archiveExtras is compiled with -DUSING_ARCHIVE_LIB
# and -DUSING_SERIALIZATION_LIB

add_executable(consumer consumer.cpp)
# consumer is compiled with -DUSING_ARCHIVE_LIB
target_link_libraries(consumer archiveExtras)

因爲archive庫是目標archiveExtras的PUBLIC依賴項,所以它(archive)的使用要求也傳播到了consumer。因爲serializationarchiveExtrasPRIVATE依賴項,所以它(serialization)的使用要求不會傳播到consumer
通常,如果只有庫的實現而不是頭文件使用了依賴項(生成庫的cpp文件中使用依賴項,但是庫所包含的頭文件沒有包含依賴項),則應在使用target_link_libraries()時用PRIVATE關鍵字指定依賴項。如果在庫的頭文件中還使用了依賴項(例如,用於類繼承),則應將其指定爲PUBLIC依賴項。庫的實現不使用依賴項,而是僅由其頭文件使用的依賴項應指定爲INTERFACE依賴項。

可以通過多次使用每個關鍵字來調用target_link_libraries()命令:

target_link_libraries(archiveExtras
  PUBLIC archive
  PRIVATE serialization
)

英文原文:
https://cmake.org/cmake/help/latest/command/target_include_directories.html
英文翻譯:
target_include_directories
將包含目錄添加到目標。

target_include_directories(<target> [SYSTEM] [BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

在編譯給定目標時,要指定包含目錄。必須由諸如add_executable()或add_library()之類的命令創建,並且不能爲ALIAS(別名)目標。

如果指定了BEFORE,則內容將被添加到該屬性的前面,而不是被附加。

INTERFACE,PUBLIC和PRIVATE關鍵字來指定以下參數的範圍。 PRIVATE和PUBLIC項目將放到的INCLUDE_DIRECTORIES變量裏。 PUBLIC和INTERFACE項目將放到的INTERFACE_INCLUDE_DIRECTORIES變量裏。 (導入的目標僅支持INTERFACE項。)以下參數指定包含目錄。

指定的包含目錄可以是絕對路徑或相對路徑。對相同的重複調用將按調用順序追加項目。如果指定了SYSTEM,則會在某些平臺上告知編譯器目錄爲系統包含目錄(對此設置進行信號化可能會產生效果,例如編譯器跳過警告,或者在依賴性計算中不考慮這些固定安裝的系統文件-請參閱編譯器文檔)。如果將SYSTEM與PUBLIC或INTERFACE一起使用,則INTERFACE_SYSTEM_INCLUDE_DIRECTORIES目標屬性將使用指定的目錄填充。

英文原文:
https://cmake.org/cmake/help/latest/command/target_link_libraries.html?highlight=target_link_libraries#libraries-for-both-a-target-and-its-dependents
英文翻譯:

target_link_libraries(<target> <item>...)

默認情況下,使用這個函數(signature)的庫依賴關係是可傳遞的(我認爲默認是PUBLIC關鍵詞)。 當這個目標(假設爲庫A,我認爲不是庫無法被鏈接,所以如果這是一個單純的可執行文件,那麼這個scope關鍵詞就沒有意義)被鏈接到另一個目標(目標B)時,鏈接到這個目標(庫A)的庫也可以被另一個目標(目標B)鏈接上。

這個可傳遞的“鏈接接口”存儲在INTERFACE_LINK_LIBRARIES目標屬性中,可以直接設置該屬性。 當CMP0022未設置爲NEW時,將建立傳遞鏈接,但可被LINK_INTERFACE_LIBRARIES屬性覆蓋。 調用此命令的其他簽名可能會設置該屬性,從而使由該簽名專有鏈接的任何庫都變爲私有。

歡迎關注我的公衆號一起交流討論:
公衆號名稱:三豐雜貨鋪
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章