I have a library that I want to use in my project but want its files to be treated as system header files when included in my own code.
Here’s my directory structure:
top
src1
src2
src3
include
libs
blah
some_lib
In directory libs I have a CMakeLists.txt that has
add_subdirectory(blah/some_lib SYSTEM)
some_lib itself uses its own cmake setup to build. I expected all the include directories from some_lib to be using -isystem but they still use -I. I even tried adding
add_subdirectory(libs SYSTEM)
to my top level CMakeLists.txt but still no go.
Is this the right way to do what I want to do? Looking at the cmake documentation it’s not clear if the SYSTEM property will propagate to all subdirectories.
If I recall correctly, when you set the SYSTEM directory property to true, it propagates into any subdirectories that directory creates too. In other words, it should be acting recursively. It wouldn’t really make sense for it to work any other way, as already highlighted in comments above.
The behavior probably relates to details of the project not provided. You mentioned that the subdirectory uses its own cmake setup, but what does that mean? It is most likely related to that, but without any details about precisely how that is done and how you’re adding things from there into the main build, it’s hard to offer any further insight.
Depends what you mean by “how the -I/-isystem paths are added to consumers”. If you just want to see the compiler command lines so you can tell what flags are used, the method for that depends on what CMake generator you’re using. If you’re using Ninja, add --verbose to the ninja command line. If using Makefiles, add VERBOSE=1 to the make command line (I think this works, it’s been so long since I had to do that with Makefiles). If you’re using something else, you can probably find the details in the IDE settings somewhere.
I can see that the command lines don’t have the -isystem that I expected.
What I meant is to find where those command lines are created. Perhaps checking the SYSTEM property at that point can shed some light and I can somehow trace it back.
Can you show the contents of the file at libs/blah/some_lib/CMakeLists.txt? The details of that will probably shed some light on what’s really going on.
I’ll be honest, that’s a lot more detail than I have time to go through. I suggest you reduce your real world case down to a minimal project which demonstrates the problem. That exercise very often uncovers the underlying cause. If you can still reproduce the problem with a very minimal example, that will be more likely to be investigated further.
I can definitely understand I have a decent workaround. As I get more comfortable with cmake, if I find the time, I’ll try to distill it and report it here.
# target_include_directories with the SYSTEM modifier will request the compiler to omit warnings
# from the provided paths, if the compiler supports that
target_include_directories(
${PROJECT_NAME} SYSTEM PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)