For example, I have a build script that is producing files under target/debug/build/my-package-123456789abcdef/out
. Specifically, I am putting generated headers there generated from cbindgen and I want to reference them from a C project later. Can I expect the hex digits to remain stable when having the C project look for headers there?
I guess it may be randomly generated or the hash of that crate, but you shouldn't to get or memorize that code, using env!("OUT_DIR")
may help. Check this documentation for some other environment variables.
tips: If you want to use rust code generated by build script, try using include!
macro.
It's the $META in
It's a hash of various inputs such as the crate name, some compiler flags, and the hashes of friendliness, one of the various Metadata fields in:
It's not clear to me which field is used exactly, but it's a clear enough signal that, no, you can't realistically depend on it staying the same over any reasonable period as it depends on the rust version and effectively the cargo version.
If you need them from a non-cargo project later, perhaps you could simply not use $OUT_DIR, or write the path to it somewhere predictable. Otherwise you could look into parsing cargo JSON output to drive a higher level build? Not sure if it goes down to that level.
Rather than generating the headers in a build script, how about writing a build command yourself which does a cargo build and separately runs cbindgen to write the headers to a fixed location. You could use something like GitHub - casey/just: 🤖 Just a command runner or the xtask pattern.
Marking @simonbuchan's answer as the solution here because I think it most directly answers the question, but I really would like a general answer to where to best place generated output artifacts like headers for an FFI. I think this question is closely related to Build.rs: is it possible to declare output files?. Seems like there has been a decent amount of discussion around OUT_DIR in the past.
Do you need the C headers to build your Rust code, or are you using cbindgen
in build.rs
because it gets called at a seemingly convenient time? Why not have the C project run cbindgen
as part of its build process?
Also ... You should never write to a directory that isn't OUT_DIR
in build.rs
or try to reach out of the standard directories. It's tempting and it works in easy cases but it will eventually break vendoring and any code that uses your crate as a dependency.
Well, sure, but we're seemingly already in "needs to be built outside of cargo" territory, which isn't uncommon for applications.