cargo/tests/testsuite/run.rs

1567 lines
39 KiB
Rust
Raw Normal View History

2019-11-25 02:42:45 +00:00
//! Tests for the `cargo run` command.
use cargo_test_support::{
basic_bin_manifest, basic_lib_manifest, basic_manifest, project, Project,
};
2021-03-20 20:43:33 +00:00
use cargo_util::paths::dylib_path_envvar;
#[cargo_test]
fn simple() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.build();
p.cargo("run")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-08-02 09:18:48 +00:00
[RUNNING] `target/debug/foo[EXE]`",
2018-12-08 11:19:47 +00:00
)
.with_stdout("hello")
.run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
}
#[cargo_test]
fn quiet_arg() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.build();
2021-12-08 21:49:22 +00:00
p.cargo("run -q").with_stderr("").with_stdout("hello").run();
2018-03-12 20:08:49 +00:00
2021-12-08 21:49:22 +00:00
p.cargo("run --quiet")
.with_stderr("")
.with_stdout("hello")
.run();
}
2023-09-22 02:46:06 +00:00
#[cargo_test]
fn unsupported_silent_arg() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.build();
p.cargo("run -s")
.with_stderr(
"\
error: unexpected argument '--silent' found
2023-09-22 02:46:06 +00:00
tip: a similar argument exists: '--quiet'
2023-09-22 02:46:06 +00:00
2023-09-28 02:10:19 +00:00
Usage: cargo[EXE] run [OPTIONS] [args]...
2023-09-22 02:46:06 +00:00
For more information, try '--help'.
",
)
.with_status(1)
.run();
p.cargo("run --silent")
.with_stderr(
"\
error: unexpected argument '--silent' found
tip: a similar argument exists: '--quiet'
2023-09-22 02:46:06 +00:00
2023-09-28 02:10:19 +00:00
Usage: cargo[EXE] run [OPTIONS] [args]...
2023-09-22 02:46:06 +00:00
For more information, try '--help'.
",
)
.with_status(1)
.run();
}
#[cargo_test]
fn quiet_arg_and_verbose_arg() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.build();
p.cargo("run -q -v")
.with_status(101)
.with_stderr("[ERROR] cannot set both --verbose and --quiet")
.run();
}
#[cargo_test]
fn quiet_arg_and_verbose_config() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
".cargo/config",
r#"
2020-09-27 00:59:58 +00:00
[term]
verbose = true
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.build();
2021-12-08 21:49:22 +00:00
p.cargo("run -q").with_stderr("").with_stdout("hello").run();
}
#[cargo_test]
fn verbose_arg_and_quiet_config() {
let p = project()
.file(
".cargo/config",
r#"
[term]
quiet = true
"#,
)
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.build();
2021-12-08 21:49:22 +00:00
p.cargo("run -v")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([CWD])
[RUNNING] `rustc [..]
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `target/debug/foo[EXE]`",
)
.with_stdout("hello")
.run();
}
#[cargo_test]
fn quiet_config_alone() {
let p = project()
.file(
".cargo/config",
r#"
[term]
quiet = true
"#,
)
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.build();
p.cargo("run").with_stderr("").with_stdout("hello").run();
}
#[cargo_test]
fn verbose_config_alone() {
let p = project()
.file(
".cargo/config",
r#"
[term]
verbose = true
"#,
)
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.build();
p.cargo("run")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([CWD])
[RUNNING] `rustc [..]
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2021-12-08 21:49:22 +00:00
[RUNNING] `target/debug/foo[EXE]`",
)
.with_stdout("hello")
.run();
}
#[cargo_test]
fn quiet_config_and_verbose_config() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
".cargo/config",
r#"
2020-09-27 00:59:58 +00:00
[term]
verbose = true
quiet = true
2020-09-27 00:59:58 +00:00
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.build();
2021-12-08 21:49:22 +00:00
p.cargo("run")
.with_status(101)
.with_stderr("[ERROR] cannot set both `term.verbose` and `term.quiet`")
.run();
}
#[cargo_test]
fn simple_with_args() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"src/main.rs",
r#"
2020-09-27 00:59:58 +00:00
fn main() {
assert_eq!(std::env::args().nth(1).unwrap(), "hello");
assert_eq!(std::env::args().nth(2).unwrap(), "world");
}
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("run hello world").run();
}
#[cfg(unix)]
#[cargo_test]
fn simple_with_non_utf8_args() {
use std::os::unix::ffi::OsStrExt;
let p = project()
.file(
"src/main.rs",
r#"
2020-09-27 00:59:58 +00:00
use std::ffi::OsStr;
use std::os::unix::ffi::OsStrExt;
2020-09-27 00:59:58 +00:00
fn main() {
assert_eq!(std::env::args_os().nth(1).unwrap(), OsStr::from_bytes(b"hello"));
assert_eq!(std::env::args_os().nth(2).unwrap(), OsStr::from_bytes(b"ab\xffcd"));
}
"#,
)
.build();
p.cargo("run")
.arg("hello")
.arg(std::ffi::OsStr::from_bytes(b"ab\xFFcd"))
.run();
}
#[cargo_test]
fn exit_code() {
let p = project()
.file("src/main.rs", "fn main() { std::process::exit(2); }")
.build();
2018-03-14 15:17:44 +00:00
let mut output = String::from(
"\
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2016-05-15 22:03:35 +00:00
[RUNNING] `target[..]`
2018-03-14 15:17:44 +00:00
",
);
if !cfg!(unix) {
2018-03-14 15:17:44 +00:00
output.push_str(
"[ERROR] process didn't exit successfully: `target[..]foo[..]` (exit [..]: 2)",
2018-03-14 15:17:44 +00:00
);
}
p.cargo("run").with_status(2).with_stderr(output).run();
}
#[cargo_test]
fn exit_code_verbose() {
let p = project()
.file("src/main.rs", "fn main() { std::process::exit(2); }")
.build();
2015-10-13 00:30:44 +00:00
2018-03-14 15:17:44 +00:00
let mut output = String::from(
"\
[COMPILING] foo v0.0.1 ([CWD])
2016-05-15 22:03:35 +00:00
[RUNNING] `rustc [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2016-05-15 22:03:35 +00:00
[RUNNING] `target[..]`
2018-03-14 15:17:44 +00:00
",
);
if !cfg!(unix) {
2018-03-14 15:17:44 +00:00
output.push_str(
"[ERROR] process didn't exit successfully: `target[..]foo[..]` (exit [..]: 2)",
2018-03-14 15:17:44 +00:00
);
}
p.cargo("run -v").with_status(2).with_stderr(output).run();
}
2015-10-13 00:30:44 +00:00
#[cargo_test]
fn no_main_file() {
let p = project().file("src/lib.rs", "").build();
p.cargo("run")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"[ERROR] a bin target must be available \
for `cargo run`\n",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn too_many_bins() {
let p = project()
.file("src/lib.rs", "")
.file("src/bin/a.rs", "")
.file("src/bin/b.rs", "")
.build();
// Using [..] here because the order is not stable
p.cargo("run")
.with_status(101)
.with_stderr(
"[ERROR] `cargo run` could not determine which binary to run. \
2019-06-21 18:36:53 +00:00
Use the `--bin` option to specify a binary, or the \
`default-run` manifest key.\
\navailable binaries: [..]\n",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn specify_name() {
let p = project()
.file("src/lib.rs", "")
2018-03-14 15:17:44 +00:00
.file(
"src/bin/a.rs",
r#"
2020-09-27 00:59:58 +00:00
#[allow(unused_extern_crates)]
extern crate foo;
fn main() { println!("hello a.rs"); }
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"src/bin/b.rs",
r#"
2020-09-27 00:59:58 +00:00
#[allow(unused_extern_crates)]
extern crate foo;
fn main() { println!("hello b.rs"); }
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("run --bin a -v")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([CWD])
2018-08-02 09:18:48 +00:00
[RUNNING] `rustc [..] src/lib.rs [..]`
[RUNNING] `rustc [..] src/bin/a.rs [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-08-02 09:18:48 +00:00
[RUNNING] `target/debug/a[EXE]`",
2018-12-08 11:19:47 +00:00
)
.with_stdout("hello a.rs")
.run();
p.cargo("run --bin b -v")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([..])
2018-08-02 09:18:48 +00:00
[RUNNING] `rustc [..] src/bin/b.rs [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-08-02 09:18:48 +00:00
[RUNNING] `target/debug/b[EXE]`",
2018-12-08 11:19:47 +00:00
)
.with_stdout("hello b.rs")
.run();
}
#[cargo_test]
fn specify_default_run() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.0.1"
authors = []
default-run = "a"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.file("src/bin/a.rs", r#"fn main() { println!("hello A"); }"#)
.file("src/bin/b.rs", r#"fn main() { println!("hello B"); }"#)
.build();
2019-06-21 18:36:53 +00:00
p.cargo("run").with_stdout("hello A").run();
p.cargo("run --bin a").with_stdout("hello A").run();
p.cargo("run --bin b").with_stdout("hello B").run();
}
#[cargo_test]
fn bogus_default_run() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.0.1"
authors = []
default-run = "b"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.file("src/bin/a.rs", r#"fn main() { println!("hello A"); }"#)
.build();
p.cargo("run")
.with_status(101)
.with_stderr(
2019-06-21 18:36:53 +00:00
"\
[ERROR] failed to parse manifest at `[..]/foo/Cargo.toml`
2018-07-16 09:28:32 +00:00
Caused by:
2019-06-21 18:36:53 +00:00
default-run target `b` not found
2018-07-16 09:28:32 +00:00
<tab>Did you mean `a`?
2019-06-21 18:36:53 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
2018-07-16 09:28:32 +00:00
}
#[cargo_test]
fn run_example() {
let p = project()
.file("src/lib.rs", "")
.file("examples/a.rs", r#"fn main() { println!("example"); }"#)
.file("src/bin/a.rs", r#"fn main() { println!("bin"); }"#)
.build();
p.cargo("run --example a")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-08-02 09:18:48 +00:00
[RUNNING] `target/debug/examples/a[EXE]`",
2018-12-08 11:19:47 +00:00
)
.with_stdout("example")
.run();
2017-03-24 20:20:38 +00:00
}
#[cargo_test]
fn run_library_example() {
let p = project()
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
[[example]]
name = "bar"
crate_type = ["lib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.file("examples/bar.rs", "fn foo() {}")
.build();
p.cargo("run --example bar")
.with_status(101)
.with_stderr("[ERROR] example target `bar` is a library and cannot be executed")
.run();
}
#[cargo_test]
2018-11-18 17:32:42 +00:00
fn run_bin_example() {
let p = project()
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
[[example]]
name = "bar"
crate_type = ["bin"]
"#,
2018-11-18 17:32:42 +00:00
)
.file("src/lib.rs", "")
.file("examples/bar.rs", r#"fn main() { println!("example"); }"#)
.build();
p.cargo("run --example bar")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `target/debug/examples/bar[EXE]`",
)
.with_stdout("example")
.run();
}
fn autodiscover_examples_project(rust_edition: &str, autoexamples: Option<bool>) -> Project {
let autoexamples = match autoexamples {
None => "".to_string(),
Some(bool) => format!("autoexamples = {}", bool),
};
project()
.file(
"Cargo.toml",
&format!(
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "{rust_edition}"
{autoexamples}
[features]
magic = []
[[example]]
name = "do_magic"
required-features = ["magic"]
"#,
rust_edition = rust_edition,
autoexamples = autoexamples
),
2018-12-08 11:19:47 +00:00
)
.file("examples/a.rs", r#"fn main() { println!("example"); }"#)
.file(
"examples/do_magic.rs",
r#"
fn main() { println!("magic example"); }
"#,
2018-12-08 11:19:47 +00:00
)
.build()
}
#[cargo_test]
fn run_example_autodiscover_2015() {
let p = autodiscover_examples_project("2015", None);
p.cargo("run --example a")
.with_status(101)
.with_stderr(
"warning: \
An explicit [[example]] section is specified in Cargo.toml which currently
disables Cargo from automatically inferring other example targets.
This inference behavior will change in the Rust 2018 edition and the following
files will be included as a example target:
2018-04-20 21:21:33 +00:00
* [..]a.rs
This is likely to break cargo build or cargo test as these files may not be
ready to be compiled as a example target today. You can future-proof yourself
and disable this warning by adding `autoexamples = false` to your [package]
section. You may also move the files to a location where Cargo would not
automatically infer them to be a target, such as in subfolders.
For more information on this warning you can consult
https://github.com/rust-lang/cargo/issues/5330
error: no example target named `a`.
Available example targets:
do_magic
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn run_example_autodiscover_2015_with_autoexamples_enabled() {
let p = autodiscover_examples_project("2015", Some(true));
p.cargo("run --example a")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-08-02 09:18:48 +00:00
[RUNNING] `target/debug/examples/a[EXE]`",
2018-12-08 11:19:47 +00:00
)
.with_stdout("example")
.run();
}
#[cargo_test]
fn run_example_autodiscover_2015_with_autoexamples_disabled() {
let p = autodiscover_examples_project("2015", Some(false));
p.cargo("run --example a")
.with_status(101)
.with_stderr(
"\
error: no example target named `a`.
Available example targets:
do_magic
",
)
.run();
}
#[cargo_test]
fn run_example_autodiscover_2018() {
let p = autodiscover_examples_project("2018", None);
p.cargo("run --example a")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-08-02 09:18:48 +00:00
[RUNNING] `target/debug/examples/a[EXE]`",
2018-12-08 11:19:47 +00:00
)
.with_stdout("example")
.run();
}
#[cargo_test]
fn autobins_disables() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
autobins = false
2018-12-08 11:19:47 +00:00
"#,
)
.file("src/lib.rs", "pub mod bin;")
.file("src/bin/mod.rs", "// empty")
.build();
p.cargo("run")
.with_status(101)
.with_stderr("[ERROR] a bin target must be available for `cargo run`")
.run();
}
#[cargo_test]
2018-03-06 20:28:52 +00:00
fn run_bins() {
let p = project()
2017-03-24 20:20:38 +00:00
.file("src/lib.rs", "")
.file("examples/a.rs", r#"fn main() { println!("example"); }"#)
.file("src/bin/a.rs", r#"fn main() { println!("bin"); }"#)
.build();
2017-03-24 20:20:38 +00:00
p.cargo("run --bins")
.with_status(1)
.with_stderr_contains(
2023-01-13 18:26:29 +00:00
"\
error: unexpected argument '--bins' found
tip: a similar argument exists: '--bin'",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn run_with_filename() {
let p = project()
.file("src/lib.rs", "")
2018-03-14 15:17:44 +00:00
.file(
"src/bin/a.rs",
r#"
2020-09-27 00:59:58 +00:00
extern crate foo;
fn main() { println!("hello a.rs"); }
"#,
2018-12-08 11:19:47 +00:00
)
.file("examples/a.rs", r#"fn main() { println!("example"); }"#)
.build();
p.cargo("run --bin bin.rs")
.with_status(101)
.with_stderr(
"\
[ERROR] no bin target named `bin.rs`.
Available bin targets:
a
",
)
.run();
p.cargo("run --bin a.rs")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] no bin target named `a.rs`
2019-06-21 18:36:53 +00:00
<tab>Did you mean `a`?",
2018-12-08 11:19:47 +00:00
)
.run();
p.cargo("run --example example.rs")
.with_status(101)
.with_stderr(
"\
[ERROR] no example target named `example.rs`.
Available example targets:
a
",
)
.run();
p.cargo("run --example a.rs")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] no example target named `a.rs`
2019-06-21 18:36:53 +00:00
<tab>Did you mean `a`?",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn either_name_or_example() {
let p = project()
.file("src/bin/a.rs", r#"fn main() { println!("hello a.rs"); }"#)
.file("examples/b.rs", r#"fn main() { println!("hello b.rs"); }"#)
.build();
p.cargo("run --bin a --example b")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"[ERROR] `cargo run` can run at most one \
executable, but multiple were \
specified",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn one_bin_multiple_examples() {
let p = project()
.file("src/lib.rs", "")
.file(
"src/bin/main.rs",
r#"fn main() { println!("hello main.rs"); }"#,
2018-12-08 11:19:47 +00:00
)
.file("examples/a.rs", r#"fn main() { println!("hello a.rs"); }"#)
.file("examples/b.rs", r#"fn main() { println!("hello b.rs"); }"#)
.build();
p.cargo("run")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-08-02 09:18:48 +00:00
[RUNNING] `target/debug/main[EXE]`",
2018-12-08 11:19:47 +00:00
)
.with_stdout("hello main.rs")
.run();
}
#[cargo_test]
fn example_with_release_flag() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
[package]
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.0.1"
authors = []
[dependencies.bar]
version = "*"
path = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"examples/a.rs",
r#"
2020-09-27 00:59:58 +00:00
extern crate bar;
fn main() {
if cfg!(debug_assertions) {
println!("slow1")
} else {
println!("fast1")
}
bar::baz();
}
2020-09-27 00:59:58 +00:00
"#,
2018-12-08 11:19:47 +00:00
)
.file("bar/Cargo.toml", &basic_lib_manifest("bar"))
2018-03-14 15:17:44 +00:00
.file(
"bar/src/bar.rs",
r#"
2020-09-27 00:59:58 +00:00
pub fn baz() {
if cfg!(debug_assertions) {
println!("slow2")
} else {
println!("fast2")
}
}
2020-09-27 00:59:58 +00:00
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("run -v --release --example a")
.with_stderr(
"\
[COMPILING] bar v0.5.0 ([CWD]/bar)
2019-09-25 01:17:36 +00:00
[RUNNING] `rustc --crate-name bar bar/src/bar.rs [..]--crate-type lib \
--emit=[..]link \
Add support for `-Cembed-bitcode=no` This commit is the Cargo half of support necessary for rust-lang/rust#70458. Today the compiler emits embedded bytecode in rlibs by default, but compresses it. This is both extraneous disk space and wasted build time for almost all builds, so the PR in question there is changing rustc to have a `-Cembed-bitcode` flag which, when enabled, places the bitcode in the object file rather than an auxiliary file (no extra compression), but also enables `-Cembed-bitcode=no` to disable bitcode emission entirely. This Cargo support changes Cargo to pass `-Cembed-bitcode=no` for almost all compilations. Cargo will keep `lto = true` and such working by not passing this flag (and thus allowing bitcode to get embedded), but by default `cargo build` and `cargo build --release` will no longer have any bitcode in rlibs which should result in speedier builds! Most of the changes here were around the test suite and various assertions about the `rustc` command lines we spit out. One test was hard-disabled until we can get `-Cembed-bitcode=no` into nightly, and then we can make it a nightly-only test. The test will then be stable again once `-Cembed-bitcode=no` hits stable. Note that this is intended to land before the upstream `-Cembed-bitcode` change. The thinking is that we'll land everything in rust-lang/rust all at once so there's no build time regressions for anyone. If we were to land the `-Cembed-bitcode` PR first then there would be a build time regression until we land Cargo changes because rustc would be emitting uncompressed bitcode by default and Cargo wouldn't be turning it off.
2020-04-01 18:41:27 +00:00
-C opt-level=3[..]\
-C metadata=[..] \
--out-dir [CWD]/target/release/deps \
-L dependency=[CWD]/target/release/deps`
[COMPILING] foo v0.0.1 ([CWD])
2019-09-25 01:17:36 +00:00
[RUNNING] `rustc --crate-name a examples/a.rs [..]--crate-type bin \
--emit=[..]link \
Add support for `-Cembed-bitcode=no` This commit is the Cargo half of support necessary for rust-lang/rust#70458. Today the compiler emits embedded bytecode in rlibs by default, but compresses it. This is both extraneous disk space and wasted build time for almost all builds, so the PR in question there is changing rustc to have a `-Cembed-bitcode` flag which, when enabled, places the bitcode in the object file rather than an auxiliary file (no extra compression), but also enables `-Cembed-bitcode=no` to disable bitcode emission entirely. This Cargo support changes Cargo to pass `-Cembed-bitcode=no` for almost all compilations. Cargo will keep `lto = true` and such working by not passing this flag (and thus allowing bitcode to get embedded), but by default `cargo build` and `cargo build --release` will no longer have any bitcode in rlibs which should result in speedier builds! Most of the changes here were around the test suite and various assertions about the `rustc` command lines we spit out. One test was hard-disabled until we can get `-Cembed-bitcode=no` into nightly, and then we can make it a nightly-only test. The test will then be stable again once `-Cembed-bitcode=no` hits stable. Note that this is intended to land before the upstream `-Cembed-bitcode` change. The thinking is that we'll land everything in rust-lang/rust all at once so there's no build time regressions for anyone. If we were to land the `-Cembed-bitcode` PR first then there would be a build time regression until we land Cargo changes because rustc would be emitting uncompressed bitcode by default and Cargo wouldn't be turning it off.
2020-04-01 18:41:27 +00:00
-C opt-level=3[..]\
-C metadata=[..] \
--out-dir [CWD]/target/release/examples \
-L dependency=[CWD]/target/release/deps \
--extern bar=[CWD]/target/release/deps/libbar-[..].rlib`
[FINISHED] release [optimized] target(s) in [..]
2018-08-02 09:18:48 +00:00
[RUNNING] `target/release/examples/a[EXE]`
",
2018-12-08 11:19:47 +00:00
)
.with_stdout(
"\
2016-05-15 21:48:11 +00:00
fast1
2018-03-14 15:17:44 +00:00
fast2",
2018-12-08 11:19:47 +00:00
)
.run();
p.cargo("run -v --example a")
.with_stderr(
"\
[COMPILING] bar v0.5.0 ([CWD]/bar)
2019-09-25 01:17:36 +00:00
[RUNNING] `rustc --crate-name bar bar/src/bar.rs [..]--crate-type lib \
Add support for `-Cembed-bitcode=no` This commit is the Cargo half of support necessary for rust-lang/rust#70458. Today the compiler emits embedded bytecode in rlibs by default, but compresses it. This is both extraneous disk space and wasted build time for almost all builds, so the PR in question there is changing rustc to have a `-Cembed-bitcode` flag which, when enabled, places the bitcode in the object file rather than an auxiliary file (no extra compression), but also enables `-Cembed-bitcode=no` to disable bitcode emission entirely. This Cargo support changes Cargo to pass `-Cembed-bitcode=no` for almost all compilations. Cargo will keep `lto = true` and such working by not passing this flag (and thus allowing bitcode to get embedded), but by default `cargo build` and `cargo build --release` will no longer have any bitcode in rlibs which should result in speedier builds! Most of the changes here were around the test suite and various assertions about the `rustc` command lines we spit out. One test was hard-disabled until we can get `-Cembed-bitcode=no` into nightly, and then we can make it a nightly-only test. The test will then be stable again once `-Cembed-bitcode=no` hits stable. Note that this is intended to land before the upstream `-Cembed-bitcode` change. The thinking is that we'll land everything in rust-lang/rust all at once so there's no build time regressions for anyone. If we were to land the `-Cembed-bitcode` PR first then there would be a build time regression until we land Cargo changes because rustc would be emitting uncompressed bitcode by default and Cargo wouldn't be turning it off.
2020-04-01 18:41:27 +00:00
--emit=[..]link[..]\
-C debuginfo=2 [..]\
-C metadata=[..] \
--out-dir [CWD]/target/debug/deps \
-L dependency=[CWD]/target/debug/deps`
[COMPILING] foo v0.0.1 ([CWD])
2019-09-25 01:17:36 +00:00
[RUNNING] `rustc --crate-name a examples/a.rs [..]--crate-type bin \
Add support for `-Cembed-bitcode=no` This commit is the Cargo half of support necessary for rust-lang/rust#70458. Today the compiler emits embedded bytecode in rlibs by default, but compresses it. This is both extraneous disk space and wasted build time for almost all builds, so the PR in question there is changing rustc to have a `-Cembed-bitcode` flag which, when enabled, places the bitcode in the object file rather than an auxiliary file (no extra compression), but also enables `-Cembed-bitcode=no` to disable bitcode emission entirely. This Cargo support changes Cargo to pass `-Cembed-bitcode=no` for almost all compilations. Cargo will keep `lto = true` and such working by not passing this flag (and thus allowing bitcode to get embedded), but by default `cargo build` and `cargo build --release` will no longer have any bitcode in rlibs which should result in speedier builds! Most of the changes here were around the test suite and various assertions about the `rustc` command lines we spit out. One test was hard-disabled until we can get `-Cembed-bitcode=no` into nightly, and then we can make it a nightly-only test. The test will then be stable again once `-Cembed-bitcode=no` hits stable. Note that this is intended to land before the upstream `-Cembed-bitcode` change. The thinking is that we'll land everything in rust-lang/rust all at once so there's no build time regressions for anyone. If we were to land the `-Cembed-bitcode` PR first then there would be a build time regression until we land Cargo changes because rustc would be emitting uncompressed bitcode by default and Cargo wouldn't be turning it off.
2020-04-01 18:41:27 +00:00
--emit=[..]link[..]\
-C debuginfo=2 [..]\
-C metadata=[..] \
--out-dir [CWD]/target/debug/examples \
-L dependency=[CWD]/target/debug/deps \
--extern bar=[CWD]/target/debug/deps/libbar-[..].rlib`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-08-02 09:18:48 +00:00
[RUNNING] `target/debug/examples/a[EXE]`
",
2018-12-08 11:19:47 +00:00
)
.with_stdout(
"\
2016-05-15 21:48:11 +00:00
slow1
2018-03-14 15:17:44 +00:00
slow2",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn run_dylib_dep() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
[package]
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies.bar]
path = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
"src/main.rs",
r#"extern crate bar; fn main() { bar::bar(); }"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"bar/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "bar"
version = "0.0.1"
authors = []
[lib]
name = "bar"
crate-type = ["dylib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("bar/src/lib.rs", "pub fn bar() {}")
.build();
p.cargo("run hello world").run();
}
#[cargo_test]
fn run_with_bin_dep() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
[dependencies.bar]
path = "bar"
"#,
)
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.file(
"bar/Cargo.toml",
r#"
[package]
name = "bar"
version = "0.0.1"
authors = []
[[bin]]
name = "bar"
"#,
)
.file("bar/src/main.rs", r#"fn main() { println!("bar"); }"#)
.build();
p.cargo("run")
.with_stderr(
"\
[WARNING] foo v0.0.1 ([CWD]) ignoring invalid dependency `bar` which is missing a lib target
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `target/debug/foo[EXE]`",
)
.with_stdout("hello")
.run();
}
#[cargo_test]
fn run_with_bin_deps() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
[dependencies.bar1]
path = "bar1"
[dependencies.bar2]
path = "bar2"
"#,
)
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.file(
"bar1/Cargo.toml",
r#"
[package]
name = "bar1"
version = "0.0.1"
authors = []
[[bin]]
name = "bar1"
"#,
)
.file("bar1/src/main.rs", r#"fn main() { println!("bar1"); }"#)
.file(
"bar2/Cargo.toml",
r#"
[package]
name = "bar2"
version = "0.0.1"
authors = []
[[bin]]
name = "bar2"
"#,
)
.file("bar2/src/main.rs", r#"fn main() { println!("bar2"); }"#)
.build();
p.cargo("run")
.with_stderr(
"\
[WARNING] foo v0.0.1 ([CWD]) ignoring invalid dependency `bar1` which is missing a lib target
[WARNING] foo v0.0.1 ([CWD]) ignoring invalid dependency `bar2` which is missing a lib target
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `target/debug/foo[EXE]`",
)
.with_stdout("hello")
.run();
}
#[cargo_test]
fn run_with_bin_dep_in_workspace() {
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["foo1", "foo2"]
"#,
)
.file(
"foo1/Cargo.toml",
r#"
[package]
name = "foo1"
version = "0.0.1"
[dependencies.bar1]
path = "bar1"
"#,
)
.file("foo1/src/main.rs", r#"fn main() { println!("hello"); }"#)
.file(
"foo1/bar1/Cargo.toml",
r#"
[package]
name = "bar1"
version = "0.0.1"
authors = []
[[bin]]
name = "bar1"
"#,
)
.file(
"foo1/bar1/src/main.rs",
r#"fn main() { println!("bar1"); }"#,
)
.file(
"foo2/Cargo.toml",
r#"
[package]
name = "foo2"
version = "0.0.1"
[dependencies.bar2]
path = "bar2"
"#,
)
.file("foo2/src/main.rs", r#"fn main() { println!("hello"); }"#)
.file(
"foo2/bar2/Cargo.toml",
r#"
[package]
name = "bar2"
version = "0.0.1"
authors = []
[[bin]]
name = "bar2"
"#,
)
.file(
"foo2/bar2/src/main.rs",
r#"fn main() { println!("bar2"); }"#,
)
.build();
p.cargo("run")
.with_status(101)
.with_stderr(
"\
[ERROR] `cargo run` could not determine which binary to run[..]
available binaries: bar1, bar2, foo1, foo2",
)
.run();
p.cargo("run --bin foo1")
.with_stderr(
"\
[WARNING] foo1 v0.0.1 ([CWD]/foo1) ignoring invalid dependency `bar1` which is missing a lib target
[WARNING] foo2 v0.0.1 ([CWD]/foo2) ignoring invalid dependency `bar2` which is missing a lib target
[COMPILING] foo1 v0.0.1 ([CWD]/foo1)
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `target/debug/foo1[EXE]`",
)
.with_stdout("hello")
.run();
}
#[cargo_test]
fn release_works() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"src/main.rs",
r#"
2020-09-27 00:59:58 +00:00
fn main() { if cfg!(debug_assertions) { panic!() } }
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("run --release")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] release [optimized] target(s) in [..]
2018-08-02 09:18:48 +00:00
[RUNNING] `target/release/foo[EXE]`
",
2018-12-08 11:19:47 +00:00
)
.run();
2018-08-29 06:11:10 +00:00
assert!(p.release_bin("foo").is_file());
}
#[cargo_test]
fn release_short_works() {
let p = project()
.file(
"src/main.rs",
r#"
fn main() { if cfg!(debug_assertions) { panic!() } }
"#,
)
.build();
p.cargo("run -r")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([CWD])
[FINISHED] release [optimized] target(s) in [..]
[RUNNING] `target/release/foo[EXE]`
",
)
.run();
assert!(p.release_bin("foo").is_file());
}
#[cargo_test]
fn run_bin_different_name() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
[package]
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[[bin]]
name = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/bar.rs", "fn main() {}")
.build();
p.cargo("run").run();
}
#[cargo_test]
fn dashes_are_forwarded() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
2018-04-28 14:57:03 +00:00
"src/bin/bar.rs",
2018-03-14 15:17:44 +00:00
r#"
2020-09-27 00:59:58 +00:00
fn main() {
let s: Vec<String> = std::env::args().collect();
assert_eq!(s[1], "--");
assert_eq!(s[2], "a");
assert_eq!(s[3], "--");
assert_eq!(s[4], "b");
}
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("run -- -- a -- b").run();
}
2015-08-29 11:03:14 +00:00
#[cargo_test]
fn run_from_executable_folder() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
.build();
2015-08-29 11:03:14 +00:00
let cwd = p.root().join("target").join("debug");
p.cargo("build").run();
2015-08-29 11:03:14 +00:00
p.cargo("run")
.cwd(cwd)
.with_stderr(
2019-07-13 23:00:47 +00:00
"[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n\
[RUNNING] `./foo[EXE]`",
2018-12-08 11:19:47 +00:00
)
.with_stdout("hello")
.run();
}
#[cargo_test]
fn run_with_library_paths() {
let p = project();
// Only link search directories within the target output directory are
// propagated through to dylib_path_envvar() (see #3366).
let mut dir1 = p.target_debug_dir();
dir1.push("foo\\backslash");
let mut dir2 = p.target_debug_dir();
dir2.push("dir=containing=equal=signs");
let p = p
.file(
"Cargo.toml",
r#"
[package]
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.0.1"
authors = []
build = "build.rs"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"build.rs",
&format!(
r##"
2020-09-27 00:59:58 +00:00
fn main() {{
println!(r#"cargo:rustc-link-search=native={}"#);
println!(r#"cargo:rustc-link-search={}"#);
}}
"##,
2018-03-14 15:17:44 +00:00
dir1.display(),
dir2.display()
),
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"src/main.rs",
&format!(
r##"
2020-09-27 00:59:58 +00:00
fn main() {{
let search_path = std::env::var_os("{}").unwrap();
let paths = std::env::split_paths(&search_path).collect::<Vec<_>>();
println!("{{:#?}}", paths);
assert!(paths.contains(&r#"{}"#.into()));
assert!(paths.contains(&r#"{}"#.into()));
}}
"##,
2018-03-14 15:17:44 +00:00
dylib_path_envvar(),
dir1.display(),
dir2.display()
),
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("run").run();
}
#[cargo_test]
2018-01-20 17:57:17 +00:00
fn library_paths_sorted_alphabetically() {
let p = project();
2018-01-20 17:57:17 +00:00
let mut dir1 = p.target_debug_dir();
dir1.push("zzzzzzz");
let mut dir2 = p.target_debug_dir();
dir2.push("BBBBBBB");
let mut dir3 = p.target_debug_dir();
dir3.push("aaaaaaa");
let p = p
.file(
"Cargo.toml",
r#"
[package]
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.0.1"
authors = []
build = "build.rs"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"build.rs",
&format!(
r##"
2020-09-27 00:59:58 +00:00
fn main() {{
println!(r#"cargo:rustc-link-search=native={}"#);
println!(r#"cargo:rustc-link-search=native={}"#);
println!(r#"cargo:rustc-link-search=native={}"#);
}}
"##,
2018-03-14 15:17:44 +00:00
dir1.display(),
dir2.display(),
dir3.display()
),
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"src/main.rs",
&format!(
r##"
2020-09-27 00:59:58 +00:00
fn main() {{
let search_path = std::env::var_os("{}").unwrap();
let paths = std::env::split_paths(&search_path).collect::<Vec<_>>();
// ASCII case-sensitive sort
assert_eq!("BBBBBBB", paths[0].file_name().unwrap().to_string_lossy());
assert_eq!("aaaaaaa", paths[1].file_name().unwrap().to_string_lossy());
assert_eq!("zzzzzzz", paths[2].file_name().unwrap().to_string_lossy());
}}
"##,
2018-03-14 15:17:44 +00:00
dylib_path_envvar()
),
2018-12-08 11:19:47 +00:00
)
.build();
2018-01-20 17:57:17 +00:00
p.cargo("run").run();
2018-01-20 17:57:17 +00:00
}
#[cargo_test]
fn fail_no_extra_verbose() {
let p = project()
.file("src/main.rs", "fn main() { std::process::exit(1); }")
.build();
p.cargo("run -q")
.with_status(1)
.with_stdout("")
.with_stderr("")
.run();
}
#[cargo_test]
fn run_multiple_packages() {
let p = project()
.no_manifest()
2018-03-14 15:17:44 +00:00
.file(
"foo/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[workspace]
2020-09-27 00:59:58 +00:00
[dependencies]
d1 = { path = "d1" }
d2 = { path = "d2" }
d3 = { path = "../d3" } # outside of the workspace
2020-09-27 00:59:58 +00:00
[[bin]]
name = "foo"
"#,
2018-12-08 11:19:47 +00:00
)
.file("foo/src/foo.rs", "fn main() { println!(\"foo\"); }")
2018-07-24 22:35:01 +00:00
.file("foo/d1/Cargo.toml", &basic_bin_manifest("d1"))
.file("foo/d1/src/lib.rs", "")
.file("foo/d1/src/main.rs", "fn main() { println!(\"d1\"); }")
2018-07-24 22:35:01 +00:00
.file("foo/d2/Cargo.toml", &basic_bin_manifest("d2"))
.file("foo/d2/src/main.rs", "fn main() { println!(\"d2\"); }")
2018-07-24 22:35:01 +00:00
.file("d3/Cargo.toml", &basic_bin_manifest("d3"))
.file("d3/src/main.rs", "fn main() { println!(\"d2\"); }")
.build();
let cargo = || {
let mut process_builder = p.cargo("run");
process_builder.cwd("foo");
process_builder
};
cargo().arg("-p").arg("d1").with_stdout("d1").run();
cargo()
.arg("-p")
.arg("d2")
.arg("--bin")
.arg("d2")
.with_stdout("d2")
.run();
cargo().with_stdout("foo").run();
2022-09-20 18:19:46 +00:00
cargo()
.arg("-p")
.arg("d1")
.arg("-p")
.arg("d2")
.with_status(1)
.with_stderr_contains(
2023-01-13 18:26:29 +00:00
"error: the argument '--package [<SPEC>]' cannot be used multiple times",
2022-09-20 18:19:46 +00:00
)
.run();
cargo()
.arg("-p")
.arg("d3")
.with_status(101)
.with_stderr_contains("[ERROR] package(s) `d3` not found in workspace [..]")
.run();
cargo()
.arg("-p")
.arg("d*")
.with_status(101)
.with_stderr_contains(
"[ERROR] `cargo run` does not support glob pattern `d*` on package selection",
)
.run();
}
#[cargo_test]
fn explicit_bin_with_args() {
let p = project()
.file(
"src/main.rs",
r#"
2020-09-27 00:59:58 +00:00
fn main() {
assert_eq!(std::env::args().nth(1).unwrap(), "hello");
assert_eq!(std::env::args().nth(2).unwrap(), "world");
}
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("run --bin foo hello world").run();
}
2018-08-09 00:38:04 +00:00
#[cargo_test]
2018-08-09 00:38:04 +00:00
fn run_workspace() {
let p = project()
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[workspace]
members = ["a", "b"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("a/Cargo.toml", &basic_bin_manifest("a"))
2018-08-09 00:38:04 +00:00
.file("a/src/main.rs", r#"fn main() {println!("run-a");}"#)
.file("b/Cargo.toml", &basic_bin_manifest("b"))
.file("b/src/main.rs", r#"fn main() {println!("run-b");}"#)
.build();
p.cargo("run")
.with_status(101)
.with_stderr(
2018-08-09 00:38:04 +00:00
"\
2019-06-21 18:36:53 +00:00
[ERROR] `cargo run` could not determine which binary to run[..]
2018-08-09 00:38:04 +00:00
available binaries: a, b",
2018-12-08 11:19:47 +00:00
)
.run();
p.cargo("run --bin a").with_stdout("run-a").run();
2018-08-09 00:38:04 +00:00
}
#[cargo_test]
2018-08-09 00:38:04 +00:00
fn default_run_workspace() {
let p = project()
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[workspace]
members = ["a", "b"]
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-08-09 00:38:04 +00:00
"a/Cargo.toml",
r#"
[package]
2020-09-27 00:59:58 +00:00
name = "a"
version = "0.0.1"
default-run = "a"
"#,
2018-12-08 11:19:47 +00:00
)
.file("a/src/main.rs", r#"fn main() {println!("run-a");}"#)
2018-08-09 00:38:04 +00:00
.file("b/Cargo.toml", &basic_bin_manifest("b"))
.file("b/src/main.rs", r#"fn main() {println!("run-b");}"#)
.build();
2019-06-21 18:36:53 +00:00
p.cargo("run").with_stdout("run-a").run();
2018-08-09 00:38:04 +00:00
}
#[cargo_test]
fn print_env_verbose() {
let p = project()
.file("Cargo.toml", &basic_manifest("a", "0.0.1"))
.file("src/main.rs", r#"fn main() {println!("run-a");}"#)
.build();
p.cargo("run -vv")
.with_stderr(
"\
[COMPILING] a v0.0.1 ([CWD])
[RUNNING] `[..]CARGO_MANIFEST_DIR=[CWD][..] rustc --crate-name a[..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[RUNNING] `[..]CARGO_MANIFEST_DIR=[CWD][..] target/debug/a[EXE]`",
)
.run();
}
#[cargo_test]
#[cfg(target_os = "macos")]
fn run_link_system_path_macos() {
use cargo_test_support::paths::{self, CargoPathExt};
use std::fs;
// Check that the default system library path is honored.
// First, build a shared library that will be accessed from
// DYLD_FALLBACK_LIBRARY_PATH.
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
[lib]
crate-type = ["cdylib"]
"#,
)
.file(
"src/lib.rs",
"#[no_mangle] pub extern fn something_shared() {}",
)
.build();
p.cargo("build").run();
// This is convoluted. Since this test can't modify things in /usr,
// this needs to dance around to check that things work.
//
// The default DYLD_FALLBACK_LIBRARY_PATH is:
// $(HOME)/lib:/usr/local/lib:/lib:/usr/lib
//
// This will make use of ~/lib in the path, but the default cc link
// path is /usr/lib:/usr/local/lib. So first need to build in one
// location, and then move it to ~/lib.
//
// 1. Build with rustc-link-search pointing to libfoo so the initial
// binary can be linked.
// 2. Move the library to ~/lib
// 3. Run `cargo run` to make sure it can still find the library in
// ~/lib.
//
// This should be equivalent to having the library in /usr/local/lib.
let p2 = project()
.at("bar")
.file("Cargo.toml", &basic_bin_manifest("bar"))
.file(
"src/main.rs",
r#"
extern {
fn something_shared();
}
fn main() {
unsafe { something_shared(); }
}
"#,
)
.file(
"build.rs",
&format!(
r#"
2020-09-27 00:59:58 +00:00
fn main() {{
println!("cargo:rustc-link-lib=foo");
println!("cargo:rustc-link-search={}");
}}
"#,
p.target_debug_dir().display()
),
)
.build();
p2.cargo("build").run();
p2.cargo("test").run();
let libdir = paths::home().join("lib");
fs::create_dir(&libdir).unwrap();
fs::rename(
p.target_debug_dir().join("libfoo.dylib"),
libdir.join("libfoo.dylib"),
)
.unwrap();
p.root().rm_rf();
const VAR: &str = "DYLD_FALLBACK_LIBRARY_PATH";
// Reset DYLD_FALLBACK_LIBRARY_PATH so that we don't inherit anything that
// was set by the cargo that invoked the test.
p2.cargo("run").env_remove(VAR).run();
p2.cargo("test").env_remove(VAR).run();
// Ensure this still works when DYLD_FALLBACK_LIBRARY_PATH has
// a value set.
p2.cargo("run").env(VAR, &libdir).run();
p2.cargo("test").env(VAR, &libdir).run();
}