c++cmakeinterfaceheader-only

Add interface library as SYSTEM in modern CMake


I'm currently transforming my C++ project from simply using a Makefile to using CMake. As I'm unfamiliar with CMake, I try and avoid learning "old" CMake and stick to "modern CMake" best practices, e.g. described here.

However, I could not figure out how to include a simple, header-only, third party library without getting bothered with warnings about that library.

Say I have a project structure like this:

CMakeLists.txt
src/
  CMakeLists.txt
  main.cpp
third-party-lib/
  foo/
    foo.h

Say main.cpp uses foo: #include <foo.h>

The problem is, I use a bunch of warning flags and foo.h introduces some warnings that I don't care about, as I'm not the author and it's nothing serious.

In a classic Makefile I would just have written -isystem third-party-lib/foo somewhere appropriate and be done.

In CMake, I achieved this by a include_directories(SYSTEM PRIVATE third-party-lib/foo) in the top-level CMakeLists.txt.

Now, according to the link above, I should keep my hands off include_directories() to avoid hidden dependencies and I think that this is a good idea. I'd rather specify for each target that actually needs foo to include that library and treat it as 'don't warn me here'. As I understand it, the approach would be:

How would I achieve that, i.e. what is the command for finding, and where to specify the SYSTEM property? Or any other suggestions for how to approach this?


Solution

  • To add a header-only library in modern CMake, you can use target_include_directories with SYSTEM INTERFACE. You can place this in your top-level CMake file, before processing the src/CMakeLists.txt file:

    add_library(foo INTERFACE)
    target_include_directories(foo SYSTEM INTERFACE 
        ${CMAKE_SOURCE_DIR}/third-party-lib/foo
    )