11

In CMake, you can make TARGET_INCLUDE_DIRECTORIES() add include directories as system include directories (i.e. use -isystem) in order to not let warnings pop up which have their root in 3rd party code:

TARGET_INCLUDE_DIRECTORIES(mytarget
    SYSTEM
        ${3rdPartyLib_INCLUDE_DIR})

I prefer to use TARGET_LINK_LIBRARIES which also makes include directories from 3rd party libraries available. As far as I know, TARGET_LINK_LIBRARIES does not support the SYSTEM modifier to add those directories as a system include directories.

Did I get something wrong?

Is there a way to make:

TARGET_LINK_LIBRARIES(mytarget
    ${3rdPartyLib_INCLUDE_DIR})

use -isystem? (or any other way to suppress warnings from 3rdPartyLib).

frans
  • 8,868
  • 11
  • 58
  • 132
  • yes, create a psuedo-target to model the imported library and its dependencies. Then target_link_libraries that target. For example, see the findboost.cmake script and note how the boost libraries are represented by targets such as Boost::boost, Boost::system etc. https://github.com/Kitware/CMake/blob/master/Modules/FindBoost.cmake – Richard Hodges Aug 13 '18 at 07:48
  • Rather than *suppress* warnings from 3rd party library it would be a better idea to *isolate* them by implementing façade library of some sort. – user7860670 Aug 13 '18 at 09:22
  • That might be an option in some cases but not if you would have to create a facade for Boost and/or Qt - for small programs this would be about 95% boiler plate facade code vs 5% own code I guess. In this case I'd rather declare `TARGET_LINK_LIBRARIES()` incomplete and use `TARGET_INCLUDE_DIRECTORIES` instead. – frans Aug 13 '18 at 10:30
  • Does this answer your question? [CMake: target\_link\_libraries include as SYSTEM to suppress compiler warnings](https://stackoverflow.com/questions/52135983/cmake-target-link-libraries-include-as-system-to-suppress-compiler-warnings) – sebastian Sep 15 '22 at 10:52
  • `target_link_libraries` links to library targets. It doesn't make sense to pass it include directories. – starball Nov 04 '22 at 01:39

2 Answers2

6

I had a similar question, which I solved with a custom function:

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 could now be extended to specify the PUBLIC|PRIVATE|INTERFACE scope but since I use it on an executable, this is sufficient for now.

sebastian
  • 2,386
  • 26
  • 22
  • Note: this will not work with [generated properties](https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html#path-expressions). For that you have to do `target_include_directories(${target} SYSTEM PRIVATE "$>")`, since the properties will not be available at "cmake time". You may want to change `BUILD_INTERFACE` to something else, see link. – ARentalTV Jul 10 '23 at 16:50
-3

I suggest you create a header named myproject_thirdparty.h that look like this:

#ifndef myproject_thirdparty_h
#define myproject_thirdparty_h

#include "myprojectMacros.h"

CLANG_PRAGMA_PUSH
CLANG_SUPPRESS_Wfloat_equal
CLANG_PRAGMA_POP

#endif

where myprojectMacros.h would define useful macros like CLANG_PRAGMA_PUSH, CLANG_PRAGMA_POP, GCC_PRAGMA_PUSH, GCC_PRAGMA_POP, ...

For example of such macro, see https://github.com/InsightSoftwareConsortium/ITK/blob/6b41fe1cbf7a71a6003d4824e02a69b41a508cda/Modules/Core/Common/include/itkMacro.h#L69-L136

Then, within your project code, you would then include myproject_thirdparty_h each time you would like to use the library, this would effectively shutdown the warnings without impacting the remaining of your project.

J-Christophe
  • 1,975
  • 15
  • 13