CMAKE_EXPORT_COMPILE_COMMANDS with Ninja doesn't use absolute paths
So I'd been trying to get some clang
tools (completion, syntax checking, etc.) working with various editors (cmake-ide
in Emacs, and the C++ extension with VS Code), and finally figured out my problem:
When generating the compile_commands.json
with the Ninja generator, all the include paths are relative, instead of absolute. This breaks tooling when the build is out-of-tree. Contrary to this, the GNU Make generator produces absolute paths in the file.
This is with CMake version 3.9.6 on macOS "High Sierra".
Expected output
This is the output with the GNU Make generator for the Apache Mesos CMake build system:
{
"directory": "/Users/andrew/src/mesos/build/3rdparty/stout/tests",
"command": "/usr/local/opt/ccache/libexec/c++ -DHAVE_LIBZ -DLIBDIR=\\\"/usr/local/libmesos\\\" -DPICOJSON_USE_INT64 -DPKGDATADIR=\\\"/usr/local/share/mesos\\\" -DPKGLIBEXECDIR=\\\"/usr/local/libexec/mesos\\\" -DVERSION=\\\"1.5.0\\\" -D__STDC_FORMAT_MACROS -I/Users/andrew/src/mesos/build/3rdparty/stout/tests -I/Users/andrew/src/mesos/3rdparty/stout/include -isystem /usr/local/opt/apr/libexec/include/apr-1 -isystem /Users/andrew/src/mesos/build/3rdparty/boost-1.53.0/src/boost-1.53.0 -isystem /Users/andrew/src/mesos/build/3rdparty/elfio-3.2/src/elfio-3.2 -isystem /Users/andrew/src/mesos/build/3rdparty/glog-0.3.3/src/glog-0.3.3-build/include -isystem /Users/andrew/src/mesos/build/3rdparty/picojson-1.3.0/src/picojson-1.3.0 -isystem /Users/andrew/src/mesos/build/3rdparty/protobuf-3.3.0/src/protobuf-3.3.0/src -isystem /usr/local/opt/subversion/include/subversion-1 -isystem /Users/andrew/src/mesos/build/3rdparty/googletest-1.8.0/src/googletest-1.8.0/googlemock/include -isystem /Users/andrew/src/mesos/build/3rdparty/googletest-1.8.0/src/googletest-1.8.0/googletest/include -std=c++11 -Wformat-security -fstack-protector-strong -O3 -DNDEBUG -fPIE -o CMakeFiles/stout-tests.dir/base64_tests.cpp.o -c /Users/andrew/src/mesos/3rdparty/stout/tests/base64_tests.cpp",
"file": "/Users/andrew/src/mesos/3rdparty/stout/tests/base64_tests.cpp"
},
Tooling that uses this to setup e.g. include paths (for flycheck
in Emacs) works since the paths are absolute.
Example: -isystem /Users/andrew/src/mesos/build/3rdparty/googletest-1.8.0/src/googletest-1.8.0/googletest/include
Actual output
However, with the Ninja generator, the output is:
{
"directory": "/Users/andrew/src/mesos/build",
"command": "/usr/local/opt/ccache/libexec/c++ -DHAVE_LIBZ -DLIBDIR=\\\"/usr/local/libmesos\\\" -DPICOJSON_USE_INT64 -DPKGDATADIR=\\\"/usr/local/share/mesos\\\" -DPKGLIBEXECDIR=\\\"/usr/local/libexec/mesos\\\" -DVERSION=\\\"1.5.0\\\" -D__STDC_FORMAT_MACROS -I3rdparty/stout/tests -I../3rdparty/stout/include -isystem /usr/local/opt/apr/libexec/include/apr-1 -isystem 3rdparty/boost-1.53.0/src/boost-1.53.0 -isystem 3rdparty/elfio-3.2/src/elfio-3.2 -isystem 3rdparty/glog-0.3.3/src/glog-0.3.3-build/include -isystem 3rdparty/picojson-1.3.0/src/picojson-1.3.0 -isystem 3rdparty/protobuf-3.3.0/src/protobuf-3.3.0/src -isystem /usr/local/opt/subversion/include/subversion-1 -isystem 3rdparty/googletest-1.8.0/src/googletest-1.8.0/googlemock/include -isystem 3rdparty/googletest-1.8.0/src/googletest-1.8.0/googletest/include -std=c++11 -Wformat-security -fstack-protector-strong -fPIE -o 3rdparty/stout/tests/CMakeFiles/stout-tests.dir/base64_tests.cpp.o -c /Users/andrew/src/mesos/3rdparty/stout/tests/base64_tests.cpp",
"file": "/Users/andrew/src/mesos/3rdparty/stout/tests/base64_tests.cpp"
},
Note that the -isystem
include paths for our third-party dependencies (built with ExternalProject_Add
and imported with add_library(foo IMPORTED) ... INTERFACE_INCLUDE_DIRECTORIES /absolute/path/to/googletest/include
, see here) have dropped their absolute path information, and are instead relative.
This appears to break tooling that expects CMake to give it absolute paths (by CMake's nature), and indeed it is dropping the absolute path info (I double checked that the set INTERFACE_INCLUDE_DIRECTORIES
is indeed absolute).
Example: -isystem 3rdparty/googletest-1.8.0/src/googletest-1.8.0/googletest/include
Am I perhaps doing something wrong with our Ninja build?