From: "Philippe Blain via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "brian m. carlson" <sandals@crustytoothpaste.net>,
Jeff King <peff@peff.net>,
Philippe Blain <levraiphilippeblain@gmail.com>,
Philippe Blain <levraiphilippeblain@gmail.com>
Subject: [PATCH v3] Makefile: add support for generating JSON compilation database
Date: Thu, 03 Sep 2020 22:13:38 +0000 [thread overview]
Message-ID: <pull.714.v3.git.1599171218675.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.714.v2.git.1599001759548.gitgitgadget@gmail.com>
From: Philippe Blain <levraiphilippeblain@gmail.com>
Tools based on LibClang [1] can make use of a 'JSON Compilation
Database' [2] that keeps track of the exact options used to compile a set
of source files.
For example, clangd [3], which is a C language server protocol
implementation, can use a JSON compilation database to determine the
flags needed to compile a file so it can provide proper editor
integration. As a result, editors supporting the language server
protocol (such as VS Code, Emacs, or Vim, with suitable plugins) can
provide better searching, integration, and refactoring tools.
The Clang compiler can generate JSON fragments when compiling [4],
using the `-MJ` flag. These JSON fragments (one per compiled source
file) can then be concatenated to create the compilation database,
commonly called 'compile_commands.json'.
Add support to the Makefile for generating these JSON fragments as well
as the compilation database itself, if the environment variable
'GENERATE_COMPILATION_DATABASE' is set.
If this variable is set, check that $(CC) indeed supports the `-MJ`
flag, following what is done for automatic dependencies.
All JSON fragments are placed in the 'compile_commands/' directory, and
the compilation database 'compile_commands.json' is generated as a
dependency of the 'all' target using a `sed` invocation.
[1] https://clang.llvm.org/docs/Tooling.html
[2] https://clang.llvm.org/docs/JSONCompilationDatabase.html
[3] https://clangd.llvm.org/
[4] https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mj-arg
Helped-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com>
---
Add support for generating JSON compilation database
Changes since v2: Incorporated Junio's suggestions:
* improved the logic around values of the new
GENERATE_COMPILATION_DATABASE macro
* simplified the Makefile functions used to generate the path of the
JSON fragments
* removed the trailing slash after the default value of compdb_dir
Changes since v1:
* Added a paragraph to the commit message to better explain why this
feature would help Git developers (Thanks Brian!)
* Corrected the description of the new GENERATE_COMPILATION_DATABASE
Makefile knob to make it reflect its actual behavior (cf.
https://lore.kernel.org/git/FC95CFF7-F9DA-4CDA-9923-99C3432DCAD5@gmail.com/
)
v1: I don't have a lot of knowledge of Make double-colon rules, or
insight into why they are used for the 'all' target, but I think the
approach I chose makes sense. In particular, I do not list any
prerequisite for the 'compile_commands.json' file, but from what I
tested it is still rebuilt anytime the 'all' target is rebuilt, which is
what we want.
Note: CMakeLists.txt in contrib/buildsystems does not need to be updated
to also support this feature because CMake supports it out-of-the-box
[1].
[1]
https://cmake.org/cmake/help/latest/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-714%2Fphil-blain%2Fcompiledb-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-714/phil-blain/compiledb-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/714
Range-diff vs v2:
1: da9544e4aa ! 1: 1955b6b390 Makefile: add support for generating JSON compilation database
@@ Makefile: all::
# the global variable _wpgmptr containing the absolute path of the current
# executable (this is the case on Windows).
#
-+# Define GENERATE_COMPILATION_DATABASE to generate JSON compilation database
-+# entries during compilation if your compiler supports it, using the `-MJ` flag.
-+# The JSON entries will be placed in the `compile_commands/` directory,
-+# and the JSON compilation database 'compile_commands.json' will be created
-+# at the root of the repository.
++# Define GENERATE_COMPILATION_DATABASE to "yes" to generate JSON compilation
++# database entries during compilation if your compiler supports it, using the
++# `-MJ` flag. The JSON entries will be placed in the `compile_commands/`
++# directory, and the JSON compilation database 'compile_commands.json' will be
++# created at the root of the repository.
+#
# Define DEVELOPER to enable more compiler warnings. Compiler version
# and family are auto detected, but could be overridden by defining
@@ Makefile: $(error please set COMPUTE_HEADER_DEPENDENCIES to yes, no, or auto \
endif
endif
-+ifdef GENERATE_COMPILATION_DATABASE
++ifndef GENERATE_COMPILATION_DATABASE
++GENERATE_COMPILATION_DATABASE = no
++endif
++
++ifeq ($(GENERATE_COMPILATION_DATABASE),yes)
+compdb_check = $(shell $(CC) $(ALL_CFLAGS) \
+ -c -MJ /dev/null \
+ -x c /dev/null -o /dev/null 2>&1; \
+ echo $$?)
-+ifeq ($(compdb_check),0)
-+override GENERATE_COMPILATION_DATABASE = yes
-+else
++ifneq ($(compdb_check),0)
+override GENERATE_COMPILATION_DATABASE = no
-+$(warning GENERATE_COMPILATION_DATABASE is set, but your compiler does not \
++$(warning GENERATE_COMPILATION_DATABASE is set to "yes", but your compiler does not \
+support generating compilation database entries)
+endif
++else
++ifneq ($(GENERATE_COMPILATION_DATABASE),no)
++$(error please set GENERATE_COMPILATION_DATABASE to "yes" or "no" \
++(not "$(GENERATE_COMPILATION_DATABASE)"))
++endif
+endif
+
ifdef SANE_TOOL_PATH
@@ Makefile: missing_dep_dirs =
dep_args =
endif
-+compdb_dir = compile_commands/
++compdb_dir = compile_commands
+
+ifeq ($(GENERATE_COMPILATION_DATABASE),yes)
+missing_compdb_dir = $(compdb_dir)
+$(missing_compdb_dir):
+ @mkdir -p $@
+
-+compdb_file = $(compdb_dir)$(subst .-,,$(subst /,-,$(dir $@)))$(notdir $@).json
++compdb_file = $(compdb_dir)/$(subst /,-,$@.json)
+compdb_args = -MJ $(compdb_file)
+else
+missing_compdb_dir =
@@ Makefile: else
+all:: compile_commands.json
+compile_commands.json:
+ @$(RM) $@
-+ $(QUIET_GEN)sed -e '1s/^/[/' -e '$$s/,$$/]/' $(compdb_dir)*.o.json > $@+
++ $(QUIET_GEN)sed -e '1s/^/[/' -e '$$s/,$$/]/' $(compdb_dir)/*.o.json > $@+
+ @if test -s $@+; then mv $@+ $@; else $(RM) $@+; fi
+endif
+
.gitignore | 2 ++
Makefile | 59 +++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 56 insertions(+), 5 deletions(-)
diff --git a/.gitignore b/.gitignore
index ee509a2ad2..f4c51300e0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -197,6 +197,7 @@
/git.spec
*.exe
*.[aos]
+*.o.json
*.py[co]
.depend/
*.gcda
@@ -218,6 +219,7 @@
/tags
/TAGS
/cscope*
+/compile_commands.json
*.hcc
*.obj
*.lib
diff --git a/Makefile b/Makefile
index 65f8cfb236..39ca667689 100644
--- a/Makefile
+++ b/Makefile
@@ -462,6 +462,12 @@ all::
# the global variable _wpgmptr containing the absolute path of the current
# executable (this is the case on Windows).
#
+# Define GENERATE_COMPILATION_DATABASE to "yes" to generate JSON compilation
+# database entries during compilation if your compiler supports it, using the
+# `-MJ` flag. The JSON entries will be placed in the `compile_commands/`
+# directory, and the JSON compilation database 'compile_commands.json' will be
+# created at the root of the repository.
+#
# Define DEVELOPER to enable more compiler warnings. Compiler version
# and family are auto detected, but could be overridden by defining
# COMPILER_FEATURES (see config.mak.dev). You can still set
@@ -1258,6 +1264,27 @@ $(error please set COMPUTE_HEADER_DEPENDENCIES to yes, no, or auto \
endif
endif
+ifndef GENERATE_COMPILATION_DATABASE
+GENERATE_COMPILATION_DATABASE = no
+endif
+
+ifeq ($(GENERATE_COMPILATION_DATABASE),yes)
+compdb_check = $(shell $(CC) $(ALL_CFLAGS) \
+ -c -MJ /dev/null \
+ -x c /dev/null -o /dev/null 2>&1; \
+ echo $$?)
+ifneq ($(compdb_check),0)
+override GENERATE_COMPILATION_DATABASE = no
+$(warning GENERATE_COMPILATION_DATABASE is set to "yes", but your compiler does not \
+support generating compilation database entries)
+endif
+else
+ifneq ($(GENERATE_COMPILATION_DATABASE),no)
+$(error please set GENERATE_COMPILATION_DATABASE to "yes" or "no" \
+(not "$(GENERATE_COMPILATION_DATABASE)"))
+endif
+endif
+
ifdef SANE_TOOL_PATH
SANE_TOOL_PATH_SQ = $(subst ','\'',$(SANE_TOOL_PATH))
BROKEN_PATH_FIX = 's|^\# @@BROKEN_PATH_FIX@@$$|git_broken_path_fix "$(SANE_TOOL_PATH_SQ)"|'
@@ -2381,16 +2408,30 @@ missing_dep_dirs =
dep_args =
endif
+compdb_dir = compile_commands
+
+ifeq ($(GENERATE_COMPILATION_DATABASE),yes)
+missing_compdb_dir = $(compdb_dir)
+$(missing_compdb_dir):
+ @mkdir -p $@
+
+compdb_file = $(compdb_dir)/$(subst /,-,$@.json)
+compdb_args = -MJ $(compdb_file)
+else
+missing_compdb_dir =
+compdb_args =
+endif
+
ASM_SRC := $(wildcard $(OBJECTS:o=S))
ASM_OBJ := $(ASM_SRC:S=o)
C_OBJ := $(filter-out $(ASM_OBJ),$(OBJECTS))
.SUFFIXES:
-$(C_OBJ): %.o: %.c GIT-CFLAGS $(missing_dep_dirs)
- $(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
-$(ASM_OBJ): %.o: %.S GIT-CFLAGS $(missing_dep_dirs)
- $(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
+$(C_OBJ): %.o: %.c GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)
+ $(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(compdb_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
+$(ASM_OBJ): %.o: %.S GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)
+ $(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(compdb_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
%.s: %.c GIT-CFLAGS FORCE
$(QUIET_CC)$(CC) -o $@ -S $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
@@ -2413,6 +2454,14 @@ else
$(OBJECTS): $(LIB_H) $(GENERATED_H)
endif
+ifeq ($(GENERATE_COMPILATION_DATABASE),yes)
+all:: compile_commands.json
+compile_commands.json:
+ @$(RM) $@
+ $(QUIET_GEN)sed -e '1s/^/[/' -e '$$s/,$$/]/' $(compdb_dir)/*.o.json > $@+
+ @if test -s $@+; then mv $@+ $@; else $(RM) $@+; fi
+endif
+
exec-cmd.sp exec-cmd.s exec-cmd.o: GIT-PREFIX
exec-cmd.sp exec-cmd.s exec-cmd.o: EXTRA_CPPFLAGS = \
'-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \
@@ -3117,7 +3166,7 @@ clean: profile-clean coverage-clean cocciclean
$(RM) $(TEST_PROGRAMS)
$(RM) $(FUZZ_PROGRAMS)
$(RM) $(HCC)
- $(RM) -r bin-wrappers $(dep_dirs)
+ $(RM) -r bin-wrappers $(dep_dirs) $(compdb_dir) compile_commands.json
$(RM) -r po/build/
$(RM) *.pyc *.pyo */*.pyc */*.pyo $(GENERATED_H) $(ETAGS_TARGET) tags cscope*
$(RM) -r $(GIT_TARNAME) .doc-tmp-dir
base-commit: d9cd4331470f4d9d78677f12dc79063dab832f53
--
gitgitgadget
prev parent reply other threads:[~2020-09-03 22:13 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-30 19:28 [PATCH] Makefile: add support for generating JSON compilation database Philippe Blain via GitGitGadget
2020-08-30 22:10 ` brian m. carlson
2020-08-31 2:37 ` Philippe Blain
2020-08-31 4:24 ` Junio C Hamano
2020-09-01 7:38 ` Jeff King
2020-09-01 13:18 ` Philippe Blain
2020-09-02 1:33 ` brian m. carlson
2020-09-02 8:04 ` Jeff King
2020-08-30 22:17 ` Philippe Blain
2020-09-01 23:09 ` [PATCH v2] " Philippe Blain via GitGitGadget
2020-09-02 17:21 ` Junio C Hamano
2020-09-03 21:17 ` Philippe Blain
2020-09-03 21:31 ` Junio C Hamano
2020-09-03 22:04 ` Philippe Blain
2020-09-03 22:13 ` Philippe Blain via GitGitGadget [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.714.v3.git.1599171218675.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=levraiphilippeblain@gmail.com \
--cc=peff@peff.net \
--cc=sandals@crustytoothpaste.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).