Skip to content

Commit

Permalink
feat(prost-build): emit rerun commands
Browse files Browse the repository at this point in the history
Inform `cargo` about the files and env vars used by `prost-build`. Then `cargo` can better determine when to rebuild a project.

- Emit `rerun-if-changed` for each proto file specified
- Emit `rerun-if-changed` for each include directory specified
- Emit `rerun-if-changed` if `file_descriptor_set_path` is set
- Emit `rerun-if-env-changed` for `PROTOC` and `PROTOC_INCLUDE`

https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-changed

BREAKING CHANGE: Previously `cargo` assumed it had to rerun `build.rs` if any files in the project changed. `prost-build` will now emit `rerun` commands, which means only the explicitly marked files cause a rerun. If `build.rs` is dependent on any other file paths than those given to `prost-build`, then your `build.rs` needs to emit `rerun` commands as well.
  • Loading branch information
caspermeijn committed Aug 30, 2024
1 parent 21208ab commit b4c8112
Showing 1 changed file with 5 additions and 6 deletions.
11 changes: 5 additions & 6 deletions prost-build/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,7 @@ impl Config {
) -> Result<FileDescriptorSet> {
let tmp;
let file_descriptor_set_path = if let Some(path) = &self.file_descriptor_set_path {
println!("cargo:rerun-if-changed={}", path.display());
path.clone()
} else {
if self.skip_protoc_run {
Expand All @@ -910,6 +911,7 @@ impl Config {
.arg(&file_descriptor_set_path);

for include in includes {
println!("cargo:rerun-if-changed={}", include.as_ref().display());
if include.as_ref().exists() {
cmd.arg("-I").arg(include.as_ref());
} else {
Expand All @@ -931,6 +933,7 @@ impl Config {
}

for proto in protos {
println!("cargo:rerun-if-changed={}", proto.as_ref().display());
cmd.arg(proto.as_ref());
}

Expand Down Expand Up @@ -1000,12 +1003,6 @@ impl Config {
protos: &[impl AsRef<Path>],
includes: &[impl AsRef<Path>],
) -> Result<()> {
// TODO: This should probably emit 'rerun-if-changed=PATH' directives for cargo, however
// according to [1] if any are output then those paths replace the default crate root,
// which is undesirable. Figure out how to do it in an additive way; perhaps gcc-rs has
// this figured out.
// [1]: http://doc.crates.io/build-script.html#outputs-of-the-build-script

let file_descriptor_set = self.load_fds(protos, includes)?;

self.compile_fds(file_descriptor_set)
Expand Down Expand Up @@ -1225,13 +1222,15 @@ pub fn error_message_protoc_not_found() -> String {

/// Returns the path to the `protoc` binary.
pub fn protoc_from_env() -> PathBuf {
println!("cargo:rerun-if-env-changed=PROTOC");
env::var_os("PROTOC")
.map(PathBuf::from)
.unwrap_or(PathBuf::from("protoc"))
}

/// Returns the path to the Protobuf include directory.
pub fn protoc_include_from_env() -> Option<PathBuf> {
println!("cargo:rerun-if-env-changed=PROTOC_INCLUDE");
let protoc_include: PathBuf = env::var_os("PROTOC_INCLUDE")?.into();

if !protoc_include.exists() {
Expand Down

0 comments on commit b4c8112

Please sign in to comment.