From ca97a0fefbbe7f066e7ec4251db0e5aa9f61e291 Mon Sep 17 00:00:00 2001 From: John Pennycook Date: Tue, 13 Feb 2024 15:47:40 -0800 Subject: [PATCH] cmake: Enable compilation database generation (#42353) * cmake: Enable CMAKE_EXPORT_COMPILE_COMMANDS Enabling this option causes CMake to generate a compile_commands.json file containing a compilation database that can be used to drive third-party tools. CMAKE_EXPORT_COMPILE_COMMANDS only exists for CMake >= 3.5 Exporting compilation databases is only supported for Makefile and Ninja generators, so check these conditions as well. CMAKE_EXPORT_COMPILE_COMMANDS is only enabled in supported configurations --- lib/spack/spack/build_systems/cmake.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/spack/spack/build_systems/cmake.py b/lib/spack/spack/build_systems/cmake.py index d66d531694b4b0..b6e66e136cd230 100644 --- a/lib/spack/spack/build_systems/cmake.py +++ b/lib/spack/spack/build_systems/cmake.py @@ -58,6 +58,20 @@ def _maybe_set_python_hints(pkg: spack.package_base.PackageBase, args: List[str] ) +def _supports_compilation_databases(pkg: spack.package_base.PackageBase) -> bool: + """Check if this package (and CMake) can support compilation databases.""" + + # CMAKE_EXPORT_COMPILE_COMMANDS only exists for CMake >= 3.5 + if not pkg.spec.satisfies("^cmake@3.5:"): + return False + + # CMAKE_EXPORT_COMPILE_COMMANDS is only implemented for Makefile and Ninja generators + if not (pkg.spec.satisfies("generator=make") or pkg.spec.satisfies("generator=ninja")): + return False + + return True + + def _conditional_cmake_defaults(pkg: spack.package_base.PackageBase, args: List[str]) -> None: """Set a few default defines for CMake, depending on its version.""" cmakes = pkg.spec.dependencies("cmake", dt.BUILD) @@ -95,6 +109,10 @@ def _conditional_cmake_defaults(pkg: spack.package_base.PackageBase, args: List[ args.append(CMakeBuilder.define("CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY", False)) args.append(CMakeBuilder.define("CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY", False)) + # Export a compilation database if supported. + if _supports_compilation_databases(pkg): + args.append(CMakeBuilder.define("CMAKE_EXPORT_COMPILE_COMMANDS", True)) + def generator(*names: str, default: Optional[str] = None): """The build system generator to use. @@ -284,7 +302,10 @@ class CMakeBuilder(BaseBuilder): @property def archive_files(self): """Files to archive for packages based on CMake""" - return [os.path.join(self.build_directory, "CMakeCache.txt")] + files = [os.path.join(self.build_directory, "CMakeCache.txt")] + if _supports_compilation_databases(self): + files.append(os.path.join(self.build_directory, "compile_commands.json")) + return files @property def root_cmakelists_dir(self):