CMake:target_link_libraries包含为SYSTEM,以禁止编译器警告 [英] CMake: target_link_libraries include as SYSTEM to suppress compiler warnings

查看:107
本文介绍了CMake:target_link_libraries包含为SYSTEM,以禁止编译器警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为禁止源于我在应用程序中使用的库的编译器警告,在添加它们之前,我将它们的目录手动包含为 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