CMake:target_link_libraries包含为SYSTEM,以禁止编译器警告 [英] CMake: target_link_libraries include as SYSTEM to suppress compiler warnings
问题描述
为禁止源于我在应用程序中使用的库的编译器警告,在添加它们之前,我将它们的目录手动包含为 target_include_directories(myapp SYSTEM ...)
作为系统库与 target_link_libraries
像这样:
To suppress compiler warnings that originate from libraries I use in my application, I manually include their directories with target_include_directories(myapp SYSTEM ...)
as system libraries before adding them with target_link_libraries
like so:
add_executable(myapp myapp.cpp)
target_include_directories(myapp SYSTEM
PRIVATE "extern/lib/include"
)
target_link_libraries(myapp lib::lib)
但是,如果 lib
的开发人员决定更改include路径,这种感觉会很骇人,并且也会中断。如果仅使用 target_link_library
,这不会有问题,但是,当然,它们是通过 -I
包含的,并且
However, that kind of feels hacky and will also break if the developers of lib
decide to change the include path. This wouldn't be a problem if using only target_link_library
but then, of course, they are included via -I
and again I would get compiler warnings coming from this include.
是否还有其他更优雅,更安全的方式来做到这一点?如果 target_link_libraries
具有 SYSTEM
选项来告诉cmake将其包含为系统库,那就太好了。
Is there any more elegant and fail-safe way of doing this? It would be great if target_link_libraries
had a SYSTEM
option to tell cmake to include it as a system library.
推荐答案
我定义了一个函数来为我处理:
I defined a function to handle this for me:
function(target_link_libraries_system target)
set(libs ${ARGN})
foreach(lib ${libs})
get_target_property(lib_include_dirs ${lib} INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories(${target} SYSTEM PRIVATE ${lib_include_dirs})
target_link_libraries(${target} ${lib})
endforeach(lib)
endfunction(target_link_libraries_system)
我现在可以调用 target_link_libraries_system(myapp lib :: lib)
,并从目标的属性。
I can now call target_link_libraries_system(myapp lib::lib)
and the include directories are read from the target's properties.
这可以扩展为可选地指定 PUBLIC | PRIVATE | INTERFACE
范围:
This can be extended to optionally specify the PUBLIC|PRIVATE|INTERFACE
scope:
function(target_link_libraries_system target)
set(options PRIVATE PUBLIC INTERFACE)
cmake_parse_arguments(TLLS "${options}" "" "" ${ARGN})
foreach(op ${options})
if(TLLS_${op})
set(scope ${op})
endif()
endforeach(op)
set(libs ${TLLS_UNPARSED_ARGUMENTS})
foreach(lib ${libs})
get_target_property(lib_include_dirs ${lib} INTERFACE_INCLUDE_DIRECTORIES)
if(lib_include_dirs)
if(scope)
target_include_directories(${target} SYSTEM ${scope} ${lib_include_dirs})
else()
target_include_directories(${target} SYSTEM PRIVATE ${lib_include_dirs})
endif()
else()
message("Warning: ${lib} doesn't set INTERFACE_INCLUDE_DIRECTORIES. No include_directories set.")
endif()
if(scope)
target_link_libraries(${target} ${scope} ${lib})
else()
target_link_libraries(${target} ${lib})
endif()
endforeach()
endfunction(target_link_libraries_system)
此扩展版本还将打印如果图书馆未设置其 INTERFACE_INCLUDE_DIRECTORIES
属性,则会发出警告。
This extended version will also print a warning if a library didn't set its INTERFACE_INCLUDE_DIRECTORIES
property.
这篇关于CMake:target_link_libraries包含为SYSTEM,以禁止编译器警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!