Re: Constant recompilation when GENERATE_COMPILATION_DATABASE is set
From: Philippe Blain <hidden>
Date: 2023-10-27 15:41:27
Subsystem:
kernel build + files below scripts/ (unless maintained elsewhere), the rest · Maintainers:
Nathan Chancellor, Nicolas Schier, Linus Torvalds
Hi brian, Le 2023-10-27 à 07:45, brian m. carlson a écrit :
I typically use clangd with Git for the nice language server protocol (LSP) support. I noticed that when GENERATE_COMPILATION_DATABASE is set (which is used so clangd can find the proper flags), `make` rebuilds all of the files every time, even if I do it back to back. This persists even after a `git clean -dxf`. Obviously, this is not great, since it means the turnaround time to compile changes is slower. Unfortunately, I'm not a huge expert in make and I'm unsure what the right solution is here. I'd appreciate anyone's thoughts on how to improve this. This is on a Debian sid (unstable) amd64 system with the following configuration. The version of clang in use is Debian's 16.0.6. ---- NO_OPENSSL=1 DC_SHA1=1 NETTLE_SHA256=1 DEVELOPER=1 NO_SVN_TESTS=1 NO_PYTHON=1 USE_ASCIIDOCTOR=1 USE_ASCIIDOCTOR_MANPAGE=1 CC=clang GENERATE_COMPILATION_DATABASE=yes CSPRNG_METHOD=getrandom getentropy ----
Indeed, with GENERATE_COMPILATION_DATABASE=yes and CC=clang I can reproduce with: make clean make -j make -j # this rebuilds everything make -j # this does not rebuild anything so the second 'make' invocation is buggy, but not subsequent ones. I took a look at the 'make -d' output and we can see it is the dependency on the 'compile_commands' directory that is the culprit, on the second invocation it is newer than the the first object file that makes checks. This makes sense since each time we compile an object we put the JSON fragment in compile_commands, so the directory is updated each time an object is built, so clearly its modification date will be newer than the one of the first object built. One way to fix this is to use the same trick that is used for the '.depend' directories created to hold the Makefile dependencies:
diff --git a/Makefile b/Makefile
index 5776309365..f6f7255dd1 100644
--- a/Makefile
+++ b/Makefile@@ -2701,7 +2701,7 @@ endif compdb_dir = compile_commands ifeq ($(GENERATE_COMPILATION_DATABASE),yes) -missing_compdb_dir = $(compdb_dir) +missing_compdb_dir = $(filter-out $(wildcard $(compdb_dir)), $(compdb_dir)) $(missing_compdb_dir): @mkdir -p $@
That is, we define missing_compdb_dir to 'compile_commands' only if the directory is not yet created. I'll try to send a proper patch for this. Thanks for the report, Philippe.