Skip to content
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

Implement cargo:rerun-if-env-changed=FOO #4125

Merged
merged 1 commit into from
Jun 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/cargo/ops/cargo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,7 @@ fn scrape_target_config(config: &Config, triple: &str)
env: Vec::new(),
metadata: Vec::new(),
rerun_if_changed: Vec::new(),
rerun_if_env_changed: Vec::new(),
warnings: Vec::new(),
};
// We require deterministic order of evaluation, so we must sort the pairs by key first.
Expand Down Expand Up @@ -745,7 +746,9 @@ fn scrape_target_config(config: &Config, triple: &str)
output.env.push((name.clone(), val.to_string()));
}
}
"warning" | "rerun-if-changed" => {
"warning" |
"rerun-if-changed" |
"rerun-if-env-changed" => {
bail!("`{}` is not supported in build script overrides", k);
}
_ => {
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/ops/cargo_rustc/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use util::{self, internal, Config, profile, Cfg, CfgExpr};
use util::errors::{CargoResult, CargoResultExt};

use super::TargetConfig;
use super::custom_build::{BuildState, BuildScripts};
use super::custom_build::{BuildState, BuildScripts, BuildDeps};
use super::fingerprint::Fingerprint;
use super::layout::Layout;
use super::links::Links;
Expand All @@ -38,7 +38,7 @@ pub struct Context<'a, 'cfg: 'a> {
pub compilation: Compilation<'cfg>,
pub packages: &'a PackageSet<'cfg>,
pub build_state: Arc<BuildState>,
pub build_explicit_deps: HashMap<Unit<'a>, (PathBuf, Vec<String>)>,
pub build_explicit_deps: HashMap<Unit<'a>, BuildDeps>,
pub fingerprints: HashMap<Unit<'a>, Arc<Fingerprint>>,
pub compiled: HashSet<Unit<'a>>,
pub build_config: BuildConfig,
Expand Down
36 changes: 29 additions & 7 deletions src/cargo/ops/cargo_rustc/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub struct BuildOutput {
pub metadata: Vec<(String, String)>,
/// Paths to trigger a rerun of this build script.
pub rerun_if_changed: Vec<String>,
/// Environment variables which, when changed, will cause a rebuild.
pub rerun_if_env_changed: Vec<String>,
/// Warnings generated by this build,
pub warnings: Vec<String>,
}
Expand Down Expand Up @@ -59,6 +61,12 @@ pub struct BuildScripts {
pub plugins: BTreeSet<PackageId>,
}

pub struct BuildDeps {
pub build_script_output: PathBuf,
pub rerun_if_changed: Vec<String>,
pub rerun_if_env_changed: Vec<String>,
}

/// Prepares a `Work` that executes the target as a custom build script.
///
/// The `req` given is the requirement which this run of the build script will
Expand Down Expand Up @@ -181,11 +189,8 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
// Check to see if the build script has already run, and if it has keep
// track of whether it has told us about some explicit dependencies
let prev_output = BuildOutput::parse_file(&output_file, &pkg_name).ok();
let rerun_if_changed = match prev_output {
Some(ref prev) => prev.rerun_if_changed.clone(),
None => Vec::new(),
};
cx.build_explicit_deps.insert(*unit, (output_file.clone(), rerun_if_changed));
let deps = BuildDeps::new(&output_file, prev_output.as_ref());
cx.build_explicit_deps.insert(*unit, deps);

fs::create_dir_all(&script_output)?;
fs::create_dir_all(&build_output)?;
Expand Down Expand Up @@ -246,8 +251,6 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)

})?;

paths::write(&output_file, &output.stdout)?;
paths::write(&err_file, &output.stderr)?;

// After the build command has finished running, we need to be sure to
// remember all of its output so we can later discover precisely what it
Expand All @@ -256,6 +259,8 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
// This is also the location where we provide feedback into the build
// state informing what variables were discovered via our script as
// well.
paths::write(&output_file, &output.stdout)?;
paths::write(&err_file, &output.stderr)?;
let parsed_output = BuildOutput::parse(&output.stdout, &pkg_name)?;

if json_messages {
Expand Down Expand Up @@ -337,6 +342,7 @@ impl BuildOutput {
let mut env = Vec::new();
let mut metadata = Vec::new();
let mut rerun_if_changed = Vec::new();
let mut rerun_if_env_changed = Vec::new();
let mut warnings = Vec::new();
let whence = format!("build script of `{}`", pkg_name);

Expand Down Expand Up @@ -378,6 +384,7 @@ impl BuildOutput {
"rustc-env" => env.push(BuildOutput::parse_rustc_env(value, &whence)?),
"warning" => warnings.push(value.to_string()),
"rerun-if-changed" => rerun_if_changed.push(value.to_string()),
"rerun-if-env-changed" => rerun_if_env_changed.push(value.to_string()),
_ => metadata.push((key.to_string(), value.to_string())),
}
}
Expand All @@ -389,6 +396,7 @@ impl BuildOutput {
env: env,
metadata: metadata,
rerun_if_changed: rerun_if_changed,
rerun_if_env_changed: rerun_if_env_changed,
warnings: warnings,
})
}
Expand Down Expand Up @@ -436,6 +444,20 @@ impl BuildOutput {
}
}

impl BuildDeps {
pub fn new(output_file: &Path, output: Option<&BuildOutput>) -> BuildDeps {
BuildDeps {
build_script_output: output_file.to_path_buf(),
rerun_if_changed: output.map(|p| &p.rerun_if_changed)
.cloned()
.unwrap_or_default(),
rerun_if_env_changed: output.map(|p| &p.rerun_if_env_changed)
.cloned()
.unwrap_or_default(),
}
}
}

/// Compute the `build_scripts` map in the `Context` which tracks what build
/// scripts each package depends on.
///
Expand Down
Loading