Skip to content

Commit 8c2d0df

Browse files
committed
Merge branch 'master' into fix-allow-staged
* master: (25 commits) Migrate from tests fom assert_that/execs to .run() Wrap ProcessBuilder in Execs & make .cargo return that Make old Execs methods take not consume self Extract Execs::match_process Add #[must_use] to Execs Inline Execs::_with_stderr Remove an unrun "cargo build" ProcessBuilder Add documentation for creating test dependencies. Only use non-absolute paths for `path` dependencies Fix test failure on nightly due to `codemap::Span` change. New metabuild strategy using custom src_path enum. Remove unnecessary change. Address review comments. Metabuild (RFC 2196) Handle Window's missing file error message Make "cargo uninstall" uninstall the cwd bins update comment based on further research List URL in HTTP download failures Fix compilation error Improve the `cargo install` deprecation messaging ...
2 parents 2bbbca3 + 9ddf75a commit 8c2d0df

101 files changed

Lines changed: 9973 additions & 12757 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/bin/cargo/commands/install.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,10 @@ By default cargo will refuse to overwrite existing binaries. The `--force` flag
6060
enables overwriting existing binaries. Thus you can reinstall a crate with
6161
`cargo install --force <crate>`.
6262
63-
As a special convenience, omitting the <crate> specification entirely will
63+
Omitting the <crate> specification entirely will
6464
install the crate in the current directory. That is, `install` is equivalent to
65-
the more explicit `install --path .`.
65+
the more explicit `install --path .`. This behaviour is deprecated, and no
66+
longer supported as of the Rust 2018 edition.
6667
6768
If the source is crates.io or `--git` then by default the crate will be built
6869
in a temporary target directory. To avoid this, the target directory can be

src/cargo/core/compiler/custom_build.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
134134
let build_plan = bcx.build_config.build_plan;
135135
let invocation_name = unit.buildkey();
136136

137+
if let Some(deps) = unit.pkg.manifest().metabuild() {
138+
prepare_metabuild(cx, build_script_unit, deps)?;
139+
}
140+
137141
// Building the command to execute
138142
let to_exec = script_output.join(unit.target.name());
139143

@@ -532,6 +536,38 @@ impl BuildOutput {
532536
}
533537
}
534538

