-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Add Cargo post-build scripts #1777
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
- Feature Name: post_build | ||
- Start Date: 2016-10-26 | ||
- RFC PR: (leave this empty) | ||
- Rust Issue: (leave this empty) | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
This will add the ability for an extra build script to be run *after* the build completes. | ||
|
||
This is a similar concept current build script concept but rather than processing files beforehand, | ||
this script would perform tasks _after_ the crate has completed compilation. | ||
|
||
# Motivation | ||
[motivation]: #motivation | ||
|
||
This feature will give Rust programmers more flexibility when compiling their crates. | ||
|
||
Pre-build scripts as we have today are very useful for performing tasks before the | ||
crate is compiled, such as for compiling C/C++ sources or generating bindings. It | ||
is not currently possible to do anything _after_ Cargo finishes. | ||
|
||
## Use cases | ||
|
||
On most platforms, once linking is done there is no longer any work to do. This | ||
differs on some systems, such as AVR (which requires linked ELF binaries to be | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this would be better handled by a Cargo subcommand. The rationale is that even if Cargo would produce a raw binary blob as its final artifact you'll still need to call a second tool to flash that into a device. So, IMO, we could leave things as they are (final artifact = ELF) and have a Cargo subcommand, say There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's a good idea, I like it |
||
converted into raw binary blobs). | ||
|
||
Currently this would require something like a Makefile which internally | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you elaborate on this? It seems to if the Makefile uses Cargo then there are crates within the repository / project directory and those crates can be published to crates.io. |
||
calls `cargo`, which prohibits the crate being published to `crates.io`. | ||
|
||
In another case, we could use post-build scripts to generate mountable disk | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For development, a Cargo subcommand like the one I mentioned above could fit the bill. For deployments, I think that's very likely that one will need to use shell scripts or Makefiles to produce the final tarball, checksum it, sign it, upload it, etc. so I don't see much gain from having Cargo help with an extra step of doing the executable -> .iso file part. |
||
images for an operating system kernel written in Rust. Again, this is something | ||
that would require an external build system today. | ||
|
||
# Detailed design | ||
[design]: #detailed-design | ||
|
||
The crate manifest `[package]` table will support another textual field `post-build`. | ||
|
||
A normal manifest would look something like this: | ||
|
||
```toml | ||
[package] | ||
name = "foobar" | ||
|
||
build = "pre-build.rs" | ||
post-build = "post-build.rs" | ||
``` | ||
|
||
Once `cargo build` finishes compiling a crate, it will check if there is a `post-build` script | ||
configured, and it will compile and run it similarly to the current build script setup. | ||
|
||
A post-build script looks like this: | ||
|
||
```rust | ||
use std::process::Command; | ||
|
||
fn main() { | ||
let out_dir = env::var("OUT_DIR").unwrap(); | ||
|
||
Command::new("avr-objcopy") | ||
.arg(&format!("-i elf32 -o binary {}/myobject {}/mybinary", out_dir, out_dir)) | ||
.spawn(); | ||
} | ||
``` | ||
|
||
If the build script returns an error code, Cargo should report compilation as failed. | ||
|
||
# Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
* More complexity in the Cargo source | ||
* A corner case that won't be used very often | ||
|
||
# Alternatives | ||
[alternatives]: #alternatives | ||
|
||
* Use a Makefile-like build system which calls into Cargo | ||
* Expect users to do post-processing manually | ||
|
||
If Cargo will not support something given crate authors this ability, people will | ||
be forced to stray-away from the crates ecosystem and use something more custom. | ||
|
||
# Unresolved questions | ||
[unresolved]: #unresolved-questions | ||
|
||
* What should "crate compilation finished" mean in this regard? | ||
* Should `cargo doc` run the post-build script? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another common use case for embedded systems is to display the binary size information (e.g.
arm-none-eabi-size the_binary
) after each build.