Generate compile_commands.json compilation database #944
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Please check if the PR fulfills these requirements
before creating one)
our contributing guidelines
What kind of change does this PR introduce?
New feature: Allow generating
compile_commands.json
file as a side effect of compilation, for consumption by editors and other tooling, as requested in Feature Request: Export compile_commands.json #849.What is the new behavior?
All compile commands (not linking and other steps) ran are output to a compilation database, a file called
compile_commands.json
(see https://clang.llvm.org/docs/JSONCompilationDatabase.html for the format). This file can be used by editors (often usingclang
orclangd
) to provide code completion, navigation and diagnostics.Other information:
This is just a rough draft, that still needs more work, some decisions and some feedback. I wanted to quickly throw something together, which ended up a bit more work than I thought. The basics work, though this is probably more of a proof of concept that might need to be significantly restructured. Open points are:
CompilationDatabase
class outside of thelegacy/builder
directory (seemed good to not add more legacy), but now I'm unsure how to approach logging. It seems that the cli and builder code have distinct logging facilities, neither of which seems easily accessible. For now I just added "fmt.Print". Suggestions are welcome.compile_commands.json
to the sketch directory, since that's where editors would look for it. I later realized that it would probably be good to also write a version to the temp build directory (note: I mean the/tmp/arduino-sketch-XYZ
directory, not thebuild
subdirectory of the sketch dir where the compilation result is exported), for any tooling that wants to inspect the copied and preprocessed sketch files.compile_commands.json
to be written to the temp build dir, but the sketch dir version should really point to the original sketch files. This means that thefile
element in the json should be updated, but maybe also any compiler arguments that resolve to sketch files should have their paths updated. This should probably be applied generically (i.e. search replacing back to the original sketch dir) to all arguments, since we can't be sure what aplatform.txt
does exactly. Alternatively, updating just thefile
field might be sufficient and can be done by passing the original filename around (does require significant refactoring, I think).-include=Arduino.h
flag added (as suggested in Feature Request: Export compile_commands.json #849 (comment)). This is imperfect, but probably as close as we can get.compile_commands.json
to the temp build dir can always be done, but writing to the sketch directory should almost certainly be opt-in (through commandline or config), to prevent user surprise and because the IDE and arduino-cli seem to try hard to prevent touching the sketch dir now. For arduino-cli, it might make sense to always generate the file in thebuild
subdirectory, along with the compiled program, and provide an option to also, or instead of, generate in the sketch directory itself (where it will be mostly automatically picked up by editors orclangd
). For the IDE, some extra care should probably be taken to not generate this file in the sketch directory for unmodified examples, even if the user enabled it in the config.compile_commands.json
file. Ideally, any existing file should be read and merged, taking care to remove any extra entries (e.g. for deleted files), but only when compilation was successful (or at least complete). Alternatively, a complete list of files to be compiled could also be used maybe (even when compilation is aborted halfway).