簡體   English   中英

CMake 目標編譯選項泄漏到其他目標

[英]CMake target compile option leaking to other targets

我正在使用 CMake,我對一個也使用 CMake 的項目有一個外部依賴項。看起來目標編譯選項正在從該依賴項的目標泄漏到我的目標。 該依賴項設置了高警告級別,因此我的項目代碼也收到了一些警告。

我知道正確的做法可能是接受它並實際修復警告,但我想:

  1. 首先了解為什么會發生這種情況
  2. 了解在不修改依賴項的 CMakeLists.txt 的情況下我可以做些什么來解決問題
  3. (可選)了解依賴作者可以采取哪些措施來防止它(如果適用)

這是我的 CMakeLists.txt 的樣子:

project(MyProject)
add_subdirectory(External/MyDependency)
# ...
add_executable(${PROJECT_NAME} ${MY_SOURCE_FILES})
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 17)
target_link_libraries(${PROJECT_NAME} my_dependency_lib)

這是我依賴項的 CMakeLists.txt的摘錄:

project(MyDependency)

# This is not the actual library I link
add_library(my_dependency_common INTERFACE)

# ...

# If I remove this line, I no longer get the warnings on my own code
target_compile_options(my_dependency_common INTERFACE /W4)

# This is where the actual library is built
# and my_dependency_lib is then linked to the my_dependency_common library
add_subdirectory(my_dependency_path)

編輯:因為關鍵字INTERFACE在這里似乎扮演着重要的角色,所以我在我的依賴項中包括了子目錄的摘錄。

add_library(my_dependency_common_2 INTERFACE)
target_link_libraries(my_dependency_common_2 INTERFACE my_dependency_common)

# this is the actual lib that I am linking
add_library(my_dependency_lib SHARED) 
target_link_libraries(my_dependency_lib my_dependency_common_2)

附加到具有INTERFACE可見性(或PUBLIC可見性,這意味着INTERFACE )的目標的信息會自動應用於鏈接目標。 您可以通過創建一個新的目標INTERFACE庫目標來避免這種情況,該目標提供必要的屬性來鏈接庫,但不提供不需要的屬性。 出於這個原因,像這樣的信息應該具有“盡可能PRIVATE ”的可見性。

請注意,該項目可能未設計為通過add_subdirectory包含在內。 你可能想檢查一下,如果項目中有 cmake 安裝邏輯,它提供了 cmake 配置腳本。 如果是這種情況,將依賴項編譯並安裝到本地目錄作為構建的引導步驟可能是一個不錯的選擇。

下面是如何在沒有不需要的選項的情況下包含 lib:

add_library(bad_lib foo.cpp foo.hpp)
target_include_directories(bad_lib PUBLIC good_include)
target_compile_options(bad_lib PUBLIC --bad-option)


# create interface lib for linking the lib without --bad-option being inherited
add_library(bad_lib_fixed INTERFACE)

# link the lib via the absolute library file path, not via the cmake target name
target_link_libraries(bad_lib_fixed INTERFACE $<TARGET_FILE:bad_lib> $<TARGET_PROPERTY:INTERFACE_LINK_LIBRARIES>)

target_include_directories(bad_lib_fixed INTERFACE $<TARGET_PROPERTY:bad_lib,INTERFACE_INCLUDE_DIRECTORIES>)


add_executable(LinkingTarget ...)
target_link_libraries(LinkingTarget PRIVATE bad_lib_fixed)

請注意,這僅適用,沒有 cmake 目標鏈接到bad_lib_fixedPUBLICINTERFACE可見性具有相同的問題。 否則需要添加這些庫的絕對路徑而不是$<TARGET_PROPERTY:INTERFACE_LINK_LIBRARIES> ...

此外請注意, INTERFACE庫目標只是為了方便而存在。 如果只有一個目標鏈接庫,您可以直接將屬性添加到該目標(可能將可見性更改為PUBLICPRIVATE )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM