Skip to content

Commit 3821c38

Browse files
phil-blaingitster
authored andcommitted
Makefile: add support for generating JSON compilation database
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 <[email protected]> Signed-off-by: Philippe Blain <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e197136 commit 3821c38

File tree

2 files changed

+56
-5
lines changed

2 files changed

+56
-5
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@
197197
/git.spec
198198
*.exe
199199
*.[aos]
200+
*.o.json
200201
*.py[co]
201202
.depend/
202203
*.gcda
@@ -218,6 +219,7 @@
218219
/tags
219220
/TAGS
220221
/cscope*
222+
/compile_commands.json
221223
*.hcc
222224
*.obj
223225
*.lib

Makefile

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,12 @@ all::
462462
# the global variable _wpgmptr containing the absolute path of the current
463463
# executable (this is the case on Windows).
464464
#
465+
# Define GENERATE_COMPILATION_DATABASE to "yes" to generate JSON compilation
466+
# database entries during compilation if your compiler supports it, using the
467+
# `-MJ` flag. The JSON entries will be placed in the `compile_commands/`
468+
# directory, and the JSON compilation database 'compile_commands.json' will be
469+
# created at the root of the repository.
470+
#
465471
# Define DEVELOPER to enable more compiler warnings. Compiler version
466472
# and family are auto detected, but could be overridden by defining
467473
# 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 \
12581264
endif
12591265
endif
12601266

1267+
ifndef GENERATE_COMPILATION_DATABASE
1268+
GENERATE_COMPILATION_DATABASE = no
1269+
endif
1270+
1271+
ifeq ($(GENERATE_COMPILATION_DATABASE),yes)
1272+
compdb_check = $(shell $(CC) $(ALL_CFLAGS) \
1273+
-c -MJ /dev/null \
1274+
-x c /dev/null -o /dev/null 2>&1; \
1275+
echo $$?)
1276+
ifneq ($(compdb_check),0)
1277+
override GENERATE_COMPILATION_DATABASE = no
1278+
$(warning GENERATE_COMPILATION_DATABASE is set to "yes", but your compiler does not \
1279+
support generating compilation database entries)
1280+
endif
1281+
else
1282+
ifneq ($(GENERATE_COMPILATION_DATABASE),no)
1283+
$(error please set GENERATE_COMPILATION_DATABASE to "yes" or "no" \
1284+
(not "$(GENERATE_COMPILATION_DATABASE)"))
1285+
endif
1286+
endif
1287+
12611288
ifdef SANE_TOOL_PATH
12621289
SANE_TOOL_PATH_SQ = $(subst ','\'',$(SANE_TOOL_PATH))
12631290
BROKEN_PATH_FIX = 's|^\# @@BROKEN_PATH_FIX@@$$|git_broken_path_fix "$(SANE_TOOL_PATH_SQ)"|'
@@ -2381,16 +2408,30 @@ missing_dep_dirs =
23812408
dep_args =
23822409
endif
23832410

2411+
compdb_dir = compile_commands
2412+
2413+
ifeq ($(GENERATE_COMPILATION_DATABASE),yes)
2414+
missing_compdb_dir = $(compdb_dir)
2415+
$(missing_compdb_dir):
2416+
@mkdir -p $@
2417+
2418+
compdb_file = $(compdb_dir)/$(subst /,-,$@.json)
2419+
compdb_args = -MJ $(compdb_file)
2420+
else
2421+
missing_compdb_dir =
2422+
compdb_args =
2423+
endif
2424+
23842425
ASM_SRC := $(wildcard $(OBJECTS:o=S))
23852426
ASM_OBJ := $(ASM_SRC:S=o)
23862427
C_OBJ := $(filter-out $(ASM_OBJ),$(OBJECTS))
23872428

23882429
.SUFFIXES:
23892430

2390-
$(C_OBJ): %.o: %.c GIT-CFLAGS $(missing_dep_dirs)
2391-
$(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
2392-
$(ASM_OBJ): %.o: %.S GIT-CFLAGS $(missing_dep_dirs)
2393-
$(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
2431+
$(C_OBJ): %.o: %.c GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)
2432+
$(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(compdb_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
2433+
$(ASM_OBJ): %.o: %.S GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir)
2434+
$(QUIET_CC)$(CC) -o $*.o -c $(dep_args) $(compdb_args) $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
23942435

23952436
%.s: %.c GIT-CFLAGS FORCE
23962437
$(QUIET_CC)$(CC) -o $@ -S $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
@@ -2413,6 +2454,14 @@ else
24132454
$(OBJECTS): $(LIB_H) $(GENERATED_H)
24142455
endif
24152456

2457+
ifeq ($(GENERATE_COMPILATION_DATABASE),yes)
2458+
all:: compile_commands.json
2459+
compile_commands.json:
2460+
@$(RM) $@
2461+
$(QUIET_GEN)sed -e '1s/^/[/' -e '$$s/,$$/]/' $(compdb_dir)/*.o.json > $@+
2462+
@if test -s $@+; then mv $@+ $@; else $(RM) $@+; fi
2463+
endif
2464+
24162465
exec-cmd.sp exec-cmd.s exec-cmd.o: GIT-PREFIX
24172466
exec-cmd.sp exec-cmd.s exec-cmd.o: EXTRA_CPPFLAGS = \
24182467
'-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \
@@ -3117,7 +3166,7 @@ clean: profile-clean coverage-clean cocciclean
31173166
$(RM) $(TEST_PROGRAMS)
31183167
$(RM) $(FUZZ_PROGRAMS)
31193168
$(RM) $(HCC)
3120-
$(RM) -r bin-wrappers $(dep_dirs)
3169+
$(RM) -r bin-wrappers $(dep_dirs) $(compdb_dir) compile_commands.json
31213170
$(RM) -r po/build/
31223171
$(RM) *.pyc *.pyo */*.pyc */*.pyo $(GENERATED_H) $(ETAGS_TARGET) tags cscope*
31233172
$(RM) -r $(GIT_TARNAME) .doc-tmp-dir

0 commit comments

Comments
 (0)