539+
fn prepare_metabuild<'a, 'cfg>(
540+
cx: &Context<'a, 'cfg>,
541+
unit: &Unit<'a>,
542+
deps: &[String],
543+
) -> CargoResult<()> {
544+
let mut output = Vec::new();
545+
let available_deps = cx.dep_targets(unit);
546+
// Filter out optional dependencies, and look up the actual lib name.
547+
let meta_deps: Vec<_> = deps
548+
.iter()
549+
.filter_map(|name| {
550+
available_deps
551+
.iter()
552+
.find(|u| u.pkg.name().as_str() == name.as_str())
553+
.map(|dep| dep.target.crate_name())
554+
})
555+
.collect();
556+
for dep in &meta_deps {
557+
output.push(format!("extern crate {};\n", dep));
558+
}
559+
output.push("fn main() {\n".to_string());
560+
for dep in &meta_deps {
561+
output.push(format!(" {}::metabuild();\n", dep));
562+
}
563+
output.push("}\n".to_string());
564+
let output = output.join("");
565+
let path = unit.pkg.manifest().metabuild_path(cx.bcx.ws.target_dir());
566+
fs::create_dir_all(path.parent().unwrap())?;
567+
paths::write_if_changed(path, &output)?;
568+
Ok(())
569+
}
570+
535571
impl BuildDeps {
536572
pub fn new(output_file: &Path, output: Option<&BuildOutput>) -> BuildDeps {
537573
BuildDeps {

src/cargo/core/compiler/fingerprint.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,24 @@ where
744744
return true;
745745
}
746746
};
747-
if mtime2 > mtime {
747+
748+
// Note that equal mtimes are considered "stale". For filesystems with
749+
// not much timestamp precision like 1s this is a conservative approximation
750+
// to handle the case where a file is modified within the same second after
751+
// a build finishes. We want to make sure that incremental rebuilds pick that up!
752+
//
753+
// For filesystems with nanosecond precision it's been seen in the wild that
754+
// its "nanosecond precision" isn't really nanosecond-accurate. It turns out that
755+
// kernels may cache the current time so files created at different times actually
756+
// list the same nanosecond precision. Some digging on #5919 picked up that the
757+
// kernel caches the current time between timer ticks, which could mean that if
758+
// a file is updated at most 10ms after a build finishes then Cargo may not
759+
// pick up the build changes.
760+
//
761+
// All in all, the equality check here is a conservative assumption that,
762+
// if equal, files were changed just after a previous build finished.
763+
// It's hoped this doesn't cause too many issues in practice!
764+
if mtime2 >= mtime {
748765
info!("stale: {} -- {} vs {}", path.display(), mtime2, mtime);
749766
true
750767
} else {

src/cargo/core/compiler/mod.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::sync::Arc;
88
use same_file::is_same_file;
99
use serde_json;
1010

11+
use core::manifest::TargetSourcePath;
1112
use core::profiles::{Lto, Profile};
1213
use core::shell::ColorChoice;
1314
use core::{PackageId, Target};
@@ -390,7 +391,6 @@ fn link_targets<'a, 'cfg>(
390391
let outputs = cx.outputs(unit)?;
391392
let export_dir = cx.files().export_dir();
392393
let package_id = unit.pkg.package_id().clone();
393-
let target = unit.target.clone();
394394
let profile = unit.profile;
395395
let unit_mode = unit.mode;
396396
let features = bcx.resolve
@@ -399,6 +399,12 @@ fn link_targets<'a, 'cfg>(
399399
.map(|s| s.to_owned())
400400
.collect();
401401
let json_messages = bcx.build_config.json_messages();
402+
let mut target = unit.target.clone();
403+
if let TargetSourcePath::Metabuild = target.src_path() {
404+
// Give it something to serialize.
405+
let path = unit.pkg.manifest().metabuild_path(cx.bcx.ws.target_dir());
406+
target.set_src_path(TargetSourcePath::Path(path));
407+
}
402408

403409
Ok(Work::new(move |_| {
404410
// If we're a "root crate", e.g. the target of this compilation, then we
@@ -668,12 +674,18 @@ fn rustdoc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoResult
668674
// second is the cwd that rustc should operate in.
669675
fn path_args(bcx: &BuildContext, unit: &Unit) -> (PathBuf, PathBuf) {
670676
let ws_root = bcx.ws.root();
671-
let src = unit.target.src_path();
677+
let src = if unit.target.is_custom_build() && unit.pkg.manifest().metabuild().is_some() {
678+
unit.pkg.manifest().metabuild_path(bcx.ws.target_dir())
679+
} else {
680+
unit.target.src_path().path().to_path_buf()
681+
};
672682
assert!(src.is_absolute());
673-
match src.strip_prefix(ws_root) {
674-
Ok(path) => (path.to_path_buf(), ws_root.to_path_buf()),
675-
Err(_) => (src.to_path_buf(), unit.pkg.root().to_path_buf()),
683+
if unit.pkg.package_id().source_id().is_path() {
684+
if let Ok(path) = src.strip_prefix(ws_root) {
685+
return (path.to_path_buf(), ws_root.to_path_buf());
686+
}
676687
}
688+
(src, unit.pkg.root().to_path_buf())
677689
}
678690

679691
fn add_path_args(bcx: &BuildContext, unit: &Unit, cmd: &mut ProcessBuilder) {

src/cargo/core/features.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ features! {
189189

190190
// "default-run" manifest option,
191191
[unstable] default_run: bool,
192+
193+
// Declarative build scripts.
194+
[unstable] metabuild: bool,
192195
}
193196
}
194197

0 commit comments

Comments
 (0)