rust-lang / cc-rs

Rust library for build scripts to compile C/C++ code into a Rust library
https://docs.rs/cc
Apache License 2.0
1.76k stars 425 forks source link

Emit compile_commands.json #497

Open thedataking opened 4 years ago

thedataking commented 4 years ago

Many editors and IDEs work better on C code when provided with a compilation database (compile_commands.json) because it tells the editor where to look for include files, the values of defines, etc.. Here are tools to generate compilation databases when using Make or cmake to build a C code base. For projects where the C code is embedded a Rust project and built with this crate, it would be helpful to be able to get a compilation database.

alexeyr commented 3 years ago

I was thinking and the problem is, what happens with multiple Builds? They need to combine their commands into a single JSON array, so just appending to a file doesn't work.

Option 1: be explicit. Create a CompilationDatabase, pass it to each Build, emit with a method on CompilationDatabase. Maybe on Drop as well to deal with panicking commands? Option 2: Create a static CompilationDatabase, each Build (optionally) adds itself to it, on Drop removes itself. When all are removed, the database is written.
Option 3: before executing every new command read the current compilation database from the file, parse it, add the new command entry and write back.

All options have something to dislike, I am not sure which is better. Or maybe there is an option 4.

schrieveslaach commented 2 years ago

@alexeyr, what do you think about following option:

let mut database = CompilationDatabase::new();

cc::Build::new().file("blobstore.c").compile_and_store("blobstore", &mut database);
// … more builds

database.store(/* maybe with a path */);

If we find a nice API I'm happy to contribute that API.

vext01 commented 1 year ago

Came here to request this very same feature!

In the meantime I think I may be able to capture the compiler commands by wrapping the compiler with a shell script...

sporksmith commented 1 year ago

In the meantime I think I may be able to capture the compiler commands by wrapping the compiler with a shell script...

That was ultimately our solution in shadow, which is in the process of incrementally migrating from C to Rust. We already had a setup script to wrap our build process, so we changed it to use the bear wrapper to generate compile_commands.json.

jeteve commented 2 weeks ago

@sporksmith Could you point to how you setup the bear wrapper for cc::Build?