mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00

This is a partial revert of ##14121 (e11d1722bb6e1e58c91adb1964993c74b45f4293) Our focus for redacting (auto or with globs) includes - run-specific information (timing, hashes, platform-specific wording) - rustc-specific information (We tend to use globs for rustc-specific information because there might be some very specific times we need to care about some of the details) However, "Packaged files" does not fit into any of that and, for now, we are erring on the side of redacting less, rather than more, with the move to snapbox. As we see how it works out and what the underlying requirements are, we can revisit this.
3329 lines
97 KiB
Rust
3329 lines
97 KiB
Rust
//! Tests specific to artifact dependencies, designated using
|
|
//! the new `dep = { artifact = "bin", … }` syntax in manifests.
|
|
|
|
use cargo_test_support::compare::assert_e2e;
|
|
use cargo_test_support::prelude::*;
|
|
use cargo_test_support::registry::{Package, RegistryBuilder};
|
|
use cargo_test_support::str;
|
|
use cargo_test_support::{
|
|
basic_bin_manifest, basic_manifest, cross_compile, project, publish, registry, rustc_host,
|
|
Project,
|
|
};
|
|
|
|
#[cargo_test]
|
|
fn check_with_invalid_artifact_dependency() {
|
|
// invalid name
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", artifact = "unknown" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "extern crate bar;") // this would fail but we don't get there, artifacts are no libs
|
|
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
|
|
.file("bar/src/lib.rs", "")
|
|
.build();
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml`
|
|
|
|
Caused by:
|
|
'unknown' is not a valid artifact specifier
|
|
|
|
"#]])
|
|
.with_status(101)
|
|
.run();
|
|
|
|
fn run_cargo_with_and_without_bindeps_feature(
|
|
p: &Project,
|
|
cmd: &str,
|
|
assert: &dyn Fn(&mut cargo_test_support::Execs),
|
|
) {
|
|
assert(
|
|
p.cargo(&format!("{} -Z bindeps", cmd))
|
|
.masquerade_as_nightly_cargo(&["bindeps"]),
|
|
);
|
|
assert(&mut p.cargo(cmd));
|
|
}
|
|
|
|
// lib specified without artifact
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", lib = true }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
|
|
.file("bar/src/lib.rs", "")
|
|
.build();
|
|
run_cargo_with_and_without_bindeps_feature(&p, "check", &|cargo| {
|
|
cargo
|
|
.with_stderr_data(str![[r#"
|
|
[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml`
|
|
|
|
Caused by:
|
|
'lib' specifier cannot be used without an 'artifact = …' value (bar)
|
|
|
|
"#]])
|
|
.with_status(101)
|
|
.run();
|
|
});
|
|
|
|
// target specified without artifact
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", target = "target" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
|
|
.file("bar/src/lib.rs", "")
|
|
.build();
|
|
run_cargo_with_and_without_bindeps_feature(&p, "check", &|cargo| {
|
|
cargo
|
|
.with_stderr_data(str![[r#"
|
|
[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml`
|
|
|
|
Caused by:
|
|
'target' specifier cannot be used without an 'artifact = …' value (bar)
|
|
|
|
"#]])
|
|
.with_status(101)
|
|
.run();
|
|
})
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn check_with_invalid_target_triple() {
|
|
// invalid name
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", artifact = "bin", target = "unknown-target-triple" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.build();
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[ERROR] failed to run `rustc` to learn about target-specific information
|
|
|
|
Caused by:
|
|
process didn't exit successfully: `rustc - --crate-name ___ --print=file-names --target unknown-target-triple [..]` ([EXIT_STATUS]: 1)
|
|
--- stderr
|
|
[ERROR] Error loading target specification: Could not find specification for target "unknown-target-triple". Run `rustc --print target-list` for a list of built-in targets
|
|
|
|
|
|
"#]])
|
|
.with_status(101)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn build_without_nightly_aborts_with_error() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", artifact = "bin" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "extern crate bar;")
|
|
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
|
|
.file("bar/src/lib.rs", "")
|
|
.build();
|
|
p.cargo("check")
|
|
.with_status(101)
|
|
.with_stderr_data(str![[r#"
|
|
[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml`
|
|
|
|
Caused by:
|
|
`artifact = …` requires `-Z bindeps` (bar)
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn disallow_artifact_and_no_artifact_dep_to_same_package_within_the_same_dep_category() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", artifact = "bin" }
|
|
bar_stable = { path = "bar/", package = "bar" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.build();
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_status(101)
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[WARNING] foo v0.0.0 ([ROOT]/foo) ignoring invalid dependency `bar_stable` which is missing a lib target
|
|
[ERROR] the crate `foo v0.0.0 ([ROOT]/foo)` depends on crate `bar v0.5.0 ([ROOT]/foo/bar)` multiple times with different names
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn features_are_unified_among_lib_and_bin_dep_of_same_target() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies.d1]
|
|
path = "d1"
|
|
features = ["d1f1"]
|
|
artifact = "bin"
|
|
lib = true
|
|
|
|
[dependencies.d2]
|
|
path = "d2"
|
|
features = ["d2f2"]
|
|
"#,
|
|
)
|
|
.file(
|
|
"src/main.rs",
|
|
r#"
|
|
fn main() {
|
|
d1::f1();
|
|
d1::f2();
|
|
d2::f1();
|
|
d2::f2();
|
|
}
|
|
"#,
|
|
)
|
|
.file(
|
|
"d1/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "d1"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[features]
|
|
d1f1 = ["d2"]
|
|
|
|
[dependencies.d2]
|
|
path = "../d2"
|
|
features = ["d2f1"]
|
|
optional = true
|
|
"#,
|
|
)
|
|
.file(
|
|
"d1/src/main.rs",
|
|
r#"fn main() {
|
|
#[cfg(feature = "d1f1")]
|
|
d2::f1();
|
|
|
|
// Using f2 is only possible as features are unififed across the same target.
|
|
// Our own manifest would only enable f1, and f2 comes in because a parent crate
|
|
// enables the feature in its manifest.
|
|
#[cfg(feature = "d1f1")]
|
|
d2::f2();
|
|
}"#,
|
|
)
|
|
.file(
|
|
"d1/src/lib.rs",
|
|
r#"
|
|
#[cfg(feature = "d2")]
|
|
extern crate d2;
|
|
/// Importing f2 here shouldn't be possible as unless features are unified.
|
|
#[cfg(feature = "d1f1")]
|
|
pub use d2::{f1, f2};
|
|
"#,
|
|
)
|
|
.file(
|
|
"d2/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "d2"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[features]
|
|
d2f1 = []
|
|
d2f2 = []
|
|
"#,
|
|
)
|
|
.file(
|
|
"d2/src/lib.rs",
|
|
r#"
|
|
#[cfg(feature = "d2f1")] pub fn f1() {}
|
|
#[cfg(feature = "d2f2")] pub fn f2() {}
|
|
"#,
|
|
)
|
|
.build();
|
|
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 3 packages to latest compatible versions
|
|
[COMPILING] d2 v0.0.1 ([ROOT]/foo/d2)
|
|
[COMPILING] d1 v0.0.1 ([ROOT]/foo/d1)
|
|
[COMPILING] foo v0.0.1 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn features_are_not_unified_among_lib_and_bin_dep_of_different_target() {
|
|
if cross_compile::disabled() {
|
|
return;
|
|
}
|
|
let target = cross_compile::alternate();
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies.d1]
|
|
path = "d1"
|
|
features = ["d1f1"]
|
|
artifact = "bin"
|
|
lib = true
|
|
target = "$TARGET"
|
|
|
|
[dependencies.d2]
|
|
path = "d2"
|
|
features = ["d2f2"]
|
|
"#
|
|
.replace("$TARGET", target),
|
|
)
|
|
.file(
|
|
"src/main.rs",
|
|
r#"
|
|
fn main() {
|
|
// the lib = true part always builds for our current target, unifying dependencies
|
|
d1::d2::f1();
|
|
d1::d2::f2();
|
|
d2::f1();
|
|
d2::f2();
|
|
}
|
|
"#,
|
|
)
|
|
.file(
|
|
"d1/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "d1"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[features]
|
|
d1f1 = ["d2"]
|
|
|
|
[dependencies.d2]
|
|
path = "../d2"
|
|
features = ["d2f1"]
|
|
optional = true
|
|
"#,
|
|
)
|
|
.file("d1/src/main.rs", r#"fn main() {
|
|
// f1 we set ourselves
|
|
d2::f1();
|
|
// As 'main' is only compiled as part of the artifact dependency and since that is not unified
|
|
// if the target differs, trying to access f2 is a compile time error as the feature isn't enabled in our dependency tree.
|
|
d2::f2();
|
|
}"#)
|
|
.file(
|
|
"d1/src/lib.rs",
|
|
r#"
|
|
#[cfg(feature = "d2")]
|
|
pub extern crate d2;
|
|
"#,
|
|
)
|
|
.file(
|
|
"d2/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "d2"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[features]
|
|
d2f1 = []
|
|
d2f2 = []
|
|
"#,
|
|
)
|
|
.file(
|
|
"d2/src/lib.rs",
|
|
r#"
|
|
#[cfg(feature = "d2f1")] pub fn f1() {}
|
|
#[cfg(feature = "d2f2")] pub fn f2() {}
|
|
"#,
|
|
)
|
|
.build();
|
|
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_status(101)
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 3 packages to latest compatible versions
|
|
[COMPILING] d2 v0.0.1 ([ROOT]/foo/d2)
|
|
[COMPILING] d1 v0.0.1 ([ROOT]/foo/d1)
|
|
error[E0425]: cannot find function `f2` in crate `d2`
|
|
...
|
|
|
|
For more information about this error, try `rustc --explain E0425`.
|
|
[ERROR] could not compile `d1` (bin "d1") due to 1 previous error
|
|
...
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn feature_resolution_works_for_cfg_target_specification() {
|
|
if cross_compile::disabled() {
|
|
return;
|
|
}
|
|
let target = cross_compile::alternate();
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies.d1]
|
|
path = "d1"
|
|
artifact = "bin"
|
|
target = "$TARGET"
|
|
"#
|
|
.replace("$TARGET", target),
|
|
)
|
|
.file(
|
|
"src/main.rs",
|
|
r#"
|
|
fn main() {
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_D1"));
|
|
}
|
|
"#,
|
|
)
|
|
.file(
|
|
"d1/Cargo.toml",
|
|
&r#"
|
|
[package]
|
|
name = "d1"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[target.'$TARGET'.dependencies]
|
|
d2 = { path = "../d2" }
|
|
"#
|
|
.replace("$TARGET", target),
|
|
)
|
|
.file(
|
|
"d1/src/main.rs",
|
|
r#"fn main() {
|
|
d1::f();
|
|
}"#,
|
|
)
|
|
.file("d1/build.rs", r#"fn main() { }"#)
|
|
.file(
|
|
"d1/src/lib.rs",
|
|
&r#"pub fn f() {
|
|
#[cfg(target = "$TARGET")]
|
|
d2::f();
|
|
}
|
|
"#
|
|
.replace("$TARGET", target),
|
|
)
|
|
.file(
|
|
"d2/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "d2"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
authors = []
|
|
"#,
|
|
)
|
|
.file("d2/build.rs", r#"fn main() { }"#)
|
|
.file("d2/src/lib.rs", "pub fn f() {}")
|
|
.build();
|
|
|
|
p.cargo("test -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn build_script_with_bin_artifacts() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[build-dependencies]
|
|
bar = { path = "bar/", artifact = ["bin", "staticlib", "cdylib"] }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("build.rs", r#"
|
|
fn main() {
|
|
let baz: std::path::PathBuf = std::env::var("CARGO_BIN_FILE_BAR_baz").expect("CARGO_BIN_FILE_BAR_baz").into();
|
|
println!("{}", baz.display());
|
|
assert!(&baz.is_file());
|
|
|
|
let lib: std::path::PathBuf = std::env::var("CARGO_STATICLIB_FILE_BAR_bar").expect("CARGO_STATICLIB_FILE_BAR_bar").into();
|
|
println!("{}", lib.display());
|
|
assert!(&lib.is_file());
|
|
|
|
let lib: std::path::PathBuf = std::env::var("CARGO_CDYLIB_FILE_BAR_bar").expect("CARGO_CDYLIB_FILE_BAR_bar").into();
|
|
println!("{}", lib.display());
|
|
assert!(&lib.is_file());
|
|
|
|
let dir: std::path::PathBuf = std::env::var("CARGO_BIN_DIR_BAR").expect("CARGO_BIN_DIR_BAR").into();
|
|
println!("{}", dir.display());
|
|
assert!(dir.is_dir());
|
|
|
|
let bar: std::path::PathBuf = std::env::var("CARGO_BIN_FILE_BAR").expect("CARGO_BIN_FILE_BAR").into();
|
|
println!("{}", bar.display());
|
|
assert!(&bar.is_file());
|
|
|
|
let bar2: std::path::PathBuf = std::env::var("CARGO_BIN_FILE_BAR_bar").expect("CARGO_BIN_FILE_BAR_bar").into();
|
|
println!("{}", bar2.display());
|
|
assert_eq!(bar, bar2);
|
|
}
|
|
"#)
|
|
.file(
|
|
"bar/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "bar"
|
|
version = "0.5.0"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[lib]
|
|
crate-type = ["staticlib", "cdylib"]
|
|
"#,
|
|
)
|
|
// compilation target is native for build scripts unless overridden
|
|
.file("bar/src/bin/bar.rs", &format!(r#"fn main() {{ assert_eq!(std::env::var("TARGET").unwrap(), "{}"); }}"#, cross_compile::native()))
|
|
.file("bar/src/bin/baz.rs", "fn main() {}")
|
|
.file("bar/src/lib.rs", "")
|
|
.build();
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(
|
|
str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] foo v0.0.0 ([ROOT]/foo)
|
|
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]]
|
|
.unordered(),
|
|
)
|
|
.run();
|
|
|
|
let build_script_output = build_script_output_string(&p, "foo");
|
|
// we need the binary directory for this artifact along with all binary paths
|
|
if cfg!(target_env = "msvc") {
|
|
assert_e2e().eq(
|
|
&build_script_output,
|
|
str![[r#"
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-[HASH]/bin/baz[EXE]
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-[HASH]/staticlib/bar-[HASH].lib
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-[HASH]/cdylib/bar.dll
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-[HASH]/bin
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-[HASH]/bin/bar[EXE]
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-[HASH]/bin/bar[EXE]
|
|
|
|
"#]],
|
|
);
|
|
} else {
|
|
assert_e2e().eq(
|
|
&build_script_output,
|
|
str![[r#"
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-[HASH]/bin/baz-[HASH][EXE]
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-[HASH]/staticlib/libbar-[HASH].a
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-[HASH]/cdylib/[..]bar.[..]
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-[HASH]/bin
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-[HASH]/bin/bar-[HASH][EXE]
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-[HASH]/bin/bar-[HASH][EXE]
|
|
|
|
"#]],
|
|
);
|
|
}
|
|
|
|
assert!(
|
|
!p.bin("bar").is_file(),
|
|
"artifacts are located in their own directory, exclusively, and won't be lifted up"
|
|
);
|
|
assert!(!p.bin("baz").is_file(),);
|
|
assert_artifact_executable_output(&p, "debug", "bar", "bar");
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn build_script_with_bin_artifact_and_lib_false() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[build-dependencies]
|
|
bar = { path = "bar/", artifact = "bin" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
"build.rs",
|
|
r#"
|
|
fn main() {
|
|
bar::doit()
|
|
}
|
|
"#,
|
|
)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() { bar::doit(); }")
|
|
.file(
|
|
"bar/src/lib.rs",
|
|
r#"
|
|
pub fn doit() {
|
|
panic!("sentinel");
|
|
}
|
|
"#,
|
|
)
|
|
.build();
|
|
|
|
#[allow(deprecated)]
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_status(101)
|
|
.with_stderr_does_not_contain("[..]sentinel[..]")
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn lib_with_bin_artifact_and_lib_false() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", artifact = "bin" }
|
|
"#,
|
|
)
|
|
.file(
|
|
"src/lib.rs",
|
|
r#"
|
|
pub fn foo() {
|
|
bar::doit()
|
|
}"#,
|
|
)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() { bar::doit(); }")
|
|
.file(
|
|
"bar/src/lib.rs",
|
|
r#"
|
|
pub fn doit() {
|
|
panic!("sentinel");
|
|
}
|
|
"#,
|
|
)
|
|
.build();
|
|
|
|
#[allow(deprecated)]
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_status(101)
|
|
.with_stderr_does_not_contain("[..]sentinel[..]")
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn build_script_with_selected_dashed_bin_artifact_and_lib_true() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[build-dependencies]
|
|
bar-baz = { path = "bar/", artifact = "bin:baz-suffix", lib = true }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("build.rs", r#"
|
|
fn main() {
|
|
bar_baz::print_env()
|
|
}
|
|
"#)
|
|
.file(
|
|
"bar/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "bar-baz"
|
|
version = "0.5.0"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[[bin]]
|
|
name = "bar"
|
|
|
|
[[bin]]
|
|
name = "baz-suffix"
|
|
"#,
|
|
)
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.file("bar/src/lib.rs", r#"
|
|
pub fn print_env() {
|
|
let dir: std::path::PathBuf = std::env::var("CARGO_BIN_DIR_BAR_BAZ").expect("CARGO_BIN_DIR_BAR_BAZ").into();
|
|
let bin: std::path::PathBuf = std::env::var("CARGO_BIN_FILE_BAR_BAZ_baz-suffix").expect("CARGO_BIN_FILE_BAR_BAZ_baz-suffix").into();
|
|
println!("{}", dir.display());
|
|
println!("{}", bin.display());
|
|
assert!(dir.is_dir());
|
|
assert!(&bin.is_file());
|
|
assert!(std::env::var("CARGO_BIN_FILE_BAR_BAZ").is_err(), "CARGO_BIN_FILE_BAR_BAZ isn't set due to name mismatch");
|
|
assert!(std::env::var("CARGO_BIN_FILE_BAR_BAZ_bar").is_err(), "CARGO_BIN_FILE_BAR_BAZ_bar isn't set as binary isn't selected");
|
|
}
|
|
"#)
|
|
.build();
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] bar-baz v0.5.0 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.0.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
|
|
let build_script_output = build_script_output_string(&p, "foo");
|
|
// we need the binary directory for this artifact and the binary itself
|
|
if cfg!(target_env = "msvc") {
|
|
assert_e2e().eq(
|
|
&build_script_output,
|
|
str![[r#"
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-baz-[HASH]/bin
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-baz-[HASH]/bin/baz_suffix[EXE]
|
|
|
|
"#]],
|
|
);
|
|
} else {
|
|
assert_e2e().eq(
|
|
&build_script_output,
|
|
str![[r#"
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-baz-[HASH]/bin
|
|
[ROOT]/foo/target/debug/deps/artifact/bar-baz-[HASH]/bin/baz_suffix-[HASH][EXE]
|
|
|
|
"#]],
|
|
);
|
|
}
|
|
|
|
assert!(
|
|
!p.bin("bar").is_file(),
|
|
"artifacts are located in their own directory, exclusively, and won't be lifted up"
|
|
);
|
|
assert_artifact_executable_output(&p, "debug", "bar", "baz_suffix");
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn lib_with_selected_dashed_bin_artifact_and_lib_true() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar-baz = { path = "bar/", artifact = ["bin:baz-suffix", "staticlib", "cdylib"], lib = true }
|
|
"#,
|
|
)
|
|
.file(
|
|
"src/lib.rs",
|
|
r#"
|
|
pub fn foo() {
|
|
bar_baz::exists();
|
|
|
|
env!("CARGO_BIN_DIR_BAR_BAZ");
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR_BAZ_baz-suffix"));
|
|
let _b = include_bytes!(env!("CARGO_STATICLIB_FILE_BAR_BAZ"));
|
|
let _b = include_bytes!(env!("CARGO_STATICLIB_FILE_BAR_BAZ_bar-baz"));
|
|
let _b = include_bytes!(env!("CARGO_STATICLIB_FILE_BAR_BAZ_bar_baz"));
|
|
let _b = include_bytes!(env!("CARGO_CDYLIB_FILE_BAR_BAZ"));
|
|
let _b = include_bytes!(env!("CARGO_CDYLIB_FILE_BAR_BAZ_bar-baz"));
|
|
let _b = include_bytes!(env!("CARGO_CDYLIB_FILE_BAR_BAZ_bar_baz"));
|
|
}
|
|
"#,
|
|
)
|
|
.file(
|
|
"bar/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "bar-baz"
|
|
version = "0.5.0"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[lib]
|
|
crate-type = ["rlib", "staticlib", "cdylib"]
|
|
|
|
[[bin]]
|
|
name = "bar"
|
|
|
|
[[bin]]
|
|
name = "baz-suffix"
|
|
"#,
|
|
)
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.file("bar/src/lib.rs", "pub fn exists() {}")
|
|
.build();
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] bar-baz v0.5.0 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.0.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
|
|
assert!(
|
|
!p.bin("bar").is_file(),
|
|
"artifacts are located in their own directory, exclusively, and won't be lifted up"
|
|
);
|
|
assert_artifact_executable_output(&p, "debug", "bar", "baz_suffix");
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn allow_artifact_and_no_artifact_dep_to_same_package_within_different_dep_categories() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", artifact = "bin" }
|
|
|
|
[dev-dependencies]
|
|
bar = { path = "bar/", package = "bar" }
|
|
"#,
|
|
)
|
|
.file(
|
|
"src/lib.rs",
|
|
r#"
|
|
#[cfg(test)] extern crate bar;
|
|
pub fn foo() {
|
|
env!("CARGO_BIN_DIR_BAR");
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR"));
|
|
}"#,
|
|
)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.file("bar/src/lib.rs", "")
|
|
.build();
|
|
p.cargo("test -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.0.0 ([ROOT]/foo)
|
|
[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
[RUNNING] unittests src/lib.rs (target/debug/deps/foo-[HASH][EXE])
|
|
[DOCTEST] foo
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn normal_build_deps_are_picked_up_in_presence_of_an_artifact_build_dep_to_the_same_package() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar", artifact = "bin:bar" }
|
|
|
|
[build-dependencies]
|
|
bar = { path = "bar" }
|
|
"#,
|
|
)
|
|
.file("build.rs", "fn main() { bar::f(); }")
|
|
.file(
|
|
"src/lib.rs",
|
|
r#"
|
|
pub fn foo() {
|
|
env!("CARGO_BIN_DIR_BAR");
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR"));
|
|
}"#,
|
|
)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.file("bar/src/lib.rs", "pub fn f() {}")
|
|
.build();
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn disallow_using_example_binaries_as_artifacts() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", artifact = "bin:one-example" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.file("bar/examples/one-example.rs", "fn main() {}")
|
|
.build();
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_status(101)
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[ERROR] dependency `bar` in package `foo` requires a `bin:one-example` artifact to be present.
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
/// From RFC 3028
|
|
///
|
|
/// > You may also specify separate dependencies with different artifact values, as well as
|
|
/// dependencies on the same crate without artifact specified; for instance, you may have a
|
|
/// build dependency on the binary of a crate and a normal dependency on the Rust library of the same crate.
|
|
#[cargo_test]
|
|
fn allow_artifact_and_non_artifact_dependency_to_same_crate() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[build-dependencies]
|
|
bar = { path = "bar/", artifact = "bin" }
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", r#"
|
|
pub fn foo() {
|
|
bar::doit();
|
|
assert!(option_env!("CARGO_BIN_FILE_BAR").is_none());
|
|
}"#)
|
|
.file(
|
|
"build.rs",
|
|
r#"
|
|
fn main() {
|
|
assert!(option_env!("CARGO_BIN_FILE_BAR").is_none(), "no environment variables at build time");
|
|
std::process::Command::new(std::env::var("CARGO_BIN_FILE_BAR").expect("BAR present")).status().unwrap();
|
|
}"#,
|
|
)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.file("bar/src/lib.rs", "pub fn doit() {}")
|
|
.build();
|
|
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.0.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn build_script_deps_adopt_specified_target_unconditionally() {
|
|
if cross_compile::disabled() {
|
|
return;
|
|
}
|
|
|
|
let target = cross_compile::alternate();
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[build-dependencies.bar]
|
|
path = "bar/"
|
|
artifact = "bin"
|
|
target = "{}"
|
|
"#,
|
|
target
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("build.rs", r#"
|
|
fn main() {
|
|
let bar: std::path::PathBuf = std::env::var("CARGO_BIN_FILE_BAR").expect("CARGO_BIN_FILE_BAR").into();
|
|
assert!(&bar.is_file());
|
|
}"#)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.file("bar/src/lib.rs", "pub fn doit() {}")
|
|
.build();
|
|
|
|
#[allow(deprecated)]
|
|
p.cargo("check -v -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_does_not_contain(format!(
|
|
"[RUNNING] `rustc --crate-name build_script_build --edition=2015 build.rs [..]--target {} [..]",
|
|
target
|
|
))
|
|
.with_stderr_contains("[RUNNING] `rustc --crate-name build_script_build --edition=2015 build.rs [..]")
|
|
.with_stderr_contains(format!(
|
|
"[RUNNING] `rustc --crate-name bar --edition=2015 bar/src/lib.rs [..]--target {} [..]",
|
|
target
|
|
))
|
|
.with_stderr_contains(format!(
|
|
"[RUNNING] `rustc --crate-name bar --edition=2015 bar/src/main.rs [..]--target {} [..]",
|
|
target
|
|
))
|
|
.with_stderr_does_not_contain(format!(
|
|
"[RUNNING] `rustc --crate-name foo [..]--target {} [..]",
|
|
target
|
|
))
|
|
.with_stderr_contains("[RUNNING] `rustc --crate-name foo [..]")
|
|
.run();
|
|
}
|
|
|
|
/// inverse RFC-3176
|
|
#[cargo_test]
|
|
fn build_script_deps_adopt_do_not_allow_multiple_targets_under_different_name_and_same_version() {
|
|
if cross_compile::disabled() {
|
|
return;
|
|
}
|
|
|
|
let alternate = cross_compile::alternate();
|
|
let native = cross_compile::native();
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[build-dependencies.bar]
|
|
path = "bar/"
|
|
artifact = "bin"
|
|
target = "{}"
|
|
|
|
[build-dependencies.bar-native]
|
|
package = "bar"
|
|
path = "bar/"
|
|
artifact = "bin"
|
|
target = "{}"
|
|
"#,
|
|
alternate,
|
|
native
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("build.rs", r#"
|
|
fn main() {
|
|
let bar: std::path::PathBuf = std::env::var("CARGO_BIN_FILE_BAR").expect("CARGO_BIN_FILE_BAR").into();
|
|
assert!(&bar.is_file());
|
|
let bar_native: std::path::PathBuf = std::env::var("CARGO_BIN_FILE_BAR_NATIVE_bar").expect("CARGO_BIN_FILE_BAR_NATIVE_bar").into();
|
|
assert!(&bar_native.is_file());
|
|
assert_ne!(bar_native, bar, "should build different binaries due to different targets");
|
|
}"#)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.build();
|
|
|
|
p.cargo("check -v -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_status(101)
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[ERROR] the crate `foo v0.0.0 ([ROOT]/foo)` depends on crate `bar v0.5.0 ([ROOT]/foo/bar)` multiple times with different names
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn non_build_script_deps_adopt_specified_target_unconditionally() {
|
|
if cross_compile::disabled() {
|
|
return;
|
|
}
|
|
|
|
let target = cross_compile::alternate();
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies.bar]
|
|
path = "bar/"
|
|
artifact = "bin"
|
|
target = "{}"
|
|
"#,
|
|
target
|
|
),
|
|
)
|
|
.file(
|
|
"src/lib.rs",
|
|
r#"pub fn foo() { let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR")); }"#,
|
|
)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.file("bar/src/lib.rs", "pub fn doit() {}")
|
|
.build();
|
|
|
|
#[allow(deprecated)]
|
|
p.cargo("check -v -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_contains(format!(
|
|
"[RUNNING] `rustc --crate-name bar --edition=2015 bar/src/lib.rs [..]--target {} [..]",
|
|
target
|
|
))
|
|
.with_stderr_contains(format!(
|
|
"[RUNNING] `rustc --crate-name bar --edition=2015 bar/src/main.rs [..]--target {} [..]",
|
|
target
|
|
))
|
|
.with_stderr_does_not_contain(format!(
|
|
"[RUNNING] `rustc --crate-name foo [..]--target {} [..]",
|
|
target
|
|
))
|
|
.with_stderr_contains("[RUNNING] `rustc --crate-name foo [..]")
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn no_cross_doctests_works_with_artifacts() {
|
|
if cross_compile::disabled() {
|
|
return;
|
|
}
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", artifact = "bin", lib = true }
|
|
"#,
|
|
)
|
|
.file(
|
|
"src/lib.rs",
|
|
r#"
|
|
//! ```
|
|
//! env!("CARGO_BIN_DIR_BAR");
|
|
//! let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR"));
|
|
//! ```
|
|
pub fn foo() {
|
|
env!("CARGO_BIN_DIR_BAR");
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR"));
|
|
}
|
|
"#,
|
|
)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/lib.rs", r#"pub extern "C" fn c() {}"#)
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.build();
|
|
|
|
let target = rustc_host();
|
|
p.cargo("test -Z bindeps --target")
|
|
.arg(&target)
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.0.1 ([ROOT]/foo)
|
|
[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
[RUNNING] unittests src/lib.rs (target/[HOST_TARGET]/debug/deps/foo-[HASH][EXE])
|
|
[DOCTEST] foo
|
|
|
|
"#]])
|
|
.run();
|
|
|
|
println!("c");
|
|
let target = cross_compile::alternate();
|
|
|
|
// This will build the library, but does not build or run doc tests.
|
|
// This should probably be a warning or error.
|
|
p.cargo("test -Z bindeps -v --doc --target")
|
|
.arg(&target)
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[RUNNING] `rustc --crate-name bar --edition=2015 bar/src/lib.rs [..]--target [ALT_TARGET] [..]
|
|
[RUNNING] `rustc --crate-name bar --edition=2015 bar/src/main.rs [..]--target [ALT_TARGET] [..]
|
|
[COMPILING] foo v0.0.1 ([ROOT]/foo)
|
|
[RUNNING] `rustc --crate-name foo [..]`
|
|
[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
[NOTE] skipping doctests for foo v0.0.1 ([ROOT]/foo) (lib), cross-compilation doctests are not yet supported
|
|
See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#doctest-xcompile for more information.
|
|
|
|
"#]])
|
|
.run();
|
|
|
|
if !cross_compile::can_run_on_host() {
|
|
return;
|
|
}
|
|
|
|
// This tests the library, but does not run the doc tests.
|
|
p.cargo("test -Z bindeps -v --target")
|
|
.arg(&target)
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[FRESH] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.0.1 ([ROOT]/foo)
|
|
[RUNNING] `rustc --crate-name foo [..]--test[..]
|
|
[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
[RUNNING] `[ROOT]/foo/target/[ALT_TARGET]/debug/deps/foo-[HASH][EXE]`
|
|
[NOTE] skipping doctests for foo v0.0.1 ([ROOT]/foo) (lib), cross-compilation doctests are not yet supported
|
|
See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#doctest-xcompile for more information.
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn build_script_deps_adopts_target_platform_if_target_equals_target() {
|
|
if cross_compile::disabled() {
|
|
return;
|
|
}
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[build-dependencies]
|
|
bar = { path = "bar/", artifact = "bin", target = "target" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("build.rs", r#"
|
|
fn main() {
|
|
let bar: std::path::PathBuf = std::env::var("CARGO_BIN_FILE_BAR").expect("CARGO_BIN_FILE_BAR").into();
|
|
assert!(&bar.is_file());
|
|
}"#)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.file("bar/src/lib.rs", "pub fn doit() {}")
|
|
.build();
|
|
|
|
let alternate_target = cross_compile::alternate();
|
|
#[allow(deprecated)]
|
|
p.cargo("check -v -Z bindeps --target")
|
|
.arg(alternate_target)
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_does_not_contain(format!(
|
|
"[RUNNING] `rustc --crate-name build_script_build --edition=2015 build.rs [..]--target {} [..]",
|
|
alternate_target
|
|
))
|
|
.with_stderr_contains("[RUNNING] `rustc --crate-name build_script_build --edition=2015 build.rs [..]")
|
|
.with_stderr_contains(format!(
|
|
"[RUNNING] `rustc --crate-name bar --edition=2015 bar/src/lib.rs [..]--target {} [..]",
|
|
alternate_target
|
|
))
|
|
.with_stderr_contains(format!(
|
|
"[RUNNING] `rustc --crate-name bar --edition=2015 bar/src/main.rs [..]--target {} [..]",
|
|
alternate_target
|
|
))
|
|
.with_stderr_contains(format!(
|
|
"[RUNNING] `rustc --crate-name foo [..]--target {} [..]",
|
|
alternate_target
|
|
))
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
// TODO(ST): rename bar (dependency) to something else and un-ignore this with RFC-3176
|
|
#[cfg_attr(target_env = "msvc", ignore = "msvc not working")]
|
|
fn profile_override_basic() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[build-dependencies]
|
|
bar = { path = "bar", artifact = "bin" }
|
|
|
|
[dependencies]
|
|
bar = { path = "bar", artifact = "bin" }
|
|
|
|
[profile.dev.build-override]
|
|
opt-level = 1
|
|
|
|
[profile.dev]
|
|
opt-level = 3
|
|
"#,
|
|
)
|
|
.file("build.rs", "fn main() {}")
|
|
.file("src/lib.rs", "")
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.file("bar/src/lib.rs", "pub fn bar() {}")
|
|
.build();
|
|
|
|
p.cargo("build -v -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(
|
|
str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.0.1 ([ROOT]/foo)
|
|
[RUNNING] `rustc --crate-name build_script_build [..] -C opt-level=1 [..]`
|
|
[RUNNING] `rustc --crate-name bar --edition=2015 bar/src/main.rs [..] -C opt-level=3 [..]`
|
|
[RUNNING] `rustc --crate-name bar --edition=2015 bar/src/main.rs [..] -C opt-level=1 [..]`
|
|
[RUNNING] `rustc --crate-name bar --edition=2015 bar/src/lib.rs [..] -C opt-level=1 [..]`
|
|
[RUNNING] `rustc --crate-name bar --edition=2015 bar/src/lib.rs [..] -C opt-level=3 [..]`
|
|
[RUNNING] `rustc --crate-name foo [..] -C opt-level=3 [..]`
|
|
[RUNNING] `[ROOT]/foo/target/debug/build/foo-[HASH]/build-script-build`
|
|
[FINISHED] `dev` profile [optimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]]
|
|
.unordered(),
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn dependencies_of_dependencies_work_in_artifacts() {
|
|
Package::new("baz", "1.0.0")
|
|
.file("src/lib.rs", "pub fn baz() {}")
|
|
.publish();
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[build-dependencies]
|
|
bar = { path = "bar/", artifact = "bin" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
"build.rs",
|
|
r#"
|
|
fn main() {
|
|
std::process::Command::new(std::env::var("CARGO_BIN_FILE_BAR").expect("BAR present")).status().unwrap();
|
|
}
|
|
"#,
|
|
)
|
|
.file(
|
|
"bar/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "bar"
|
|
version = "0.5.0"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[dependencies]
|
|
baz = "1.0.0"
|
|
"#,
|
|
)
|
|
.file("bar/src/lib.rs", r#"pub fn bar() {baz::baz()}"#)
|
|
.file("bar/src/main.rs", r#"fn main() {bar::bar()}"#)
|
|
.build();
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.run();
|
|
|
|
// cargo tree sees artifacts as the dependency kind they are in and doesn't do anything special with it.
|
|
p.cargo("tree -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stdout_data(str![[r#"
|
|
foo v0.0.0 ([ROOT]/foo)
|
|
[build-dependencies]
|
|
└── bar v0.5.0 ([ROOT]/foo/bar)
|
|
└── baz v1.0.0
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn artifact_dep_target_specified() {
|
|
if cross_compile::disabled() {
|
|
return;
|
|
}
|
|
let target = cross_compile::alternate();
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
authors = []
|
|
resolver = "2"
|
|
edition = "2015"
|
|
|
|
[dependencies]
|
|
bindep = { path = "bindep", artifact = "bin", target = "$TARGET" }
|
|
"#
|
|
.replace("$TARGET", target),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("bindep/Cargo.toml", &basic_manifest("bindep", "0.0.0"))
|
|
.file("bindep/src/main.rs", "fn main() {}")
|
|
.build();
|
|
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] bindep v0.0.0 ([ROOT]/foo/bindep)
|
|
[CHECKING] foo v0.0.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.with_status(0)
|
|
.run();
|
|
|
|
// TODO: This command currently fails due to a bug in cargo but it should be fixed so that it succeeds in the future.
|
|
p.cargo("tree -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stdout_data(str![[""]])
|
|
.with_stderr_data(str![[r#"
|
|
thread 'main' panicked at src/cargo/[..]:
|
|
activated_features for invalid package: features did not find PackageId { name: "bindep", version: "0.0.0", source: "[..]" } NormalOrDev
|
|
[NOTE] run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
|
|
|
"#]])
|
|
.with_status(101)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn targets_are_picked_up_from_non_workspace_artifact_deps() {
|
|
if cross_compile::disabled() {
|
|
return;
|
|
}
|
|
let target = cross_compile::alternate();
|
|
Package::new("artifact", "1.0.0")
|
|
.file("src/main.rs", r#"fn main() {}"#)
|
|
.file("src/lib.rs", r#"pub fn lib() {}"#)
|
|
.publish();
|
|
|
|
let mut dep = registry::Dependency::new("artifact", "1.0.0");
|
|
Package::new("uses-artifact", "1.0.0")
|
|
.schema_version(3)
|
|
.file(
|
|
"src/lib.rs",
|
|
r#"pub fn uses_artifact() { let _b = include_bytes!(env!("CARGO_BIN_FILE_ARTIFACT")); }"#,
|
|
)
|
|
.add_dep(dep.artifact("bin", Some(target.to_string())))
|
|
.publish();
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[dependencies]
|
|
uses-artifact = { version = "1.0.0" }
|
|
"#,
|
|
)
|
|
.file(
|
|
"src/lib.rs",
|
|
r#"pub fn foo() { uses_artifact::uses_artifact(); }"#,
|
|
)
|
|
.build();
|
|
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn index_version_filtering() {
|
|
if cross_compile::disabled() {
|
|
return;
|
|
}
|
|
let target = cross_compile::alternate();
|
|
|
|
Package::new("artifact", "1.0.0")
|
|
.file("src/main.rs", r#"fn main() {}"#)
|
|
.file("src/lib.rs", r#"pub fn lib() {}"#)
|
|
.publish();
|
|
|
|
let mut dep = registry::Dependency::new("artifact", "1.0.0");
|
|
|
|
Package::new("bar", "1.0.0").publish();
|
|
Package::new("bar", "1.0.1")
|
|
.schema_version(3)
|
|
.add_dep(dep.artifact("bin", Some(target.to_string())))
|
|
.publish();
|
|
|
|
// Verify that without `-Zbindeps` that it does not use 1.0.1.
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
|
|
[dependencies]
|
|
bar = "1.0"
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.build();
|
|
|
|
p.cargo("tree")
|
|
.with_stdout_data(str![[r#"
|
|
foo v0.1.0 ([ROOT]/foo)
|
|
└── bar v1.0.0
|
|
|
|
"#]])
|
|
.run();
|
|
|
|
// And with -Zbindeps it can use 1.0.1.
|
|
p.cargo("update -Zbindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[UPDATING] `dummy-registry` index
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[ADDING] artifact v1.0.0
|
|
[UPDATING] bar v1.0.0 -> v1.0.1
|
|
|
|
"#]])
|
|
.run();
|
|
|
|
// And without -Zbindeps, now that 1.0.1 is in Cargo.lock, it should fail.
|
|
p.cargo("check")
|
|
.with_status(101)
|
|
.with_stderr_data(str![[r#"
|
|
[UPDATING] `dummy-registry` index
|
|
[ERROR] failed to select a version for the requirement `bar = "^1.0"` (locked to 1.0.1)
|
|
candidate versions found which didn't match: 1.0.0
|
|
location searched: `dummy-registry` index (which is replacing registry `crates-io`)
|
|
required by package `foo v0.1.0 ([ROOT]/foo)`
|
|
perhaps a crate was updated and forgotten to be re-vendored?
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
// FIXME: `download_accessible` should work properly for artifact dependencies
|
|
#[cargo_test]
|
|
#[ignore = "broken, needs download_accessible fix"]
|
|
fn proc_macro_in_artifact_dep() {
|
|
// Forcing FeatureResolver to check a proc-macro for a dependency behind a
|
|
// target dependency.
|
|
if cross_compile::disabled() {
|
|
return;
|
|
}
|
|
Package::new("pm", "1.0.0")
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "pm"
|
|
version = "1.0.0"
|
|
edition = "2015"
|
|
|
|
[lib]
|
|
proc-macro = true
|
|
|
|
"#,
|
|
)
|
|
.publish();
|
|
let alternate = cross_compile::alternate();
|
|
Package::new("bin-uses-pm", "1.0.0")
|
|
.target_dep("pm", "1.0", alternate)
|
|
.file("src/main.rs", "fn main() {}")
|
|
.publish();
|
|
// Simulate a network error downloading the proc-macro.
|
|
std::fs::remove_file(cargo_test_support::paths::root().join("dl/pm/1.0.0/download")).unwrap();
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
|
|
[dependencies]
|
|
bin-uses-pm = {{ version = "1.0", artifact = "bin", target = "{alternate}"}}
|
|
"#
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.build();
|
|
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#""#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn allow_dep_renames_with_multiple_versions() {
|
|
Package::new("bar", "1.0.0")
|
|
.file("src/main.rs", r#"fn main() {println!("1.0.0")}"#)
|
|
.publish();
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[build-dependencies]
|
|
bar = { path = "bar/", artifact = "bin" }
|
|
bar_stable = { package = "bar", version = "1.0.0", artifact = "bin" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
"build.rs",
|
|
r#"
|
|
fn main() {
|
|
std::process::Command::new(std::env::var("CARGO_BIN_FILE_BAR").expect("BAR present")).status().unwrap();
|
|
std::process::Command::new(std::env::var("CARGO_BIN_FILE_BAR_STABLE_bar").expect("BAR STABLE present")).status().unwrap();
|
|
}
|
|
"#,
|
|
)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", r#"fn main() {println!("0.5.0")}"#)
|
|
.build();
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(
|
|
str![[r#"
|
|
[UPDATING] `dummy-registry` index
|
|
[LOCKING] 3 packages to latest compatible versions
|
|
[DOWNLOADING] crates ...
|
|
[DOWNLOADED] bar v1.0.0 (registry `dummy-registry`)
|
|
[COMPILING] bar v1.0.0
|
|
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.0.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]]
|
|
.unordered(),
|
|
)
|
|
.run();
|
|
let build_script_output = build_script_output_string(&p, "foo");
|
|
assert_e2e().eq(
|
|
&build_script_output,
|
|
str![[r#"
|
|
0.5.0
|
|
1.0.0
|
|
|
|
"#]],
|
|
);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn allow_artifact_and_non_artifact_dependency_to_same_crate_if_these_are_not_the_same_dep_kind() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[build-dependencies]
|
|
bar = { path = "bar/", artifact = "bin", lib = false }
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", r#"
|
|
pub fn foo() {
|
|
bar::doit();
|
|
assert!(option_env!("CARGO_BIN_FILE_BAR").is_none());
|
|
}"#)
|
|
.file(
|
|
"build.rs",
|
|
r#"fn main() {
|
|
println!("{}", std::env::var("CARGO_BIN_FILE_BAR").expect("CARGO_BIN_FILE_BAR"));
|
|
println!("{}", std::env::var("CARGO_BIN_FILE_BAR_bar").expect("CARGO_BIN_FILE_BAR_bar"));
|
|
}"#,
|
|
)
|
|
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
|
|
.file("bar/src/lib.rs", "pub fn doit() {}")
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.build();
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] bar v0.0.1 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.0.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn prevent_no_lib_warning_with_artifact_dependencies() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", artifact = "bin" }
|
|
"#,
|
|
)
|
|
.file(
|
|
"src/lib.rs",
|
|
r#"pub fn foo() { let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR")); }"#,
|
|
)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.build();
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[CHECKING] foo v0.0.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn show_no_lib_warning_with_artifact_dependencies_that_have_no_lib_but_lib_true() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[build-dependencies]
|
|
bar = { path = "bar/", artifact = "bin" }
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", artifact = "bin", lib = true }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("src/build.rs", "fn main() {}")
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.build();
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[WARNING] foo v0.0.0 ([ROOT]/foo) ignoring invalid dependency `bar` which is missing a lib target
|
|
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[CHECKING] foo v0.0.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn resolver_2_build_dep_without_lib() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
authors = []
|
|
edition = "2021"
|
|
|
|
[build-dependencies]
|
|
bar = { path = "bar/", artifact = "bin" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("build.rs", r#"
|
|
fn main() {
|
|
let bar: std::path::PathBuf = std::env::var("CARGO_BIN_FILE_BAR").expect("CARGO_BIN_FILE_BAR").into();
|
|
assert!(&bar.is_file());
|
|
}"#)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.build();
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn check_missing_crate_type_in_package_fails() {
|
|
for crate_type in &["cdylib", "staticlib", "bin"] {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[dependencies]
|
|
bar = {{ path = "bar/", artifact = "{}" }}
|
|
"#,
|
|
crate_type
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1")) //no bin, just rlib
|
|
.file("bar/src/lib.rs", "")
|
|
.build();
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_status(101)
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[ERROR] dependency `bar` in package `foo` requires a [..] artifact to be present.
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn check_target_equals_target_in_non_build_dependency_errors() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", artifact = "bin", target = "target" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.build();
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_status(101)
|
|
.with_stderr_data(str![[r#"
|
|
[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml`
|
|
|
|
Caused by:
|
|
`target = "target"` in normal- or dev-dependencies has no effect (bar)
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn env_vars_and_build_products_for_various_build_targets() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[lib]
|
|
doctest = true
|
|
|
|
[build-dependencies]
|
|
bar = { path = "bar/", artifact = ["cdylib", "staticlib"] }
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", artifact = "bin", lib = true }
|
|
|
|
[dev-dependencies]
|
|
bar = { path = "bar/", artifact = "bin:baz" }
|
|
"#,
|
|
)
|
|
.file("build.rs", r#"
|
|
fn main() {
|
|
let file: std::path::PathBuf = std::env::var("CARGO_CDYLIB_FILE_BAR").expect("CARGO_CDYLIB_FILE_BAR").into();
|
|
assert!(&file.is_file());
|
|
|
|
let file: std::path::PathBuf = std::env::var("CARGO_STATICLIB_FILE_BAR").expect("CARGO_STATICLIB_FILE_BAR").into();
|
|
assert!(&file.is_file());
|
|
|
|
assert!(std::env::var("CARGO_BIN_FILE_BAR").is_err());
|
|
assert!(std::env::var("CARGO_BIN_FILE_BAR_baz").is_err());
|
|
}
|
|
"#)
|
|
.file(
|
|
"src/lib.rs",
|
|
r#"
|
|
//! ```
|
|
//! bar::c();
|
|
//! env!("CARGO_BIN_DIR_BAR");
|
|
//! let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR"));
|
|
//! let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR_bar"));
|
|
//! let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR_baz"));
|
|
//! assert!(option_env!("CARGO_STATICLIB_FILE_BAR").is_none());
|
|
//! assert!(option_env!("CARGO_CDYLIB_FILE_BAR").is_none());
|
|
//! ```
|
|
pub fn foo() {
|
|
bar::c();
|
|
env!("CARGO_BIN_DIR_BAR");
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR"));
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR_bar"));
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR_baz"));
|
|
assert!(option_env!("CARGO_STATICLIB_FILE_BAR").is_none());
|
|
assert!(option_env!("CARGO_CDYLIB_FILE_BAR").is_none());
|
|
}
|
|
|
|
#[cfg(test)]
|
|
#[test]
|
|
fn env_unit() {
|
|
env!("CARGO_BIN_DIR_BAR");
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR"));
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR_bar"));
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR_baz"));
|
|
assert!(option_env!("CARGO_STATICLIB_FILE_BAR").is_none());
|
|
assert!(option_env!("CARGO_CDYLIB_FILE_BAR").is_none());
|
|
}
|
|
"#,
|
|
)
|
|
.file(
|
|
"tests/main.rs",
|
|
r#"
|
|
#[test]
|
|
fn env_integration() {
|
|
env!("CARGO_BIN_DIR_BAR");
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR"));
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR_bar"));
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR_baz"));
|
|
}"#,
|
|
)
|
|
.file("build.rs", "fn main() {}")
|
|
.file(
|
|
"bar/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "bar"
|
|
version = "0.5.0"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[lib]
|
|
crate-type = ["staticlib", "cdylib", "rlib"]
|
|
|
|
[[bin]]
|
|
name = "bar"
|
|
|
|
[[bin]]
|
|
name = "baz"
|
|
"#,
|
|
)
|
|
.file("bar/src/lib.rs", r#"pub extern "C" fn c() {}"#)
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.build();
|
|
p.cargo("test -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.0.0 ([ROOT]/foo)
|
|
[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
[RUNNING] unittests src/lib.rs (target/debug/deps/foo-[HASH][EXE])
|
|
[RUNNING] tests/main.rs (target/debug/deps/main-[HASH][EXE])
|
|
[DOCTEST] foo
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn publish_artifact_dep() {
|
|
let registry = RegistryBuilder::new().http_api().http_index().build();
|
|
|
|
Package::new("bar", "1.0.0").publish();
|
|
Package::new("baz", "1.0.0").publish();
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
authors = []
|
|
license = "MIT"
|
|
description = "foo"
|
|
documentation = "foo"
|
|
homepage = "foo"
|
|
repository = "foo"
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar = { version = "1.0", artifact = "bin", lib = true }
|
|
|
|
[build-dependencies]
|
|
baz = { version = "1.0", artifact = ["bin:a", "cdylib", "staticlib"], target = "target" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.build();
|
|
|
|
p.cargo("publish -Z bindeps --no-verify")
|
|
.replace_crates_io(registry.index_url())
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[UPDATING] crates.io index
|
|
[PACKAGING] foo v0.1.0 ([ROOT]/foo)
|
|
[PACKAGED] 3 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
|
|
[UPLOADING] foo v0.1.0 ([ROOT]/foo)
|
|
[UPLOADED] foo v0.1.0 to registry `crates-io`
|
|
[NOTE] waiting for `foo v0.1.0` to be available at registry `crates-io`.
|
|
You may press ctrl-c to skip waiting; the crate should be available shortly.
|
|
[PUBLISHED] foo v0.1.0 at registry `crates-io`
|
|
|
|
"#]])
|
|
.run();
|
|
|
|
publish::validate_upload_with_contents(
|
|
r#"
|
|
{
|
|
"authors": [],
|
|
"badges": {},
|
|
"categories": [],
|
|
"deps": [{
|
|
"artifact": ["bin"],
|
|
"default_features": true,
|
|
"features": [],
|
|
"kind": "normal",
|
|
"lib": true,
|
|
"name": "bar",
|
|
"optional": false,
|
|
"target": null,
|
|
"version_req": "^1.0"
|
|
},
|
|
{
|
|
"artifact": [
|
|
"bin:a",
|
|
"cdylib",
|
|
"staticlib"
|
|
],
|
|
"bindep_target": "target",
|
|
"default_features": true,
|
|
"features": [],
|
|
"kind": "build",
|
|
"name": "baz",
|
|
"optional": false,
|
|
"target": null,
|
|
"version_req": "^1.0"
|
|
}
|
|
],
|
|
"description": "foo",
|
|
"documentation": "foo",
|
|
"features": {},
|
|
"homepage": "foo",
|
|
"keywords": [],
|
|
"license": "MIT",
|
|
"license_file": null,
|
|
"links": null,
|
|
"name": "foo",
|
|
"readme": null,
|
|
"readme_file": null,
|
|
"repository": "foo",
|
|
"rust_version": null,
|
|
"vers": "0.1.0"
|
|
}
|
|
"#,
|
|
"foo-0.1.0.crate",
|
|
&["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"],
|
|
&[(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"{}
|
|
[package]
|
|
edition = "2015"
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
authors = []
|
|
build = false
|
|
autobins = false
|
|
autoexamples = false
|
|
autotests = false
|
|
autobenches = false
|
|
description = "foo"
|
|
homepage = "foo"
|
|
documentation = "foo"
|
|
readme = false
|
|
license = "MIT"
|
|
repository = "foo"
|
|
resolver = "2"
|
|
|
|
[lib]
|
|
name = "foo"
|
|
path = "src/lib.rs"
|
|
|
|
[dependencies.bar]
|
|
version = "1.0"
|
|
artifact = ["bin"]
|
|
lib = true
|
|
|
|
[build-dependencies.baz]
|
|
version = "1.0"
|
|
artifact = [
|
|
"bin:a",
|
|
"cdylib",
|
|
"staticlib",
|
|
]
|
|
target = "target""#,
|
|
cargo::core::manifest::MANIFEST_PREAMBLE
|
|
),
|
|
)],
|
|
);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn doc_lib_true() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies.bar]
|
|
path = "bar"
|
|
artifact = "bin"
|
|
lib = true
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "extern crate bar; pub fn foo() {}")
|
|
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
|
|
.file("bar/src/lib.rs", "pub fn bar() {}")
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.build();
|
|
|
|
p.cargo("doc -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] bar v0.0.1 ([ROOT]/foo/bar)
|
|
[DOCUMENTING] bar v0.0.1 ([ROOT]/foo/bar)
|
|
[DOCUMENTING] foo v0.0.1 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
[GENERATED] [ROOT]/foo/target/doc/foo/index.html
|
|
|
|
"#]])
|
|
.run();
|
|
|
|
assert!(p.root().join("target/doc").is_dir());
|
|
assert!(p.root().join("target/doc/foo/index.html").is_file());
|
|
assert!(p.root().join("target/doc/bar/index.html").is_file());
|
|
|
|
// Verify that it emits rmeta for the bin and lib dependency.
|
|
assert_eq!(p.glob("target/debug/artifact/*.rlib").count(), 0);
|
|
assert_eq!(p.glob("target/debug/deps/libbar-*.rmeta").count(), 2);
|
|
|
|
p.cargo("doc -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
[GENERATED] [ROOT]/foo/target/doc/foo/index.html
|
|
|
|
"#]])
|
|
.run();
|
|
|
|
assert!(p.root().join("target/doc").is_dir());
|
|
assert!(p.root().join("target/doc/foo/index.html").is_file());
|
|
assert!(p.root().join("target/doc/bar/index.html").is_file());
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn rustdoc_works_on_libs_with_artifacts_and_lib_false() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
authors = []
|
|
resolver = "2"
|
|
|
|
[dependencies.bar]
|
|
path = "bar"
|
|
artifact = ["bin", "staticlib", "cdylib"]
|
|
"#,
|
|
)
|
|
.file(
|
|
"src/lib.rs",
|
|
r#"
|
|
pub fn foo() {
|
|
env!("CARGO_BIN_DIR_BAR");
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR"));
|
|
let _b = include_bytes!(env!("CARGO_CDYLIB_FILE_BAR"));
|
|
let _b = include_bytes!(env!("CARGO_CDYLIB_FILE_BAR_bar"));
|
|
let _b = include_bytes!(env!("CARGO_STATICLIB_FILE_BAR"));
|
|
let _b = include_bytes!(env!("CARGO_STATICLIB_FILE_BAR_bar"));
|
|
}"#,
|
|
)
|
|
.file(
|
|
"bar/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "bar"
|
|
version = "0.5.0"
|
|
edition = "2015"
|
|
authors = []
|
|
|
|
[lib]
|
|
crate-type = ["staticlib", "cdylib"]
|
|
"#,
|
|
)
|
|
.file("bar/src/lib.rs", "pub fn bar() {}")
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.build();
|
|
|
|
p.cargo("doc -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[DOCUMENTING] foo v0.0.1 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
[GENERATED] [ROOT]/foo/target/doc/foo/index.html
|
|
|
|
"#]])
|
|
.run();
|
|
|
|
assert!(p.root().join("target/doc").is_dir());
|
|
assert!(p.root().join("target/doc/foo/index.html").is_file());
|
|
assert!(
|
|
!p.root().join("target/doc/bar/index.html").is_file(),
|
|
"bar is not a lib dependency and thus remains undocumented"
|
|
);
|
|
}
|
|
|
|
fn assert_artifact_executable_output(
|
|
p: &Project,
|
|
target_name: &str,
|
|
dep_name: &str,
|
|
bin_name: &str,
|
|
) {
|
|
if cfg!(target_env = "msvc") {
|
|
assert_eq!(
|
|
p.glob(format!(
|
|
"target/{}/deps/artifact/{}-*/bin/{}{}",
|
|
target_name,
|
|
dep_name,
|
|
bin_name,
|
|
std::env::consts::EXE_SUFFIX
|
|
))
|
|
.count(),
|
|
1,
|
|
"artifacts are placed into their own output directory to not possibly clash"
|
|
);
|
|
} else {
|
|
assert_eq!(
|
|
p.glob(format!(
|
|
"target/{}/deps/artifact/{}-*/bin/{}-*{}",
|
|
target_name,
|
|
dep_name,
|
|
bin_name,
|
|
std::env::consts::EXE_SUFFIX
|
|
))
|
|
.filter_map(Result::ok)
|
|
.filter(|f| f.extension().map_or(true, |ext| ext != "o" && ext != "d"))
|
|
.count(),
|
|
1,
|
|
"artifacts are placed into their own output directory to not possibly clash"
|
|
);
|
|
}
|
|
}
|
|
|
|
fn build_script_output_string(p: &Project, package_name: &str) -> String {
|
|
let paths = p
|
|
.glob(format!("target/debug/build/{}-*/output", package_name))
|
|
.collect::<Result<Vec<_>, _>>()
|
|
.unwrap();
|
|
assert_eq!(paths.len(), 1);
|
|
std::fs::read_to_string(&paths[0]).unwrap()
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn build_script_features_for_shared_dependency() {
|
|
// When a build script is built and run, its features should match. Here:
|
|
//
|
|
// foo
|
|
// -> artifact on d1 with target
|
|
// -> common with features f1
|
|
//
|
|
// d1
|
|
// -> common with features f2
|
|
//
|
|
// common has features f1 and f2, with a build script.
|
|
//
|
|
// When common is built as a dependency of d1, it should have features
|
|
// `f2` (for the library and the build script).
|
|
//
|
|
// When common is built as a dependency of foo, it should have features
|
|
// `f1` (for the library and the build script).
|
|
if cross_compile::disabled() {
|
|
return;
|
|
}
|
|
let target = cross_compile::alternate();
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
d1 = { path = "d1", artifact = "bin", target = "$TARGET" }
|
|
common = { path = "common", features = ["f1"] }
|
|
"#
|
|
.replace("$TARGET", target),
|
|
)
|
|
.file(
|
|
"src/main.rs",
|
|
r#"
|
|
fn main() {
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_D1"));
|
|
common::f1();
|
|
}
|
|
"#,
|
|
)
|
|
.file(
|
|
"d1/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "d1"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
|
|
[dependencies]
|
|
common = { path = "../common", features = ["f2"] }
|
|
"#,
|
|
)
|
|
.file(
|
|
"d1/src/main.rs",
|
|
r#"fn main() {
|
|
common::f2();
|
|
}"#,
|
|
)
|
|
.file(
|
|
"common/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "common"
|
|
version = "0.0.1"
|
|
edition = "2015"
|
|
|
|
[features]
|
|
f1 = []
|
|
f2 = []
|
|
"#,
|
|
)
|
|
.file(
|
|
"common/src/lib.rs",
|
|
r#"
|
|
#[cfg(feature = "f1")]
|
|
pub fn f1() {}
|
|
|
|
#[cfg(feature = "f2")]
|
|
pub fn f2() {}
|
|
"#,
|
|
)
|
|
.file(
|
|
"common/build.rs",
|
|
&r#"
|
|
use std::env::var_os;
|
|
fn main() {
|
|
assert_eq!(var_os("CARGO_FEATURE_F1").is_some(), cfg!(feature="f1"));
|
|
assert_eq!(var_os("CARGO_FEATURE_F2").is_some(), cfg!(feature="f2"));
|
|
if std::env::var("TARGET").unwrap() == "$TARGET" {
|
|
assert!(var_os("CARGO_FEATURE_F1").is_none());
|
|
assert!(var_os("CARGO_FEATURE_F2").is_some());
|
|
} else {
|
|
assert!(var_os("CARGO_FEATURE_F1").is_some());
|
|
assert!(var_os("CARGO_FEATURE_F2").is_none());
|
|
}
|
|
}
|
|
"#
|
|
.replace("$TARGET", target),
|
|
)
|
|
.build();
|
|
|
|
p.cargo("build -Z bindeps -v")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn calc_bin_artifact_fingerprint() {
|
|
// See rust-lang/cargo#10527
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
resolver = "2"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/", artifact = "bin" }
|
|
"#,
|
|
)
|
|
.file(
|
|
"src/main.rs",
|
|
r#"
|
|
fn main() {
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_BAR"));
|
|
}
|
|
"#,
|
|
)
|
|
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
|
|
.file("bar/src/main.rs", r#"fn main() { println!("foo") }"#)
|
|
.build();
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[CHECKING] foo v0.1.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
|
|
p.change_file("bar/src/main.rs", r#"fn main() { println!("bar") }"#);
|
|
// Change in artifact bin dep `bar` propagates to `foo`, triggering recompile.
|
|
p.cargo("check -v -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[DIRTY] bar v0.5.0 ([ROOT]/foo/bar): the file `bar/src/main.rs` has changed ([..])
|
|
[COMPILING] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[RUNNING] `rustc --crate-name bar [..]`
|
|
[DIRTY] foo v0.1.0 ([ROOT]/foo): the dependency bar was rebuilt
|
|
[CHECKING] foo v0.1.0 ([ROOT]/foo)
|
|
[RUNNING] `rustc --crate-name foo [..]`
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
|
|
// All units are fresh. No recompile.
|
|
p.cargo("check -v -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[FRESH] bar v0.5.0 ([ROOT]/foo/bar)
|
|
[FRESH] foo v0.1.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn with_target_and_optional() {
|
|
// See rust-lang/cargo#10526
|
|
if cross_compile::disabled() {
|
|
return;
|
|
}
|
|
let target = cross_compile::alternate();
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
edition = "2021"
|
|
[dependencies]
|
|
d1 = { path = "d1", artifact = "bin", optional = true, target = "$TARGET" }
|
|
"#
|
|
.replace("$TARGET", target),
|
|
)
|
|
.file(
|
|
"src/main.rs",
|
|
r#"
|
|
fn main() {
|
|
let _b = include_bytes!(env!("CARGO_BIN_FILE_D1"));
|
|
}
|
|
"#,
|
|
)
|
|
.file(
|
|
"d1/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "d1"
|
|
version = "0.0.1"
|
|
edition = "2021"
|
|
"#,
|
|
)
|
|
.file("d1/src/main.rs", "fn main() {}")
|
|
.build();
|
|
|
|
p.cargo("check -Z bindeps -F d1 -v")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] d1 v0.0.1 ([ROOT]/foo/d1)
|
|
[RUNNING] `rustc --crate-name d1 [..]--crate-type bin[..]
|
|
[CHECKING] foo v0.0.1 ([ROOT]/foo)
|
|
[RUNNING] `rustc --crate-name foo [..]--cfg[..]d1[..]
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn with_assumed_host_target_and_optional_build_dep() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.1"
|
|
edition = "2021"
|
|
[build-dependencies]
|
|
d1 = { path = "d1", artifact = "bin", optional = true, target = "target" }
|
|
"#,
|
|
)
|
|
.file("src/main.rs", "fn main() {}")
|
|
.file(
|
|
"build.rs",
|
|
r#"
|
|
fn main() {
|
|
std::env::var("CARGO_BIN_FILE_D1").unwrap();
|
|
}
|
|
"#,
|
|
)
|
|
.file(
|
|
"d1/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "d1"
|
|
version = "0.0.1"
|
|
edition = "2021"
|
|
"#,
|
|
)
|
|
.file("d1/src/main.rs", "fn main() {}")
|
|
.build();
|
|
|
|
p.cargo("check -Z bindeps -F d1 -v")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(
|
|
str![[r#"
|
|
[LOCKING] 2 packages to latest compatible versions
|
|
[COMPILING] foo v0.0.1 ([ROOT]/foo)
|
|
[COMPILING] d1 v0.0.1 ([ROOT]/foo/d1)
|
|
[RUNNING] `rustc --crate-name build_script_build --edition=2021 [..]--crate-type bin[..]
|
|
[RUNNING] `rustc --crate-name d1 --edition=2021 [..]--crate-type bin[..]
|
|
[RUNNING] `[ROOT]/foo/target/debug/build/foo-[HASH]/build-script-build`
|
|
[RUNNING] `rustc --crate-name foo --edition=2021 [..]--cfg[..]d1[..]
|
|
[FINISHED] `dev` profile [..]
|
|
|
|
"#]]
|
|
.unordered(),
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn decouple_same_target_transitive_dep_from_artifact_dep() {
|
|
// See https://github.com/rust-lang/cargo/issues/11463
|
|
let target = rustc_host();
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
|
|
[dependencies]
|
|
a = {{ path = "a" }}
|
|
bar = {{ path = "bar", artifact = "bin", target = "{target}" }}
|
|
"#
|
|
),
|
|
)
|
|
.file(
|
|
"src/main.rs",
|
|
r#"
|
|
fn main() {}
|
|
"#,
|
|
)
|
|
.file(
|
|
"bar/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
|
|
[dependencies]
|
|
a = { path = "../a", features = ["feature"] }
|
|
"#,
|
|
)
|
|
.file(
|
|
"bar/src/main.rs",
|
|
r#"
|
|
fn main() {}
|
|
"#,
|
|
)
|
|
.file(
|
|
"a/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "a"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
|
|
[dependencies]
|
|
b = { path = "../b" }
|
|
c = { path = "../c" }
|
|
|
|
[features]
|
|
feature = ["c/feature"]
|
|
"#,
|
|
)
|
|
.file(
|
|
"a/src/lib.rs",
|
|
r#"
|
|
use b::Trait as _;
|
|
|
|
pub fn use_b_trait(x: &impl c::Trait) {
|
|
x.b();
|
|
}
|
|
"#,
|
|
)
|
|
.file(
|
|
"b/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "b"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
|
|
[dependencies]
|
|
c = { path = "../c" }
|
|
"#,
|
|
)
|
|
.file(
|
|
"b/src/lib.rs",
|
|
r#"
|
|
pub trait Trait {
|
|
fn b(&self) {}
|
|
}
|
|
|
|
impl<T: c::Trait> Trait for T {}
|
|
"#,
|
|
)
|
|
.file(
|
|
"c/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "c"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
|
|
[features]
|
|
feature = []
|
|
"#,
|
|
)
|
|
.file(
|
|
"c/src/lib.rs",
|
|
r#"
|
|
pub trait Trait {}
|
|
"#,
|
|
)
|
|
.build();
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 5 packages to latest compatible versions
|
|
[COMPILING] c v0.1.0 ([ROOT]/foo/c)
|
|
[COMPILING] b v0.1.0 ([ROOT]/foo/b)
|
|
[COMPILING] a v0.1.0 ([ROOT]/foo/a)
|
|
[COMPILING] bar v0.1.0 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.1.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn decouple_same_target_transitive_dep_from_artifact_dep_lib() {
|
|
// See https://github.com/rust-lang/cargo/issues/10837
|
|
let target = rustc_host();
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
|
|
[dependencies]
|
|
a = {{ path = "a" }}
|
|
b = {{ path = "b", features = ["feature"] }}
|
|
bar = {{ path = "bar", artifact = "bin", lib = true, target = "{target}" }}
|
|
"#
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
"bar/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
|
|
[dependencies]
|
|
a = { path = "../a", features = ["b"] }
|
|
b = { path = "../b" }
|
|
"#,
|
|
)
|
|
.file("bar/src/lib.rs", "")
|
|
.file(
|
|
"bar/src/main.rs",
|
|
r#"
|
|
use b::Trait;
|
|
|
|
fn main() {
|
|
a::A.b()
|
|
}
|
|
"#,
|
|
)
|
|
.file(
|
|
"a/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "a"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
|
|
[dependencies]
|
|
b = { path = "../b", optional = true }
|
|
"#,
|
|
)
|
|
.file(
|
|
"a/src/lib.rs",
|
|
r#"
|
|
pub struct A;
|
|
|
|
#[cfg(feature = "b")]
|
|
impl b::Trait for A {}
|
|
"#,
|
|
)
|
|
.file(
|
|
"b/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "b"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
|
|
[features]
|
|
feature = []
|
|
"#,
|
|
)
|
|
.file(
|
|
"b/src/lib.rs",
|
|
r#"
|
|
pub trait Trait {
|
|
fn b(&self) {}
|
|
}
|
|
"#,
|
|
)
|
|
.build();
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 4 packages to latest compatible versions
|
|
[COMPILING] b v0.1.0 ([ROOT]/foo/b)
|
|
[COMPILING] a v0.1.0 ([ROOT]/foo/a)
|
|
[COMPILING] bar v0.1.0 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.1.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn decouple_same_target_transitive_dep_from_artifact_dep_and_proc_macro() {
|
|
let target = rustc_host();
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
|
|
[dependencies]
|
|
c = {{ path = "c" }}
|
|
bar = {{ path = "bar", artifact = "bin", target = "{target}" }}
|
|
"#
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
"bar/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
|
|
[dependencies]
|
|
b = { path = "../b" }
|
|
"#,
|
|
)
|
|
.file("bar/src/main.rs", "fn main() {}")
|
|
.file(
|
|
"b/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "b"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
|
|
[dependencies]
|
|
a = { path = "../a" }
|
|
|
|
[lib]
|
|
proc-macro = true
|
|
"#,
|
|
)
|
|
.file("b/src/lib.rs", "")
|
|
.file(
|
|
"c/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "c"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
|
|
[dependencies]
|
|
d = { path = "../d", features = ["feature"] }
|
|
a = { path = "../a" }
|
|
|
|
[lib]
|
|
proc-macro = true
|
|
"#,
|
|
)
|
|
.file(
|
|
"c/src/lib.rs",
|
|
r#"
|
|
use a::Trait;
|
|
|
|
fn _c() {
|
|
d::D.a()
|
|
}
|
|
"#,
|
|
)
|
|
.file(
|
|
"a/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "a"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
|
|
[dependencies]
|
|
d = { path = "../d" }
|
|
"#,
|
|
)
|
|
.file(
|
|
"a/src/lib.rs",
|
|
r#"
|
|
pub trait Trait {
|
|
fn a(&self) {}
|
|
}
|
|
|
|
impl Trait for d::D {}
|
|
"#,
|
|
)
|
|
.file(
|
|
"d/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "d"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
|
|
[features]
|
|
feature = []
|
|
"#,
|
|
)
|
|
.file("d/src/lib.rs", "pub struct D;")
|
|
.build();
|
|
|
|
p.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(
|
|
str![[r#"
|
|
[LOCKING] 6 packages to latest compatible versions
|
|
[COMPILING] d v0.1.0 ([ROOT]/foo/d)
|
|
[COMPILING] a v0.1.0 ([ROOT]/foo/a)
|
|
[COMPILING] b v0.1.0 ([ROOT]/foo/b)
|
|
[COMPILING] c v0.1.0 ([ROOT]/foo/c)
|
|
[COMPILING] bar v0.1.0 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.1.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..]
|
|
|
|
"#]]
|
|
.unordered(),
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn same_target_artifact_dep_sharing() {
|
|
let target = rustc_host();
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
|
|
[dependencies]
|
|
a = {{ path = "a" }}
|
|
bar = {{ path = "bar", artifact = "bin", target = "{target}" }}
|
|
"#
|
|
),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
"bar/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "bar"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
|
|
[dependencies]
|
|
a = { path = "../a" }
|
|
"#,
|
|
)
|
|
.file(
|
|
"bar/src/main.rs",
|
|
r#"
|
|
fn main() {}
|
|
"#,
|
|
)
|
|
.file(
|
|
"a/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "a"
|
|
version = "0.1.0"
|
|
edition = "2015"
|
|
"#,
|
|
)
|
|
.file("a/src/lib.rs", "")
|
|
.build();
|
|
p.cargo(&format!("build -Z bindeps --target {target}"))
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 3 packages to latest compatible versions
|
|
[COMPILING] a v0.1.0 ([ROOT]/foo/a)
|
|
[COMPILING] bar v0.1.0 ([ROOT]/foo/bar)
|
|
[COMPILING] foo v0.1.0 ([ROOT]/foo)
|
|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
|
|
|
"#]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn check_transitive_artifact_dependency_with_different_target() {
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
|
|
[dependencies]
|
|
bar = { path = "bar/" }
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
"bar/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "bar"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
|
|
[dependencies]
|
|
baz = { path = "baz/", artifact = "bin", target = "custom-target" }
|
|
"#,
|
|
)
|
|
.file("bar/src/lib.rs", "")
|
|
.file(
|
|
"bar/baz/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "baz"
|
|
version = "0.0.0"
|
|
edition = "2015"
|
|
|
|
[dependencies]
|
|
"#,
|
|
)
|
|
.file("bar/baz/src/main.rs", "fn main() {}")
|
|
.build();
|
|
|
|
p.cargo("check -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.with_stderr_data(str![[r#"
|
|
[LOCKING] 3 packages to latest compatible versions
|
|
[ERROR] failed to determine target information for target `custom-target`.
|
|
Artifact dependency `baz` in package `bar v0.0.0 ([ROOT]/foo/bar)` requires building for `custom-target`
|
|
|
|
Caused by:
|
|
failed to run `rustc` to learn about target-specific information
|
|
|
|
Caused by:
|
|
process didn't exit successfully: `rustc [..] ([EXIT_STATUS]: 1)
|
|
--- stderr
|
|
[ERROR] Error loading target specification: Could not find specification for target "custom-target". Run `rustc --print target-list` for a list of built-in targets
|
|
|
|
|
|
"#]])
|
|
.with_status(101)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn build_only_specified_artifact_library() {
|
|
// Create a project with:
|
|
// - A crate `bar` with both `staticlib` and `cdylib` as crate-types.
|
|
// - A crate `foo` which depends on either the `staticlib` or `cdylib` artifact of bar,
|
|
// whose build-script simply checks which library artifacts are present.
|
|
let create_project = |artifact_lib| {
|
|
project()
|
|
.file(
|
|
"bar/Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "bar"
|
|
version = "1.0.0"
|
|
|
|
[lib]
|
|
crate-type = ["staticlib", "cdylib"]
|
|
"#,
|
|
)
|
|
.file("bar/src/lib.rs", "")
|
|
.file(
|
|
"Cargo.toml",
|
|
&format!(
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "1.0.0"
|
|
|
|
[build-dependencies]
|
|
bar = {{ path = "bar", artifact = "{artifact_lib}" }}
|
|
"#),
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.file(
|
|
"build.rs",
|
|
r#"
|
|
fn main() {
|
|
println!("cdylib present: {}", std::env::var_os("CARGO_CDYLIB_FILE_BAR").is_some());
|
|
println!("staticlib present: {}", std::env::var_os("CARGO_STATICLIB_FILE_BAR").is_some());
|
|
}
|
|
"#,
|
|
)
|
|
.build()
|
|
};
|
|
|
|
let cdylib = create_project("cdylib");
|
|
cdylib
|
|
.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.run();
|
|
assert_e2e().eq(
|
|
&build_script_output_string(&cdylib, "foo"),
|
|
str![[r#"
|
|
cdylib present: true
|
|
staticlib present: false
|
|
|
|
"#]],
|
|
);
|
|
|
|
let staticlib = create_project("staticlib");
|
|
staticlib
|
|
.cargo("build -Z bindeps")
|
|
.masquerade_as_nightly_cargo(&["bindeps"])
|
|
.run();
|
|
assert_e2e().eq(
|
|
&build_script_output_string(&staticlib, "foo"),
|
|
str![[r#"
|
|
cdylib present: false
|
|
staticlib present: true
|
|
|
|
"#]],
|
|
);
|
|
}
|