CMake:target_link_libraries包含为SYSTEM,以禁止编译器警告

时间:2018-09-02 10:12:48

标签: cmake

要禁止源于我在应用程序中使用的库的编译器警告,我先将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将其包含为系统库,那就太好了。

4 个答案:

答案 0 :(得分:2)

我定义了一个函数来为我处理:

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范围,但是由于我在可执行文件上使用了它,所以现在就足够了。

答案 1 :(得分:2)

我修改了塞巴斯蒂安的解决方案以包括范围。

function(target_link_libraries_system target scope)
  set(libs ${ARGN})
  foreach(lib ${libs})
    get_target_property(lib_include_dirs ${lib} INTERFACE_INCLUDE_DIRECTORIES)
    target_include_directories(${target} SYSTEM ${scope} ${lib_include_dirs})
    target_link_libraries(${target} ${scope} ${lib})
  endforeach(lib)
endfunction(target_link_libraries_system )

答案 2 :(得分:2)

这在 CMake discourse 中被问到,@ben.boeckel(CMake 开发人员)回答:

<块引用>

IMPORTED 目标应该已经有它们的包含目录 虽然被视为系统。有 NO_SYSTEM_FROM_IMPORTED 目标 属性来禁用它。

答案 3 :(得分:0)

可能的陷阱:如果您像我一样,请通过启用顶层目录中的所有警告来启动每个项目…

Array
(
    [0] => Sample text 1
    [1] => Sample text 2
    [2] => </title>
)

...然后,这显然会被所有子项目(例如git子模块或您拥有的东西)继承。

如果是这种情况,则解决方案很简单–具体:在子目录中进行操作,和/或使用# Warning level add_compile_options( -Wall -Wextra -Wpedantic -Werror=switch -Werror=return-type -Werror=uninitialized -Werror=format-security -Werror=reorder -Werror=delete-non-virtual-dtor $<$<CONFIG:Debug>:-Werror> ) ,以取得良好效果:

target_compile_options