Build.rs: is it possible to declare output files?

Hi!

I'm using cbindgen through build.rs to generate a .h file for my FFI. The header file is written to the
root of the crate, or to a CARGO_TARGET_DIR (env variable), so that this can be steered by an
"outer" build system.

My problem is: whenever the header file is deleted, cargo doesn't know that the file is supposed to be
a target of the build, and if the rest of the build is up-to-date the header file will not be regenerated.

Is it possible to declare the path to the generated header file, so that the build system knows about it?

I'm thinking something along the lines of rerun-if-changed, but meant to declare an output rather than an input file to the build system.

Thank you in advance for your help!

Albe

In general, the build script should only ever create or change files in the directory given by the environment variable OUT_DIR. If you don't follow this convention, you will run into various problems, including the one you mentioned in the question.

Hi @smarnach,

thanks for your answer! That makes sense, I'll try to do that.

However, if I write the header file to OUT_DIR, it will be hard for another type system to find it (target/debug/build/libname-hash/out/). Do you know of a way to reference the "stable" output directory? Pretty much like my libxyz.a is being copied into target/debug/libxyz.a, I would need my cbindgen-generated xyz.h to also be in there.

Also, I would still need to inform cargo of the existence of my xyz.h. If I delete target/debug/libxyz.a, it will nicely be recreated on the next cargo build, ideally I could do the same with the header file.

You are right, my answer did not really address your question.

I don't think there is a way to inform Cargo about build artefacts it doesn't know by itself. If you are using another build system anyway, maybe you could include a rule to generate the header file in the superordinate build system, using the cbindgen command line tool? You should declare a dependency on libxyz.a to make sure the header file is regenerated whenever the library changes.

Related to both problems (a stable out directory and a declared output for the build system), I found some discussion in cargo about this, for example https://github.com/rust-lang/cargo/issues/5457 and the related PR https://github.com/rust-lang/cargo/pull/7325 but it seems like this isn't a priority at the moment.

Since this is a library that will be exposed to other languages (and other build systems :slight_smile: ) I hoped to be able to keep it clean and simple with just cargo.

I guess at this point my best bet is wrapping it in a Makefile and expose that to the outer build systems. Thank you for your answers!