Skip to content

Instantly share code, notes, and snippets.

@herrgahr
Last active April 1, 2021 14:37
Show Gist options
  • Save herrgahr/f482c1bdb7a28e084053dcd9667b4515 to your computer and use it in GitHub Desktop.
Save herrgahr/f482c1bdb7a28e084053dcd9667b4515 to your computer and use it in GitHub Desktop.
#example for generating compile_commands.json for a simple Makefile
# variables:
# CURDIR (make builtin) the CWD of the make process (build directory)
# / the project root - we're assuming the Makefile lives there
# CC the C compiler
# CFLAGS C compiler flags
# C_SRCS list of .c files that are built
/ := $(dir $(lastword $(MAKEFILE_LIST)))
$(CURDIR)/compile_commands.json:
@echo Generating $@
$(file >$@,$(compile_commands))
define compile_commands_1
{
"directory": "$(CURDIR)",
"command": "$(CC) $(CFLAGS) -c $1 -o $1.o",
"file": "$1"
}
endef
# since commpile_commands_1 does not emit a "," after each element, we need to add it.
# For this, we're using make's subst function. Since function arguments are delimited by
# commas, we can't use a literal , in the function call. For this, we define the _comma
# variable and use that instead.
# We'll be relacing "} {" by "},{"
# Another possibility would be to emit the comma in compile_commands_1 so we'll end up with
# with an invalid JSON array like : [{}, {}, ]
# The solution is to add a dummy element at the end: [{}, {}, {dummy-element}]
# Which brings us the the next problem: that dummy element can't be empty, otherwise clang tools will
# choke on the .json. So the dummy element will need to contain "directory", "command" and "file" fields
# whose contents will not really matter. I don't quite like this approach, so we'll do the
# 's/} {/},{' trick...
_comma=,
define compile_commands
[
$(subst } {,}$(_comma){,$(foreach s,$(C_SRCS),$(call compile_commands_1,$(realpath $/$s))))
]
endef
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment