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) 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.
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.
cmake:48 (include) CMakeLists. txt:208 (find_package) This warning is for project developers. Use -Wno-dev to suppress it. You can disable the warning like this when you are configuring your build.
Specify libraries or flags to use when linking a given target and/or its dependents. Usage requirements from linked library targets will be propagated. Usage requirements of a target's dependencies affect compilation of its own sources.
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) I can now call target_link_libraries_system(myapp lib::lib) and the include directories are read from the target's properties.
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) This extended version will also print a warning if a library didn't set its INTERFACE_INCLUDE_DIRECTORIES property.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With