cmakecppcheck

Use -I instead of -isystem when using CMake find_package in compile_commands.json


My question is basically the inverse of this SO question - Use -isystem instead of -I with CMake

I have a library I'm testing and the test application brings in the library via CMake's find_package

# CMakeLists.txt

...
find_package(as REQUIRED)
add_executable(as-tests tests.cpp ...)
target_link_libraries(as-tests as::as)
...

This all works fine but the problem is CMake seems to add -isystem to all include paths brought in this way as opposed to with target_include_directories. This is what I see when I generate a compile_commands.json file.

# compile_commands.json

...
{
  "directory": ...
  "command": ... -isystem <full/path/to/as/include/>" ...
  "file": ...
},
...

I was wondering if it's possible to pass a flag or setting to find_package to let CMake know this is not a system library but a local one (especially if I've installed it to somewhere that's not the default install location using CMAKE_INSTALL_PREFIX and later CMAKE_PREFIX_PATH.

The reason this is causing me pain is I'd like to use cppcheck to analyze these files but it (sensibly) ignores all files it deems to be system includes.

$ cppcheck --project=compile_commands.json --language=c++ --std=c++17 --enable=all

# will not analyse any includes with -isystem prefix

So in summary, can I do something like find_package(as REQUIRED NOT_SYSTEM) to get the normal -I to appear in compile_commands.json?

Thanks! :)


Update:

@mathstuf is 100% correct (thank you for your answer!) I wanted to expand on this slightly as the current state of things isn't exactly what I was after...

It is possible to set NO_SYSTEM_FROM_IMPORTED on the target you are building, but not on imported targets..

e.g. You can do this:

project(app LANGUAGES CXX)

add_executable(
    ${PROJECT_NAME} main.cpp)
set_target_properties(
    ${PROJECT_NAME} PROPERTIES
    NO_SYSTEM_FROM_IMPORTED true)

but you cannot do this:

find_package(lib REQUIRED)
set_target_properties(
    lib::lib PROPERTIES
    NO_SYSTEM_FROM_IMPORTED true)

This is alright, but this means if you have multiple imported targets you can't pick one particular library to be -I and another to remain as -isystem (-isystem is the default for all imported targets).

You can see more info about this here https://gitlab.kitware.com/cmake/cmake/issues/17348 and here https://gitlab.kitware.com/cmake/cmake/issues/17364

I guess I'll just have to live with everything being -I for now


Solution

  • There is the target property NO_SYSTEM_FROM_IMPORTED you can set on the consuming target to remove that behavior.