Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate compile_commands.json #395

Closed
grafikrobot opened this issue May 23, 2024 · 8 comments · Fixed by #399
Closed

Generate compile_commands.json #395

grafikrobot opened this issue May 23, 2024 · 8 comments · Fixed by #399
Assignees
Labels
enhancement New feature or request

Comments

@grafikrobot
Copy link
Member

Many IDEs and downstream tools want to parse a compile_commands.json. The ideal solution for B2 would be to have single command actions to record. But since B2 currently doesn't guarantee such single command actions we need something else until we get those. The following is a "kludge" way of doing it. But something is better than nothing. What we need to implement:

  1. Add a feature to register action pre-execution hooks in the engine side. Such hooks would be given the action script string and can process the string. Possibly returning a different string to execute.
  2. Add a compile commands pre-launch step that loads an existing "compile_commands.json" at project root and writes it out at B2 exit.
  3. Add a action pre-exec hook to watch for per-toolset compile (and link?) commands that extracts the single command line invocation (by matching a regex in the action script). Control would be by adding a target variable COMPILE_COMMAND that sets a regex that extracts the command.
  4. Change, initially, the gcc/clang toolset to set the COMPILE_COMMAND for each appropriate action.
@grafikrobot grafikrobot added the enhancement New feature or request label May 23, 2024
@vinniefalco
Copy link

What is this "load an existing compile_commands.json?" Why?

@grafikrobot
Copy link
Member Author

What is this "load an existing compile_commands.json?" Why?

Because B2 can do very fine grained incremental builds. And if you want to get a full picture of the project you can't throw away the history of what you previously compiled on each b2 invocation. Especially if it's an invocation that's a no-op, which would create an empty json file.

@vinniefalco
Copy link

That is a nice to have feature but maybe not strictly required for an initial proof of concept.

@grisumbras
Copy link
Contributor

I think, the described approach is actually not needed. Running with different build requests, and appending commands to compile_commands.json is both unnecessary complexity and potentially problematic, when e.g. some targets are removed from the build scripts.

Rather, I think something like b2 variant=debug,release --compile-db should create a new file for all jam targets it considers for update (not necessarily updates). Maybe we also don't want it to actually try updating them, although there is already -n flag for that.

There's also a question what to do with ancillary targets e.g. created by ac module. Maybe potentially add an engile rule that marks a target as hidden?

Now, that I think of it, what if we can mark Jam targets as watched (maybe by setting a variable on them), and then their actions get recorded into some list in the form of command output sources?

@grafikrobot
Copy link
Member Author

After my many questions in slack, adjusted plan:

  1. Add a feature to register action pre-execution hooks in the engine side. Such hooks would be given the action script string and can process the string. Possibly returning a different string to execute.
  2. Add a action pre-exec hook to watch for per-toolset compile (and link?) commands that extracts the single command line invocation (by matching a regex in the action script). Control would be by adding a target variable COMMAND_DATABASE that sets a regex that extracts the command.
  3. Change, initially, the gcc/clang toolset to set the variable for each appropriate action.
  4. Add a command line arg --command-database=json that simulates the build request (i.e. equivalent to -n -a). That collects all the registered action commands and writes out the resulting json to <build-dir>/compile_commands.json.
  5. Add a command line arg --command-database-out=<filename> to specify an override to the file name and location.

@grafikrobot grafikrobot self-assigned this May 24, 2024
@grisumbras
Copy link
Contributor

LGTM
Also, AFAIK, link commands aren't needed.

@grafikrobot
Copy link
Member Author

Step 0? Structured data output to JSON complete: c30bce8

@grafikrobot
Copy link
Member Author

grafikrobot added a commit that referenced this issue Jun 2, 2024
…399)

This implements obtaining and generating compile commands from toolsets that compile C or C++ sources. I.e. implements both the --command-database=json amd --command-database-out=<filename> CLI options. Although it implements the toolset changes for most compilers, only a few are tested.

Fixes #395
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

3 participants