为了禁止源于我在应用程序中使用的库的编译器警告,在将它们添加到target_include_directories(myapp SYSTEM ...)
之前,我手动将它们的目录包含在target_link_libraries
作为系统库,如下所示:
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
包括在内的,并且我再次从该包含中收到编译器警告。有没有更优雅,更安全的方式来做到这一点?如果
target_link_libraries
有一个SYSTEM
选项告诉cmake将其包含为系统库,那就太好了。
最佳答案
我定义了一个函数来为我处理:
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)
,并且从目标的属性中读取包含目录。可以扩展为可选地指定
PUBLIC|PRIVATE|INTERFACE
范围: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
属性,则此扩展版本还将打印警告。
关于cmake - CMake:target_link_libraries包含为SYSTEM,以禁止编译器警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52135983/