cargo/tests/testsuite/build.rs

6762 lines
180 KiB
Rust
Raw Normal View History

2019-11-25 02:42:45 +00:00
//! Tests for the `cargo build` command.
use cargo::{
core::compiler::CompileMode,
core::{Shell, Workspace},
ops::CompileOptions,
Config,
};
use cargo_test_support::compare;
use cargo_test_support::paths::{root, CargoPathExt};
use cargo_test_support::registry::Package;
use cargo_test_support::tools;
use cargo_test_support::{
basic_bin_manifest, basic_lib_manifest, basic_manifest, cargo_exe, git, is_nightly, main_file,
paths, process, project, rustc_host, sleep_ms, symlink_supported, t, Execs, ProjectBuilder,
};
2021-03-20 20:43:33 +00:00
use cargo_util::paths::dylib_path_envvar;
2019-09-12 19:52:46 +00:00
use std::env;
use std::fs;
use std::io::Read;
use std::process::Stdio;
#[cargo_test]
fn cargo_compile_simple() {
let p = project()
2015-03-26 18:17:44 +00:00
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.build();
p.cargo("build").run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
2014-05-09 00:50:28 +00:00
p.process(&p.bin("foo")).with_stdout("i am foo\n").run();
}
#[cargo_test]
fn cargo_fail_with_no_stderr() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &String::from("refusal"))
.build();
p.cargo("build --message-format=json")
.with_status(101)
.with_stderr_does_not_contain("--- stderr")
.run();
}
2019-02-03 04:01:23 +00:00
/// Checks that the `CARGO_INCREMENTAL` environment variable results in
2019-02-20 17:12:27 +00:00
/// `rustc` getting `-C incremental` passed to it.
#[cargo_test]
fn cargo_compile_incremental() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.build();
p.cargo("build -v")
.env("CARGO_INCREMENTAL", "1")
.with_stderr_contains(
"[RUNNING] `rustc [..] -C incremental=[..]/target/debug/incremental[..]`\n",
2018-12-08 11:19:47 +00:00
)
.run();
2017-01-11 16:30:12 +00:00
p.cargo("test -v")
.env("CARGO_INCREMENTAL", "1")
.with_stderr_contains(
"[RUNNING] `rustc [..] -C incremental=[..]/target/debug/incremental[..]`\n",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn incremental_profile() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.1.0"
authors = []
2020-09-27 00:59:58 +00:00
[profile.dev]
incremental = false
2020-09-27 00:59:58 +00:00
[profile.release]
incremental = true
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("build -v")
.env_remove("CARGO_INCREMENTAL")
.with_stderr_does_not_contain("[..]C incremental=[..]")
.run();
p.cargo("build -v")
.env("CARGO_INCREMENTAL", "1")
.with_stderr_contains("[..]C incremental=[..]")
.run();
p.cargo("build --release -v")
.env_remove("CARGO_INCREMENTAL")
.with_stderr_contains("[..]C incremental=[..]")
.run();
p.cargo("build --release -v")
.env("CARGO_INCREMENTAL", "0")
.with_stderr_does_not_contain("[..]C incremental=[..]")
.run();
}
#[cargo_test]
fn incremental_config() {
let p = project()
.file("src/main.rs", "fn main() {}")
2018-03-14 15:17:44 +00:00
.file(
2024-01-26 19:40:46 +00:00
".cargo/config.toml",
2018-03-14 15:17:44 +00:00
r#"
2020-09-27 00:59:58 +00:00
[build]
incremental = false
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("build -v")
.env_remove("CARGO_INCREMENTAL")
.with_stderr_does_not_contain("[..]C incremental=[..]")
.run();
p.cargo("build -v")
.env("CARGO_INCREMENTAL", "1")
.with_stderr_contains("[..]C incremental=[..]")
.run();
}
#[cargo_test]
fn cargo_compile_with_redundant_default_mode() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.build();
p.cargo("build --debug")
.with_stderr(
"\
error: unexpected argument '--debug' found
tip: `--debug` is the default for `cargo build`; instead `--release` is supported
Usage: cargo[EXE] build [OPTIONS]
For more information, try '--help'.
",
)
.with_status(1)
.run();
}
#[cargo_test]
fn cargo_compile_with_unsupported_short_config_flag() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.build();
p.cargo("build -c net.git-fetch-with-cli=true")
.with_stderr(
"\
error: unexpected argument '-c' found
tip: a similar argument exists: '--config'
Usage: cargo[EXE] build [OPTIONS]
For more information, try '--help'.
",
)
.with_status(1)
.run();
}
#[cargo_test]
fn cargo_compile_with_workspace_excluded() {
let p = project().file("src/main.rs", "fn main() {}").build();
2019-08-12 12:31:20 +00:00
p.cargo("build --workspace --exclude foo")
.with_stderr_does_not_contain("[..]virtual[..]")
.with_stderr_contains("[..]no packages to compile")
.with_status(101)
.run();
}
#[cargo_test]
fn cargo_compile_manifest_path() {
let p = project()
2015-03-26 18:17:44 +00:00
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.build();
p.cargo("build --manifest-path foo/Cargo.toml")
.cwd(p.root().parent().unwrap())
.run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
}
#[cargo_test]
fn cargo_compile_with_wrong_manifest_path_flag() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.build();
p.cargo("build --path foo/Cargo.toml")
.cwd(p.root().parent().unwrap())
.with_stderr(
"\
error: unexpected argument '--path' found
tip: a similar argument exists: '--manifest-path'
Usage: cargo[EXE] build [OPTIONS]
For more information, try '--help'.
",
)
.with_status(1)
.run();
}
2023-04-12 02:42:28 +00:00
#[cargo_test]
fn chdir_gated() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.build();
p.cargo("-C foo build")
.cwd(p.root().parent().unwrap())
.with_stderr(
"error: the `-C` flag is unstable, \
pass `-Z unstable-options` on the nightly channel to enable it",
)
.with_status(101)
.run();
// No masquerade should also fail.
p.cargo("-C foo -Z unstable-options build")
.cwd(p.root().parent().unwrap())
.with_stderr(
"error: the `-C` flag is unstable, \
pass `-Z unstable-options` on the nightly channel to enable it",
)
.with_status(101)
.run();
}
#[cargo_test]
fn cargo_compile_directory_not_cwd() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.file(".cargo/config.toml", &"")
.build();
2023-04-12 02:42:28 +00:00
p.cargo("-Zunstable-options -C foo build")
.masquerade_as_nightly_cargo(&["chdir"])
.cwd(p.root().parent().unwrap())
.run();
assert!(p.bin("foo").is_file());
}
#[cargo_test]
fn cargo_compile_with_unsupported_short_unstable_feature_flag() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.file(".cargo/config.toml", &"")
.build();
p.cargo("-zunstable-options -C foo build")
.masquerade_as_nightly_cargo(&["chdir"])
.cwd(p.root().parent().unwrap())
.with_stderr(
"\
error: unexpected argument '-z' found
tip: a similar argument exists: '-Z'
Usage: cargo [..][OPTIONS] [COMMAND]
cargo [..][OPTIONS] -Zscript <MANIFEST_RS> [ARGS]...
For more information, try '--help'.
",
)
.with_status(1)
.run();
}
#[cargo_test]
fn cargo_compile_directory_not_cwd_with_invalid_config() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.file(".cargo/config.toml", &"!")
.build();
2023-04-12 02:42:28 +00:00
p.cargo("-Zunstable-options -C foo build")
.masquerade_as_nightly_cargo(&["chdir"])
.cwd(p.root().parent().unwrap())
.with_status(101)
.with_stderr_contains(
"\
Caused by:
TOML parse error at line 1, column 1
|
1 | !
| ^
invalid key
",
)
.run();
}
#[cargo_test]
fn cargo_compile_with_invalid_manifest() {
let p = project().file("Cargo.toml", "").build();
2014-05-09 00:50:28 +00:00
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
virtual manifests must be configured with [workspace]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn cargo_compile_with_invalid_manifest2() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
2020-09-27 00:59:58 +00:00
"
[package]
2020-09-27 00:59:58 +00:00
foo = bar
",
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] invalid string
expected `\"`, `'`
--> Cargo.toml:3:23
|
3 | foo = bar
| ^
|
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
2014-05-09 00:50:28 +00:00
#[cargo_test]
fn cargo_compile_with_invalid_manifest3() {
let p = project().file("src/Cargo.toml", "a = bar").build();
p.cargo("build --manifest-path src/Cargo.toml")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] invalid string
expected `\"`, `'`
--> src/Cargo.toml:1:5
|
1 | a = bar
| ^
|
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
2016-07-10 17:29:31 +00:00
fn cargo_compile_duplicate_build_targets() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
authors = []
2016-07-10 17:29:31 +00:00
2020-09-27 00:59:58 +00:00
[lib]
name = "main"
path = "src/main.rs"
crate-type = ["dylib"]
2016-07-10 17:29:31 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "#![allow(warnings)] fn main() {}")
.build();
2016-07-10 17:29:31 +00:00
p.cargo("build")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
warning: file `[..]main.rs` found to be present in multiple build targets:
* `lib` target `main`
* `bin` target `foo`
[COMPILING] foo v0.0.1 ([..])
[FINISHED] [..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
2016-07-10 17:29:31 +00:00
}
#[cargo_test]
fn cargo_compile_with_invalid_version() {
let p = project()
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("foo", "1.0"))
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] unexpected end of input while parsing minor version number
--> Cargo.toml:4:19
|
4 | version = \"1.0\"
| ^^^^^
|
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn cargo_compile_with_empty_package_name() {
let p = project()
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("", "0.0.0"))
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] package name cannot be empty
--> Cargo.toml:3:16
|
3 | name = \"\"
| ^^
|
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn cargo_compile_with_invalid_package_name() {
let p = project()
.file("Cargo.toml", &basic_manifest("foo::bar", "0.0.0"))
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
"\
[ERROR] invalid character `:` in package name: `foo::bar`, characters must be Unicode XID characters (numbers, `-`, `_`, or most letters)
--> Cargo.toml:3:16
|
3 | name = \"foo::bar\"
| ^^^^^^^^^^
|
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn cargo_compile_with_invalid_bin_target_name() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
authors = []
version = "0.0.0"
2020-09-27 00:59:58 +00:00
[[bin]]
name = ""
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
2017-07-08 21:59:31 +00:00
binary target names cannot be empty
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn cargo_compile_with_forbidden_bin_target_name() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
authors = []
version = "0.0.0"
2020-09-27 00:59:58 +00:00
[[bin]]
name = "build"
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
the binary target name `build` is forbidden, it conflicts with cargo's build directory names
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn cargo_compile_with_bin_and_crate_type() {
let p = project()
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
authors = []
version = "0.0.0"
2020-09-27 00:59:58 +00:00
[[bin]]
name = "the_foo_bin"
path = "src/foo.rs"
crate-type = ["cdylib", "rlib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/foo.rs", "fn main() {}")
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
the target `the_foo_bin` is a binary and can't have any crate-types set \
(currently \"cdylib, rlib\")",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn cargo_compile_api_exposes_artifact_paths() {
let p = project()
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
authors = []
version = "0.0.0"
2020-09-27 00:59:58 +00:00
[[bin]]
name = "the_foo_bin"
path = "src/bin.rs"
2020-09-27 00:59:58 +00:00
[lib]
name = "the_foo_lib"
path = "src/foo.rs"
crate-type = ["cdylib", "rlib"]
"#,
)
.file("src/foo.rs", "pub fn bar() {}")
.file("src/bin.rs", "pub fn main() {}")
.build();
let shell = Shell::from_write(Box::new(Vec::new()));
let config = Config::new(shell, env::current_dir().unwrap(), paths::home());
let ws = Workspace::new(&p.root().join("Cargo.toml"), &config).unwrap();
let compile_options = CompileOptions::new(ws.config(), CompileMode::Build).unwrap();
let result = cargo::ops::compile(&ws, &compile_options).unwrap();
assert_eq!(1, result.binaries.len());
assert!(result.binaries[0].path.exists());
assert!(result.binaries[0]
.path
.to_str()
.unwrap()
.contains("the_foo_bin"));
assert_eq!(1, result.cdylibs.len());
// The exact library path varies by platform, but should certainly exist at least
assert!(result.cdylibs[0].path.exists());
assert!(result.cdylibs[0]
.path
.to_str()
.unwrap()
.contains("the_foo_lib"));
}
#[cargo_test]
fn cargo_compile_with_bin_and_proc() {
let p = project()
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
authors = []
version = "0.0.0"
2020-09-27 00:59:58 +00:00
[[bin]]
name = "the_foo_bin"
path = "src/foo.rs"
proc-macro = true
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/foo.rs", "fn main() {}")
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
the target `the_foo_bin` is a binary and can't have `proc-macro` set `true`",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn cargo_compile_with_invalid_lib_target_name() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
authors = []
version = "0.0.0"
2020-09-27 00:59:58 +00:00
[lib]
name = ""
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
2017-07-08 21:59:31 +00:00
library target names cannot be empty
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn cargo_compile_with_invalid_non_numeric_dep_version() {
let p = project()
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.1"
2020-09-27 00:59:58 +00:00
[dependencies]
crossbeam = "y"
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
Caused by:
failed to parse the version requirement `y` for dependency `crossbeam`
Caused by:
2021-05-25 23:46:11 +00:00
unexpected character 'y' while parsing major version number
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn cargo_compile_without_manifest() {
let p = project().no_manifest().build();
2014-05-09 00:50:28 +00:00
p.cargo("build")
.with_status(101)
.with_stderr("[ERROR] could not find `Cargo.toml` in `[..]` or any parent directory")
.run();
}
#[cargo_test]
2021-06-22 07:36:32 +00:00
#[cfg(target_os = "linux")]
fn cargo_compile_with_lowercase_cargo_toml() {
let p = project()
.no_manifest()
.file("cargo.toml", &basic_manifest("foo", "0.1.0"))
.file("src/lib.rs", &main_file(r#""i am foo""#, &[]))
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
"[ERROR] could not find `Cargo.toml` in `[..]` or any parent directory, \
but found cargo.toml please try to rename it to Cargo.toml",
)
.run();
}
#[cargo_test]
fn cargo_compile_with_invalid_code() {
let p = project()
2015-03-26 18:17:44 +00:00
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", "invalid rust code!")
.build();
p.cargo("build")
.with_status(101)
.with_stderr_contains(
2023-08-09 15:19:59 +00:00
"[ERROR] could not compile `foo` (bin \"foo\") due to 1 previous error\n",
)
2018-12-08 11:19:47 +00:00
.run();
2018-08-29 06:11:10 +00:00
assert!(p.root().join("Cargo.lock").is_file());
}
#[cargo_test]
fn cargo_compile_with_invalid_code_in_deps() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[dependencies.bar]
path = "../bar"
[dependencies.baz]
path = "../baz"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "invalid rust code!")
.build();
let _bar = project()
.at("bar")
.file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("src/lib.rs", "invalid rust code!")
.build();
let _baz = project()
.at("baz")
.file("Cargo.toml", &basic_manifest("baz", "0.1.0"))
.file("src/lib.rs", "invalid rust code!")
.build();
p.cargo("build")
.with_status(101)
.with_stderr_contains("[..]invalid rust code[..]")
.with_stderr_contains("[ERROR] could not compile [..]")
.run();
}
#[cargo_test]
fn cargo_compile_with_warnings_in_the_root_package() {
let p = project()
2015-03-26 18:17:44 +00:00
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", "fn main() {} fn dead() {}")
.build();
p.cargo("build")
.with_stderr_contains("[WARNING] [..]dead[..]")
.run();
}
#[cargo_test]
fn cargo_compile_with_warnings_in_a_dep_package() {
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.5.0"
authors = ["wycats@example.com"]
2020-09-27 00:59:58 +00:00
[dependencies.bar]
path = "bar"
2020-09-27 00:59:58 +00:00
[[bin]]
2020-09-27 00:59:58 +00:00
name = "foo"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
2018-07-24 22:35:01 +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 gimme() -> &'static str {
"test passed"
}
2020-09-27 00:59:58 +00:00
fn dead() {}
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("build")
.with_stderr_contains("[WARNING] [..]dead[..]")
.run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
p.process(&p.bin("foo")).with_stdout("test passed\n").run();
}
2014-05-09 00:50:28 +00:00
#[cargo_test]
fn cargo_compile_with_nested_deps_inferred() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
[package]
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.5.0"
authors = ["wycats@example.com"]
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
[dependencies.bar]
path = 'bar'
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
[[bin]]
name = "foo"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
2018-03-14 15:17:44 +00:00
.file(
"bar/Cargo.toml",
r#"
[package]
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
name = "bar"
version = "0.5.0"
authors = ["wycats@example.com"]
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
[dependencies.baz]
path = "../baz"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"bar/src/lib.rs",
r#"
2020-09-27 00:59:58 +00:00
extern crate baz;
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
pub fn gimme() -> String {
baz::gimme()
}
"#,
2018-12-08 11:19:47 +00:00
)
.file("baz/Cargo.toml", &basic_manifest("baz", "0.5.0"))
2018-03-14 15:17:44 +00:00
.file(
"baz/src/lib.rs",
r#"
2020-09-27 00:59:58 +00:00
pub fn gimme() -> String {
"test passed".to_string()
}
"#,
2018-12-08 11:19:47 +00:00
)
.build();
2014-07-08 00:59:18 +00:00
p.cargo("build").run();
2014-07-08 00:59:18 +00:00
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
assert!(!p.bin("libbar.rlib").is_file());
assert!(!p.bin("libbaz.rlib").is_file());
2014-07-08 00:59:18 +00:00
p.process(&p.bin("foo")).with_stdout("test passed\n").run();
}
2014-07-08 00:59:18 +00:00
#[cargo_test]
fn cargo_compile_with_nested_deps_correct_bin() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
[package]
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.5.0"
authors = ["wycats@example.com"]
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
[dependencies.bar]
path = "bar"
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
[[bin]]
name = "foo"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
2018-03-14 15:17:44 +00:00
.file(
"bar/Cargo.toml",
r#"
[package]
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
name = "bar"
version = "0.5.0"
authors = ["wycats@example.com"]
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
[dependencies.baz]
path = "../baz"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"bar/src/lib.rs",
r#"
2020-09-27 00:59:58 +00:00
extern crate baz;
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
pub fn gimme() -> String {
baz::gimme()
}
"#,
2018-12-08 11:19:47 +00:00
)
.file("baz/Cargo.toml", &basic_manifest("baz", "0.5.0"))
2018-03-14 15:17:44 +00:00
.file(
"baz/src/lib.rs",
r#"
2020-09-27 00:59:58 +00:00
pub fn gimme() -> String {
"test passed".to_string()
}
"#,
2018-12-08 11:19:47 +00:00
)
.build();
2014-07-08 00:59:18 +00:00
p.cargo("build").run();
2014-07-08 00:59:18 +00:00
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
assert!(!p.bin("libbar.rlib").is_file());
assert!(!p.bin("libbaz.rlib").is_file());
2014-07-08 00:59:18 +00:00
p.process(&p.bin("foo")).with_stdout("test passed\n").run();
}
2014-07-08 00:59:18 +00:00
#[cargo_test]
fn cargo_compile_with_nested_deps_shorthand() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
[package]
2014-05-08 23:49:58 +00:00
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.5.0"
authors = ["wycats@example.com"]
2014-05-08 23:49:58 +00:00
2020-09-27 00:59:58 +00:00
[dependencies.bar]
path = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
2018-03-14 15:17:44 +00:00
.file(
"bar/Cargo.toml",
r#"
[package]
2014-05-08 23:49:58 +00:00
2020-09-27 00:59:58 +00:00
name = "bar"
version = "0.5.0"
authors = ["wycats@example.com"]
2014-05-08 23:49:58 +00:00
2020-09-27 00:59:58 +00:00
[dependencies.baz]
path = "../baz"
2014-05-08 23:49:58 +00:00
2020-09-27 00:59:58 +00:00
[lib]
2014-05-08 23:49:58 +00:00
2020-09-27 00:59:58 +00:00
name = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"bar/src/bar.rs",
r#"
2020-09-27 00:59:58 +00:00
extern crate baz;
2014-05-08 23:49:58 +00:00
2020-09-27 00:59:58 +00:00
pub fn gimme() -> String {
baz::gimme()
}
"#,
2018-12-08 11:19:47 +00:00
)
.file("baz/Cargo.toml", &basic_lib_manifest("baz"))
2018-03-14 15:17:44 +00:00
.file(
"baz/src/baz.rs",
r#"
2020-09-27 00:59:58 +00:00
pub fn gimme() -> String {
"test passed".to_string()
}
"#,
2018-12-08 11:19:47 +00:00
)
.build();
2014-05-08 23:49:58 +00:00
p.cargo("build").run();
2014-05-08 23:49:58 +00:00
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
assert!(!p.bin("libbar.rlib").is_file());
assert!(!p.bin("libbaz.rlib").is_file());
2014-05-08 23:49:58 +00:00
p.process(&p.bin("foo")).with_stdout("test passed\n").run();
}
2014-05-08 23:49:58 +00:00
#[cargo_test]
fn cargo_compile_with_nested_deps_longhand() {
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.5.0"
authors = ["wycats@example.com"]
2020-09-27 00:59:58 +00:00
[dependencies.bar]
path = "bar"
version = "0.5.0"
2020-09-27 00:59:58 +00:00
[[bin]]
2020-09-27 00:59:58 +00:00
name = "foo"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
2018-03-14 15:17:44 +00:00
.file(
"bar/Cargo.toml",
r#"
[package]
2020-09-27 00:59:58 +00:00
name = "bar"
version = "0.5.0"
authors = ["wycats@example.com"]
2020-09-27 00:59:58 +00:00
[dependencies.baz]
path = "../baz"
version = "0.5.0"
2020-09-27 00:59:58 +00:00
[lib]
2020-09-27 00:59:58 +00:00
name = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"bar/src/bar.rs",
r#"
2020-09-27 00:59:58 +00:00
extern crate baz;
2020-09-27 00:59:58 +00:00
pub fn gimme() -> String {
baz::gimme()
}
"#,
2018-12-08 11:19:47 +00:00
)
.file("baz/Cargo.toml", &basic_lib_manifest("baz"))
2018-03-14 15:17:44 +00:00
.file(
"baz/src/baz.rs",
r#"
2020-09-27 00:59:58 +00:00
pub fn gimme() -> String {
"test passed".to_string()
}
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("build").run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
assert!(!p.bin("libbar.rlib").is_file());
assert!(!p.bin("libbaz.rlib").is_file());
p.process(&p.bin("foo")).with_stdout("test passed\n").run();
}
// Check that Cargo gives a sensible error if a dependency can't be found
// because of a name mismatch.
#[cargo_test]
fn cargo_compile_with_dep_name_mismatch() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.0.1"
authors = ["wycats@example.com"]
2020-09-27 00:59:58 +00:00
[[bin]]
2020-09-27 00:59:58 +00:00
name = "foo"
2020-09-27 00:59:58 +00:00
[dependencies.notquitebar]
2020-09-27 00:59:58 +00:00
path = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/bin/foo.rs", &main_file(r#""i am foo""#, &["bar"]))
2015-03-26 18:17:44 +00:00
.file("bar/Cargo.toml", &basic_bin_manifest("bar"))
.file("bar/src/bar.rs", &main_file(r#""i am bar""#, &[]))
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
2020-09-27 00:59:58 +00:00
"\
error: no matching package named `notquitebar` found
location searched: [CWD]/bar
required by package `foo v0.0.1 ([CWD])`
2020-09-27 00:59:58 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
2020-04-09 06:46:30 +00:00
// Ensure that renamed deps have a valid name
#[cargo_test]
fn cargo_compile_with_invalid_dep_rename() {
let p = project()
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "buggin"
version = "0.1.0"
2020-04-09 06:46:30 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
"haha this isn't a valid name 🐛" = { package = "libc", version = "0.1" }
"#,
2020-04-09 06:46:30 +00:00
)
.file("src/main.rs", &main_file(r#""What's good?""#, &[]))
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
"\
[ERROR] invalid character ` ` in package name: `haha this isn't a valid name 🐛`, characters must be Unicode XID characters (numbers, `-`, `_`, or most letters)
--> Cargo.toml:7:17
|
7 | \"haha this isn't a valid name 🐛\" = { package = \"libc\", version = \"0.1\" }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
2020-04-09 06:46:30 +00:00
",
)
.run();
}
#[cargo_test]
fn cargo_compile_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("build --bin bin.rs")
.with_status(101)
.with_stderr(
"\
[ERROR] no bin target named `bin.rs`.
Available bin targets:
a
",
)
.run();
p.cargo("build --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("build --example example.rs")
.with_status(101)
.with_stderr(
"\
[ERROR] no example target named `example.rs`.
Available example targets:
a
",
)
.run();
p.cargo("build --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 incompatible_dependencies() {
Package::new("bad", "0.1.0").publish();
Package::new("bad", "1.0.0").publish();
Package::new("bad", "1.0.1").publish();
Package::new("bad", "1.0.2").publish();
Package::new("bar", "0.1.0").dep("bad", "0.1.0").publish();
Package::new("baz", "0.1.1").dep("bad", "=1.0.0").publish();
Package::new("baz", "0.1.0").dep("bad", "=1.0.0").publish();
Package::new("qux", "0.1.2").dep("bad", ">=1.0.1").publish();
Package::new("qux", "0.1.1").dep("bad", ">=1.0.1").publish();
Package::new("qux", "0.1.0").dep("bad", ">=1.0.1").publish();
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"
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1.0"
baz = "0.1.0"
qux = "0.1.0"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "fn main(){}")
.build();
p.cargo("build")
.with_status(101)
.with_stderr_contains(
2018-03-14 15:17:44 +00:00
"\
error: failed to select a version for `bad`.
... required by package `qux v0.1.0`
... which satisfies dependency `qux = \"^0.1.0\"` of package `foo v0.0.1 ([..])`
versions that meet the requirements `>=1.0.1` are: 1.0.2, 1.0.1
2018-02-15 03:28:59 +00:00
all possible versions conflict with previously selected packages.
2018-02-07 16:51:40 +00:00
previously selected package `bad v1.0.0`
... which satisfies dependency `bad = \"=1.0.0\"` of package `baz v0.1.0`
... which satisfies dependency `baz = \"^0.1.0\"` of package `foo v0.0.1 ([..])`
2018-02-15 03:28:59 +00:00
2018-03-14 15:17:44 +00:00
failed to select a version for `bad` which could resolve this conflict",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn incompatible_dependencies_with_multi_semver() {
Package::new("bad", "1.0.0").publish();
Package::new("bad", "1.0.1").publish();
Package::new("bad", "2.0.0").publish();
Package::new("bad", "2.0.1").publish();
Package::new("bar", "0.1.0").dep("bad", "=1.0.0").publish();
Package::new("baz", "0.1.0").dep("bad", ">=2.0.1").publish();
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"
2020-09-27 00:59:58 +00:00
[dependencies]
bar = "0.1.0"
baz = "0.1.0"
bad = ">=1.0.1, <=2.0.0"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "fn main(){}")
.build();
p.cargo("build")
.with_status(101)
.with_stderr_contains(
2018-03-14 15:17:44 +00:00
"\
error: failed to select a version for `bad`.
... required by package `foo v0.0.1 ([..])`
versions that meet the requirements `>=1.0.1, <=2.0.0` are: 2.0.0, 1.0.1
2018-02-15 03:28:59 +00:00
all possible versions conflict with previously selected packages.
2018-02-15 03:28:59 +00:00
previously selected package `bad v2.0.1`
... which satisfies dependency `bad = \">=2.0.1\"` of package `baz v0.1.0`
... which satisfies dependency `baz = \"^0.1.0\"` of package `foo v0.0.1 ([..])`
2018-02-15 03:28:59 +00:00
previously selected package `bad v1.0.0`
... which satisfies dependency `bad = \"=1.0.0\"` of package `bar v0.1.0`
... which satisfies dependency `bar = \"^0.1.0\"` of package `foo v0.0.1 ([..])`
2018-02-15 03:28:59 +00:00
2018-03-14 15:17:44 +00:00
failed to select a version for `bad` which could resolve this conflict",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn compile_path_dep_then_change_version() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[dependencies.bar]
path = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
2018-07-24 22:35:01 +00:00
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
.file("bar/src/lib.rs", "")
.build();
p.cargo("build").run();
p.change_file("bar/Cargo.toml", &basic_manifest("bar", "0.0.2"));
p.cargo("build").run();
}
#[cargo_test]
fn ignores_carriage_return_in_lockfile() {
let p = project()
2020-09-27 00:59:58 +00:00
.file("src/main.rs", "mod a; fn main() {}")
.file("src/a.rs", "")
.build();
p.cargo("build").run();
let lock = p.read_lockfile();
p.change_file("Cargo.lock", &lock.replace("\n", "\r\n"));
p.cargo("build").run();
}
#[cargo_test]
fn cargo_default_env_metadata_env_var() {
// Ensure that path dep + dylib + env_var get metadata
// (even though path_dep + dylib should not)
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[dependencies.bar]
path = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "// hi")
2018-03-14 15:17:44 +00:00
.file(
"bar/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "bar"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[lib]
name = "bar"
crate_type = ["dylib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("bar/src/lib.rs", "// hello")
.build();
// No metadata on libbar since it's a dylib path dependency
p.cargo("build -v")
.with_stderr(&format!(
2018-03-14 15:17:44 +00:00
"\
[COMPILING] bar v0.0.1 ([CWD]/bar)
2019-09-25 01:17:36 +00:00
[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type dylib \
--emit=[..]link \
-C prefer-dynamic[..]-C debuginfo=2 [..]\
-C metadata=[..] \
--out-dir [..] \
-L dependency=[CWD]/target/debug/deps`
[COMPILING] foo v0.0.1 ([CWD])
2019-09-25 01:17:36 +00:00
[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
--emit=[..]link[..]-C debuginfo=2 [..]\
-C metadata=[..] \
-C extra-filename=[..] \
--out-dir [..] \
-L dependency=[CWD]/target/debug/deps \
--extern bar=[CWD]/target/debug/deps/{prefix}bar{suffix}`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
2018-03-14 15:17:44 +00:00
prefix = env::consts::DLL_PREFIX,
suffix = env::consts::DLL_SUFFIX,
2018-12-08 11:19:47 +00:00
))
.run();
p.cargo("clean").run();
// If you set the env-var, then we expect metadata on libbar
p.cargo("build -v")
.env("__CARGO_DEFAULT_LIB_METADATA", "stable")
.with_stderr(&format!(
2018-03-14 15:17:44 +00:00
"\
[COMPILING] bar v0.0.1 ([CWD]/bar)
2019-09-25 01:17:36 +00:00
[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type dylib \
--emit=[..]link \
-C prefer-dynamic[..]-C debuginfo=2 [..]\
-C metadata=[..] \
--out-dir [..] \
-L dependency=[CWD]/target/debug/deps`
[COMPILING] foo v0.0.1 ([CWD])
2019-09-25 01:17:36 +00:00
[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
--emit=[..]link[..]-C debuginfo=2 [..]\
-C metadata=[..] \
-C extra-filename=[..] \
--out-dir [..] \
-L dependency=[CWD]/target/debug/deps \
--extern bar=[CWD]/target/debug/deps/{prefix}bar-[..]{suffix}`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
2018-03-14 15:17:44 +00:00
prefix = env::consts::DLL_PREFIX,
suffix = env::consts::DLL_SUFFIX,
2018-12-08 11:19:47 +00:00
))
.run();
}
#[cargo_test]
fn crate_env_vars() {
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.5.1-alpha.1"
description = "This is foo"
homepage = "https://example.com"
repository = "https://example.com/repo.git"
authors = ["wycats@example.com"]
license = "MIT OR Apache-2.0"
license-file = "license.txt"
2022-05-28 16:41:41 +00:00
rust-version = "1.61.0"
2023-01-28 10:05:16 +00:00
readme = "../../README.md"
2020-09-27 00:59:58 +00:00
[[bin]]
name = "foo-bar"
path = "src/main.rs"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"src/main.rs",
r#"
2020-09-27 00:59:58 +00:00
extern crate foo;
2014-07-24 00:57:49 +00:00
2020-09-27 00:59:58 +00:00
static VERSION_MAJOR: &'static str = env!("CARGO_PKG_VERSION_MAJOR");
static VERSION_MINOR: &'static str = env!("CARGO_PKG_VERSION_MINOR");
static VERSION_PATCH: &'static str = env!("CARGO_PKG_VERSION_PATCH");
static VERSION_PRE: &'static str = env!("CARGO_PKG_VERSION_PRE");
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
static CARGO_MANIFEST_DIR: &'static str = env!("CARGO_MANIFEST_DIR");
static PKG_NAME: &'static str = env!("CARGO_PKG_NAME");
static HOMEPAGE: &'static str = env!("CARGO_PKG_HOMEPAGE");
static REPOSITORY: &'static str = env!("CARGO_PKG_REPOSITORY");
static LICENSE: &'static str = env!("CARGO_PKG_LICENSE");
static LICENSE_FILE: &'static str = env!("CARGO_PKG_LICENSE_FILE");
static DESCRIPTION: &'static str = env!("CARGO_PKG_DESCRIPTION");
2022-05-28 16:41:41 +00:00
static RUST_VERSION: &'static str = env!("CARGO_PKG_RUST_VERSION");
2023-01-28 10:05:16 +00:00
static README: &'static str = env!("CARGO_PKG_README");
2020-09-27 00:59:58 +00:00
static BIN_NAME: &'static str = env!("CARGO_BIN_NAME");
static CRATE_NAME: &'static str = env!("CARGO_CRATE_NAME");
2014-07-24 00:57:49 +00:00
2020-09-27 00:59:58 +00:00
fn main() {
let s = format!("{}-{}-{} @ {} in {}", VERSION_MAJOR,
VERSION_MINOR, VERSION_PATCH, VERSION_PRE,
CARGO_MANIFEST_DIR);
assert_eq!(s, foo::version());
println!("{}", s);
assert_eq!("foo", PKG_NAME);
assert_eq!("foo-bar", BIN_NAME);
assert_eq!("foo_bar", CRATE_NAME);
assert_eq!("https://example.com", HOMEPAGE);
assert_eq!("https://example.com/repo.git", REPOSITORY);
assert_eq!("MIT OR Apache-2.0", LICENSE);
assert_eq!("license.txt", LICENSE_FILE);
2020-09-27 00:59:58 +00:00
assert_eq!("This is foo", DESCRIPTION);
2022-05-28 16:41:41 +00:00
assert_eq!("1.61.0", RUST_VERSION);
2023-01-28 10:05:16 +00:00
assert_eq!("../../README.md", README);
2020-09-27 00:59:58 +00:00
let s = format!("{}.{}.{}-{}", VERSION_MAJOR,
VERSION_MINOR, VERSION_PATCH, VERSION_PRE);
assert_eq!(s, VERSION);
// Verify CARGO_TARGET_TMPDIR isn't set for bins
assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
// Verify CARGO_RUSTC_CURRENT_DIR is set for examples
let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
let file_path = workspace_dir.join(file!());
assert!(file_path.exists(), "{}", file_path.display());
2020-09-27 00:59:58 +00:00
}
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"src/lib.rs",
r#"
use std::env;
use std::path::PathBuf;
2020-09-27 00:59:58 +00:00
pub fn version() -> String {
format!("{}-{}-{} @ {} in {}",
env!("CARGO_PKG_VERSION_MAJOR"),
env!("CARGO_PKG_VERSION_MINOR"),
env!("CARGO_PKG_VERSION_PATCH"),
env!("CARGO_PKG_VERSION_PRE"),
env!("CARGO_MANIFEST_DIR"))
}
pub fn check_no_int_test_env() {
env::var("CARGO_TARGET_DIR").unwrap_err();
}
pub fn check_tmpdir(tmp: Option<&'static str>) {
let tmpdir: PathBuf = tmp.unwrap().into();
let exe: PathBuf = env::current_exe().unwrap().into();
2021-08-20 19:12:42 +00:00
let mut expected: PathBuf = exe.parent().unwrap()
.parent().unwrap()
.parent().unwrap()
.into();
expected.push("tmp");
assert_eq!(tmpdir, expected);
// Check that CARGO_TARGET_TMPDIR isn't set for lib code
assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
env::var("CARGO_TARGET_TMPDIR").unwrap_err();
// Verify CARGO_RUSTC_CURRENT_DIR is set for examples
let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
let file_path = workspace_dir.join(file!());
assert!(file_path.exists(), "{}", file_path.display());
}
#[test]
fn unit_env_cargo_target_tmpdir() {
// Check that CARGO_TARGET_TMPDIR isn't set for unit tests
assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
env::var("CARGO_TARGET_TMPDIR").unwrap_err();
}
#[test]
fn unit_env_cargo_rustc_current_dir() {
let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
let file_path = workspace_dir.join(file!());
assert!(file_path.exists(), "{}", file_path.display());
}
2020-09-27 00:59:58 +00:00
"#,
2018-12-08 11:19:47 +00:00
)
.file(
"examples/ex-env-vars.rs",
r#"
static PKG_NAME: &'static str = env!("CARGO_PKG_NAME");
static BIN_NAME: &'static str = env!("CARGO_BIN_NAME");
static CRATE_NAME: &'static str = env!("CARGO_CRATE_NAME");
fn main() {
assert_eq!("foo", PKG_NAME);
assert_eq!("ex-env-vars", BIN_NAME);
assert_eq!("ex_env_vars", CRATE_NAME);
// Verify CARGO_TARGET_TMPDIR isn't set for examples
assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
// Verify CARGO_RUSTC_CURRENT_DIR is set for examples
let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
let file_path = workspace_dir.join(file!());
assert!(file_path.exists(), "{}", file_path.display());
}
"#,
)
.file(
"tests/env.rs",
r#"
#[test]
fn integration_env_cargo_target_tmpdir() {
foo::check_tmpdir(option_env!("CARGO_TARGET_TMPDIR"));
}
#[test]
fn integration_env_cargo_rustc_current_dir() {
let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
let file_path = workspace_dir.join(file!());
assert!(file_path.exists(), "{}", file_path.display());
}
"#,
);
let p = if is_nightly() {
p.file(
"benches/env.rs",
r#"
#![feature(test)]
extern crate test;
use test::Bencher;
#[bench]
fn bench_env_cargo_target_tmpdir(_: &mut Bencher) {
foo::check_tmpdir(option_env!("CARGO_TARGET_TMPDIR"));
}
#[test]
fn bench_env_cargo_rustc_current_dir() {
let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
let file_path = workspace_dir.join(file!());
assert!(file_path.exists(), "{}", file_path.display());
}
"#,
)
.build()
} else {
p.build()
};
2014-07-24 00:57:49 +00:00
Overhaul how cargo treats profiles This commit is a complete overhaul of how Cargo handles compilation profiles internally. The external interface of Cargo is not affected by this change. Previously each Target had a Profile embedded within it. Conceptually a Target is an entry in the manifest (a binary, benchmark, etc) and a Profile controlled various flags (e.g. --test, -C opt-level, etc). Each Package then contained many profiles for each possible compilation mode. For example a Package would have one target for testing a library, benchmarking a library, documenting a library, etc. When it came to building these targets, Cargo would filter out the targets listed to determine what needed to be built. This filtering was largely done based off an "environment" represented as a string. Each mode of compilation got a separate environment string like `"test"` or `"bench"`. Altogether, however, this approach had a number of drawbacks: * Examples in release mode do not currently work. This is due to how examples are classified and how release mode is handled (e.g. the "release" environment where examples are meant to be built in the "test" environment). * It is not trivial to implement `cargo test --release` today. * It is not trivial to implement `cargo build --bin foo` where *only* the binary `foo` is built. The same is true for examples. * It is not trivial to add selective building of a number of binaries/examples/etc. * Filtering the list of targets to build has some pretty hokey logic that involves pseudo-environments like "doc-all" vs "doc". This logic is duplicated in a few places and in general is quite brittle. * The TOML parser greatly affects compilation due to the time at which profiles are generated, which seems somewhat backwards. * Profiles must be overridden, but only partially, at compile time becuase only the top-level package's profile is applied. In general, this system just needed an overhaul. This commit made a single change of separating `Profile` from `Target` and then basically hit `make` until all the tests passed again. The other large architectural changes are: * Environment strings are now entirely gone. * Filters are implemented in a much more robust fashion. * Release mode is now handled much more gracefully. * The unit of compilation in the backend is no longer (package, target) but rather (package, target, profile). This change had to be propagated many location in the `cargo_rustc` module. * The backend does not filter targets to build *at all*. All filtering now happens entirely in the frontend. I'll test issues after this change lands, but the motivation behind this is to open the door to quickly fixing a number of outstanding issues against Cargo. This change itself is not intended to close many bugs.
2015-02-19 19:30:35 +00:00
println!("build");
p.cargo("build -v")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.run();
2014-07-24 00:57:49 +00:00
Overhaul how cargo treats profiles This commit is a complete overhaul of how Cargo handles compilation profiles internally. The external interface of Cargo is not affected by this change. Previously each Target had a Profile embedded within it. Conceptually a Target is an entry in the manifest (a binary, benchmark, etc) and a Profile controlled various flags (e.g. --test, -C opt-level, etc). Each Package then contained many profiles for each possible compilation mode. For example a Package would have one target for testing a library, benchmarking a library, documenting a library, etc. When it came to building these targets, Cargo would filter out the targets listed to determine what needed to be built. This filtering was largely done based off an "environment" represented as a string. Each mode of compilation got a separate environment string like `"test"` or `"bench"`. Altogether, however, this approach had a number of drawbacks: * Examples in release mode do not currently work. This is due to how examples are classified and how release mode is handled (e.g. the "release" environment where examples are meant to be built in the "test" environment). * It is not trivial to implement `cargo test --release` today. * It is not trivial to implement `cargo build --bin foo` where *only* the binary `foo` is built. The same is true for examples. * It is not trivial to add selective building of a number of binaries/examples/etc. * Filtering the list of targets to build has some pretty hokey logic that involves pseudo-environments like "doc-all" vs "doc". This logic is duplicated in a few places and in general is quite brittle. * The TOML parser greatly affects compilation due to the time at which profiles are generated, which seems somewhat backwards. * Profiles must be overridden, but only partially, at compile time becuase only the top-level package's profile is applied. In general, this system just needed an overhaul. This commit made a single change of separating `Profile` from `Target` and then basically hit `make` until all the tests passed again. The other large architectural changes are: * Environment strings are now entirely gone. * Filters are implemented in a much more robust fashion. * Release mode is now handled much more gracefully. * The unit of compilation in the backend is no longer (package, target) but rather (package, target, profile). This change had to be propagated many location in the `cargo_rustc` module. * The backend does not filter targets to build *at all*. All filtering now happens entirely in the frontend. I'll test issues after this change lands, but the motivation behind this is to open the door to quickly fixing a number of outstanding issues against Cargo. This change itself is not intended to close many bugs.
2015-02-19 19:30:35 +00:00
println!("bin");
p.process(&p.bin("foo-bar"))
2018-12-08 11:19:47 +00:00
.with_stdout("0-5-1 @ alpha.1 in [CWD]")
.run();
println!("example");
p.cargo("run --example ex-env-vars -v")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.run();
Overhaul how cargo treats profiles This commit is a complete overhaul of how Cargo handles compilation profiles internally. The external interface of Cargo is not affected by this change. Previously each Target had a Profile embedded within it. Conceptually a Target is an entry in the manifest (a binary, benchmark, etc) and a Profile controlled various flags (e.g. --test, -C opt-level, etc). Each Package then contained many profiles for each possible compilation mode. For example a Package would have one target for testing a library, benchmarking a library, documenting a library, etc. When it came to building these targets, Cargo would filter out the targets listed to determine what needed to be built. This filtering was largely done based off an "environment" represented as a string. Each mode of compilation got a separate environment string like `"test"` or `"bench"`. Altogether, however, this approach had a number of drawbacks: * Examples in release mode do not currently work. This is due to how examples are classified and how release mode is handled (e.g. the "release" environment where examples are meant to be built in the "test" environment). * It is not trivial to implement `cargo test --release` today. * It is not trivial to implement `cargo build --bin foo` where *only* the binary `foo` is built. The same is true for examples. * It is not trivial to add selective building of a number of binaries/examples/etc. * Filtering the list of targets to build has some pretty hokey logic that involves pseudo-environments like "doc-all" vs "doc". This logic is duplicated in a few places and in general is quite brittle. * The TOML parser greatly affects compilation due to the time at which profiles are generated, which seems somewhat backwards. * Profiles must be overridden, but only partially, at compile time becuase only the top-level package's profile is applied. In general, this system just needed an overhaul. This commit made a single change of separating `Profile` from `Target` and then basically hit `make` until all the tests passed again. The other large architectural changes are: * Environment strings are now entirely gone. * Filters are implemented in a much more robust fashion. * Release mode is now handled much more gracefully. * The unit of compilation in the backend is no longer (package, target) but rather (package, target, profile). This change had to be propagated many location in the `cargo_rustc` module. * The backend does not filter targets to build *at all*. All filtering now happens entirely in the frontend. I'll test issues after this change lands, but the motivation behind this is to open the door to quickly fixing a number of outstanding issues against Cargo. This change itself is not intended to close many bugs.
2015-02-19 19:30:35 +00:00
println!("test");
p.cargo("test -v")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.run();
if is_nightly() {
println!("bench");
p.cargo("bench -v")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.run();
}
}
#[cargo_test]
fn cargo_rustc_current_dir_foreign_workspace_dep() {
let foo = project()
.file(
"Cargo.toml",
r#"
[workspace]
[package]
name = "foo"
version = "0.0.1"
authors = []
[dependencies]
baz.path = "../baz"
baz_member.path = "../baz/baz_member"
"#,
)
.file("src/lib.rs", "")
.build();
let _baz = project()
.at("baz")
.file(
"Cargo.toml",
r#"
[workspace]
members = ["baz_member"]
[package]
name = "baz"
version = "0.1.0"
"#,
)
.file("src/lib.rs", "")
.file(
"tests/env.rs",
r#"
use std::path::Path;
#[test]
fn baz_env() {
let workspace_dir = Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
let manifest_dir = Path::new(option_env!("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"));
let current_dir = std::env::current_dir().expect("current_dir");
let file_path = workspace_dir.join(file!());
assert!(file_path.exists(), "{}", file_path.display());
let workspace_dir = std::fs::canonicalize(current_dir.join(workspace_dir)).expect("CARGO_RUSTC_CURRENT_DIR");
let manifest_dir = std::fs::canonicalize(current_dir.join(manifest_dir)).expect("CARGO_MANIFEST_DIR");
assert_eq!(workspace_dir, manifest_dir);
}
"#,
)
.file(
"baz_member/Cargo.toml",
r#"
[package]
name = "baz_member"
version = "0.1.0"
authors = []
"#,
)
.file("baz_member/src/lib.rs", "")
.file(
"baz_member/tests/env.rs",
r#"
use std::path::Path;
#[test]
fn baz_member_env() {
let workspace_dir = Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
let file_path = workspace_dir.join(file!());
assert!(file_path.exists(), "{}", file_path.display());
}
"#,
)
.build();
// Verify it works from a different workspace
foo.cargo("test -p baz")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.with_stdout_contains("running 1 test\ntest baz_env ... ok")
.run();
foo.cargo("test -p baz_member")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.with_stdout_contains("running 1 test\ntest baz_member_env ... ok")
.run();
}
#[cargo_test]
fn cargo_rustc_current_dir_non_local_dep() {
Package::new("bar", "0.1.0")
.file(
"tests/bar_env.rs",
r#"
use std::path::Path;
#[test]
fn bar_env() {
let workspace_dir = Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
let manifest_dir = Path::new(option_env!("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"));
let current_dir = std::env::current_dir().expect("current_dir");
let file_path = workspace_dir.join(file!());
assert!(file_path.exists(), "{}", file_path.display());
let workspace_dir = std::fs::canonicalize(current_dir.join(workspace_dir)).expect("CARGO_RUSTC_CURRENT_DIR");
let manifest_dir = std::fs::canonicalize(current_dir.join(manifest_dir)).expect("CARGO_MANIFEST_DIR");
assert_eq!(workspace_dir, manifest_dir);
}
"#,
)
.publish();
let p = project()
.file("src/lib.rs", "")
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
[dependencies]
bar = "0.1.0"
"#,
)
.build();
p.cargo("test -p bar")
.masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
.with_stdout_contains("running 1 test\ntest bar_env ... ok")
.run();
}
#[cargo_test]
fn cargo_rustc_current_dir_is_not_stable() {
if is_nightly() {
return;
}
let p = project()
.file(
"tests/env.rs",
r#"
use std::path::Path;
#[test]
fn env() {
assert_eq!(option_env!("CARGO_RUSTC_CURRENT_DIR"), None);
}
"#,
)
.build();
p.cargo("test").run();
}
2014-07-24 00:57:49 +00:00
#[cargo_test]
fn crate_authors_env_vars() {
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.5.1-alpha.1"
authors = ["wycats@example.com", "neikos@example.com"]
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"src/main.rs",
r#"
2020-09-27 00:59:58 +00:00
extern crate foo;
2020-09-27 00:59:58 +00:00
static AUTHORS: &'static str = env!("CARGO_PKG_AUTHORS");
2020-09-27 00:59:58 +00:00
fn main() {
let s = "wycats@example.com:neikos@example.com";
assert_eq!(AUTHORS, foo::authors());
println!("{}", AUTHORS);
assert_eq!(s, AUTHORS);
}
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"src/lib.rs",
r#"
2020-09-27 00:59:58 +00:00
pub fn authors() -> String {
format!("{}", env!("CARGO_PKG_AUTHORS"))
}
"#,
2018-12-08 11:19:47 +00:00
)
.build();
println!("build");
p.cargo("build -v").run();
println!("bin");
p.process(&p.bin("foo"))
.with_stdout("wycats@example.com:neikos@example.com")
.run();
println!("test");
p.cargo("test -v").run();
}
#[cargo_test]
fn vv_prints_rustc_env_vars() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.0.1"
authors = ["escape='\"@example.com"]
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
let mut b = p.cargo("build -vv");
if cfg!(windows) {
b.with_stderr_contains(
"[RUNNING] `[..]set CARGO_PKG_NAME=foo&& [..]rustc [..]`"
).with_stderr_contains(
r#"[RUNNING] `[..]set CARGO_PKG_AUTHORS="escape='\"@example.com"&& [..]rustc [..]`"#
)
} else {
2019-01-27 13:39:49 +00:00
b.with_stderr_contains("[RUNNING] `[..]CARGO_PKG_NAME=foo [..]rustc [..]`")
.with_stderr_contains(
r#"[RUNNING] `[..]CARGO_PKG_AUTHORS='escape='\''"@example.com' [..]rustc [..]`"#,
)
};
b.run();
}
// The tester may already have LD_LIBRARY_PATH=::/foo/bar which leads to a false positive error
fn setenv_for_removing_empty_component(mut execs: Execs) -> Execs {
let v = dylib_path_envvar();
if let Ok(search_path) = env::var(v) {
let new_search_path =
env::join_paths(env::split_paths(&search_path).filter(|e| !e.as_os_str().is_empty()))
.expect("join_paths");
execs.env(v, new_search_path); // build_command() will override LD_LIBRARY_PATH accordingly
}
execs
}
// Regression test for #4277
#[cargo_test]
fn crate_library_path_env_var() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"src/main.rs",
&format!(
2020-09-27 00:59:58 +00:00
r#"
fn main() {{
let search_path = env!("{}");
let paths = std::env::split_paths(&search_path).collect::<Vec<_>>();
assert!(!paths.contains(&"".into()));
}}
"#,
2018-03-14 15:17:44 +00:00
dylib_path_envvar()
),
2018-12-08 11:19:47 +00:00
)
.build();
setenv_for_removing_empty_component(p.cargo("run")).run();
}
// Regression test for #4277
#[cargo_test]
fn build_with_fake_libc_not_loading() {
let p = project()
.file("src/main.rs", "fn main() {}")
.file("src/lib.rs", r#" "#)
.file("libc.so.6", r#""#)
.build();
setenv_for_removing_empty_component(p.cargo("build")).run();
}
2014-07-08 00:59:18 +00:00
// this is testing that src/<pkg-name>.rs still works (for now)
#[cargo_test]
fn many_crate_types_old_style_lib_location() {
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.5.0"
authors = ["wycats@example.com"]
2020-09-27 00:59:58 +00:00
[lib]
2020-09-27 00:59:58 +00:00
name = "foo"
crate_type = ["rlib", "dylib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/foo.rs", "pub fn foo() {}")
.build();
p.cargo("build")
.with_stderr_contains(
2018-03-14 15:17:44 +00:00
"\
2018-08-02 09:18:48 +00:00
[WARNING] path `[..]src/foo.rs` was erroneously implicitly accepted for library `foo`,
2018-03-14 15:17:44 +00:00
please rename the file to `src/lib.rs` or set lib.path in Cargo.toml",
2018-12-08 11:19:47 +00:00
)
.run();
2018-08-29 06:11:10 +00:00
assert!(p.root().join("target/debug/libfoo.rlib").is_file());
2018-03-14 15:17:44 +00:00
let fname = format!("{}foo{}", env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX);
2018-08-29 06:11:10 +00:00
assert!(p.root().join("target/debug").join(&fname).is_file());
}
2014-07-08 00:59:18 +00:00
#[cargo_test]
fn many_crate_types_correct() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
[package]
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.5.0"
authors = ["wycats@example.com"]
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
[lib]
2014-07-08 00:59:18 +00:00
2020-09-27 00:59:58 +00:00
name = "foo"
crate_type = ["rlib", "dylib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "pub fn foo() {}")
.build();
p.cargo("build").run();
2018-08-29 06:11:10 +00:00
assert!(p.root().join("target/debug/libfoo.rlib").is_file());
2018-03-14 15:17:44 +00:00
let fname = format!("{}foo{}", env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX);
2018-08-29 06:11:10 +00:00
assert!(p.root().join("target/debug").join(&fname).is_file());
}
2014-06-27 05:53:05 +00:00
#[cargo_test]
fn set_both_dylib_and_cdylib_crate_types() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.5.0"
authors = ["wycats@example.com"]
[lib]
name = "foo"
crate_type = ["cdylib", "dylib"]
"#,
)
.file("src/lib.rs", "pub fn foo() {}")
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
"\
error: failed to parse manifest at `[..]`
Caused by:
library `foo` cannot set the crate type of both `dylib` and `cdylib`
",
)
.run();
}
#[cargo_test]
fn dev_dependencies_conflicting_warning() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = "2018"
[dev-dependencies]
a = {path = "a"}
[dev_dependencies]
a = {path = "a"}
"#,
)
.file("src/lib.rs", "")
.file(
"a/Cargo.toml",
r#"
[package]
name = "a"
version = "0.0.1"
"#,
)
.file("a/src/lib.rs", "")
.build();
p.cargo("build")
.with_stderr_contains(
"[WARNING] conflicting between `dev-dependencies` and `dev_dependencies` in the `foo` package.\n
`dev_dependencies` is ignored and not recommended for use in the future"
)
.run();
}
#[cargo_test]
fn build_dependencies_conflicting_warning() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = "2018"
[build-dependencies]
a = {path = "a"}
[build_dependencies]
a = {path = "a"}
"#,
)
.file("src/lib.rs", "")
.file(
"a/Cargo.toml",
r#"
[package]
name = "a"
version = "0.0.1"
"#,
)
.file("a/src/lib.rs", "")
.build();
p.cargo("build")
.with_stderr_contains(
"[WARNING] conflicting between `build-dependencies` and `build_dependencies` in the `foo` package.\n
`build_dependencies` is ignored and not recommended for use in the future"
)
.run();
}
#[cargo_test]
fn lib_crate_types_conflicting_warning() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.5.0"
authors = ["wycats@example.com"]
[lib]
name = "foo"
crate-type = ["rlib", "dylib"]
crate_type = ["staticlib", "dylib"]
"#,
)
.file("src/lib.rs", "pub fn foo() {}")
.build();
p.cargo("build")
.with_stderr_contains(
"[WARNING] conflicting between `crate-type` and `crate_type` in the `foo` library target.\n
`crate_type` is ignored and not recommended for use in the future",
)
.run();
}
#[cargo_test]
fn examples_crate_types_conflicting_warning() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.5.0"
authors = ["wycats@example.com"]
[[example]]
name = "ex"
path = "examples/ex.rs"
crate-type = ["rlib", "dylib"]
crate_type = ["proc_macro"]
[[example]]
name = "goodbye"
path = "examples/ex-goodbye.rs"
crate-type = ["rlib", "dylib"]
crate_type = ["rlib", "staticlib"]
"#,
)
.file("src/lib.rs", "")
.file(
"examples/ex.rs",
r#"
fn main() { println!("ex"); }
"#,
)
.file(
"examples/ex-goodbye.rs",
r#"
fn main() { println!("goodbye"); }
"#,
)
.build();
p.cargo("build")
.with_stderr_contains(
"\
[WARNING] conflicting between `crate-type` and `crate_type` in the `ex` example target.\n
`crate_type` is ignored and not recommended for use in the future
[WARNING] conflicting between `crate-type` and `crate_type` in the `goodbye` example target.\n
`crate_type` is ignored and not recommended for use in the future",
)
.run();
}
#[cargo_test]
fn self_dependency() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
2020-09-27 00:59:58 +00:00
name = "test"
version = "0.0.0"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies.test]
2020-09-27 00:59:58 +00:00
path = "."
2020-09-27 00:59:58 +00:00
[lib]
name = "test"
path = "src/test.rs"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/test.rs", "fn main() {}")
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] cyclic package dependency: package `test v0.0.0 ([CWD])` depends on itself. Cycle:
package `test v0.0.0 ([CWD])`
... which satisfies path dependency `test` of package `test v0.0.0 ([..])`",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
/// Make sure broken and loop symlinks don't break the build
///
/// This test requires you to be able to make symlinks.
/// For windows, this may require you to enable developer mode.
fn ignore_broken_symlinks() {
if !symlink_supported() {
return;
}
let p = project()
2015-03-26 18:17:44 +00:00
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.symlink("Notafile", "bar")
// To hit the symlink directory, we need a build script
// to trigger a full scan of package files.
.file("build.rs", &main_file(r#""build script""#, &[]))
.symlink_dir("a/b", "a/b/c/d/foo")
.build();
p.cargo("build")
.with_stderr_contains(
"[WARNING] File system loop found: [..]/a/b/c/d/foo points to an ancestor [..]/a/b",
)
.run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
p.process(&p.bin("foo")).with_stdout("i am foo\n").run();
}
#[cargo_test]
fn missing_lib_and_bin() {
2018-07-24 13:01:56 +00:00
let p = project().build();
p.cargo("build")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] failed to parse manifest at `[..]Cargo.toml`
Caused by:
no targets specified in the manifest
2018-03-14 15:17:44 +00:00
either src/lib.rs, src/main.rs, a [lib] section, or [[bin]] section must be present\n",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn lto_build() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
2020-09-27 00:59:58 +00:00
name = "test"
version = "0.0.0"
authors = []
2014-11-14 16:49:01 +00:00
2020-09-27 00:59:58 +00:00
[profile.release]
lto = true
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("build -v --release")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[COMPILING] test v0.0.0 ([CWD])
2019-09-25 01:17:36 +00:00
[RUNNING] `rustc --crate-name test src/main.rs [..]--crate-type bin \
--emit=[..]link \
2014-12-21 18:45:39 +00:00
-C opt-level=3 \
-C lto \
[..]
[FINISHED] release [optimized] target(s) in [..]
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn verbose_build() {
let p = project().file("src/lib.rs", "").build();
p.cargo("build -v")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[COMPILING] foo v0.0.1 ([CWD])
2019-09-25 01:17:36 +00:00
[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
--emit=[..]link[..]-C debuginfo=2 [..]\
-C metadata=[..] \
--out-dir [..] \
-L dependency=[CWD]/target/debug/deps`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn verbose_release_build() {
let p = project().file("src/lib.rs", "").build();
p.cargo("build -v --release")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[COMPILING] foo v0.0.1 ([CWD])
2019-09-25 01:17:36 +00:00
[RUNNING] `rustc --crate-name foo src/lib.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 opt-level=3[..]\
-C metadata=[..] \
--out-dir [..] \
-L dependency=[CWD]/target/release/deps`
[FINISHED] release [optimized] target(s) in [..]
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn verbose_release_build_short() {
let p = project().file("src/lib.rs", "").build();
p.cargo("build -v -r")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([CWD])
[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
--emit=[..]link[..]\
-C opt-level=3[..]\
-C metadata=[..] \
--out-dir [..] \
-L dependency=[CWD]/target/release/deps`
[FINISHED] release [optimized] target(s) in [..]
",
)
.run();
}
#[cargo_test]
fn verbose_release_build_deps() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
2020-09-27 00:59:58 +00:00
name = "test"
version = "0.0.0"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies.foo]
path = "foo"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
2018-03-14 15:17:44 +00:00
.file(
"foo/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.0.0"
authors = []
2020-09-27 00:59:58 +00:00
[lib]
name = "foo"
crate_type = ["dylib", "rlib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("foo/src/lib.rs", "")
.build();
p.cargo("build -v --release")
.with_stderr(&format!(
2018-03-14 15:17:44 +00:00
"\
[COMPILING] foo v0.0.0 ([CWD]/foo)
2019-09-25 01:17:36 +00:00
[RUNNING] `rustc --crate-name foo foo/src/lib.rs [..]\
2017-01-03 21:22:58 +00:00
--crate-type dylib --crate-type rlib \
--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 prefer-dynamic[..]\
-C opt-level=3[..]\
-C metadata=[..] \
--out-dir [..] \
-L dependency=[CWD]/target/release/deps`
[COMPILING] test v0.0.0 ([CWD])
2019-09-25 01:17:36 +00:00
[RUNNING] `rustc --crate-name test src/lib.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 opt-level=3[..]\
-C metadata=[..] \
--out-dir [..] \
-L dependency=[CWD]/target/release/deps \
--extern foo=[CWD]/target/release/deps/{prefix}foo{suffix} \
--extern foo=[CWD]/target/release/deps/libfoo.rlib`
[FINISHED] release [optimized] target(s) in [..]
",
2018-03-14 15:17:44 +00:00
prefix = env::consts::DLL_PREFIX,
suffix = env::consts::DLL_SUFFIX
2018-12-08 11:19:47 +00:00
))
.run();
}
2014-07-10 22:13:53 +00:00
#[cargo_test]
fn explicit_examples() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "1.0.0"
authors = []
2014-07-10 22:13:53 +00:00
2020-09-27 00:59:58 +00:00
[lib]
name = "foo"
path = "src/lib.rs"
2014-07-10 22:13:53 +00:00
2020-09-27 00:59:58 +00:00
[[example]]
name = "hello"
path = "examples/ex-hello.rs"
2014-07-10 22:13:53 +00:00
2020-09-27 00:59:58 +00:00
[[example]]
name = "goodbye"
path = "examples/ex-goodbye.rs"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"src/lib.rs",
r#"
2020-09-27 00:59:58 +00:00
pub fn get_hello() -> &'static str { "Hello" }
pub fn get_goodbye() -> &'static str { "Goodbye" }
pub fn get_world() -> &'static str { "World" }
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"examples/ex-hello.rs",
r#"
2020-09-27 00:59:58 +00:00
extern crate foo;
fn main() { println!("{}, {}!", foo::get_hello(), foo::get_world()); }
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"examples/ex-goodbye.rs",
r#"
2020-09-27 00:59:58 +00:00
extern crate foo;
fn main() { println!("{}, {}!", foo::get_goodbye(), foo::get_world()); }
"#,
2018-12-08 11:19:47 +00:00
)
.build();
2014-07-10 22:13:53 +00:00
2019-02-19 17:32:07 +00:00
p.cargo("build --examples").run();
p.process(&p.bin("examples/hello"))
.with_stdout("Hello, World!\n")
.run();
p.process(&p.bin("examples/goodbye"))
.with_stdout("Goodbye, World!\n")
.run();
}
2014-07-10 22:13:53 +00:00
#[cargo_test]
fn non_existing_test() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "1.0.0"
[lib]
name = "foo"
path = "src/lib.rs"
[[test]]
name = "hello"
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("build --tests -v")
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
can't find `hello` test at `tests/hello.rs` or `tests/hello/main.rs`. \
Please specify test.path if you want to use a non-default path.",
)
.run();
}
#[cargo_test]
fn non_existing_example() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "1.0.0"
2020-09-27 00:59:58 +00:00
[lib]
name = "foo"
path = "src/lib.rs"
2020-09-27 00:59:58 +00:00
[[example]]
name = "hello"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
p.cargo("build --examples -v")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
can't find `hello` example at `examples/hello.rs` or `examples/hello/main.rs`. \
Please specify example.path if you want to use a non-default path.",
)
.run();
}
#[cargo_test]
fn non_existing_benchmark() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "1.0.0"
[lib]
name = "foo"
path = "src/lib.rs"
[[bench]]
name = "hello"
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("build --benches -v")
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
can't find `hello` bench at `benches/hello.rs` or `benches/hello/main.rs`. \
Please specify bench.path if you want to use a non-default path.",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn non_existing_binary() {
let p = project()
2018-07-24 13:01:56 +00:00
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/lib.rs", "")
.file("src/bin/ehlo.rs", "")
.build();
p.cargo("build -v")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
can't find `foo` bin at `src/bin/foo.rs` or `src/bin/foo/main.rs`. \
Please specify bin.path if you want to use a non-default path.",
)
.run();
}
#[cargo_test]
fn commonly_wrong_path_of_test() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "1.0.0"
[lib]
name = "foo"
path = "src/lib.rs"
[[test]]
name = "foo"
"#,
)
.file("src/lib.rs", "")
.file("test/foo.rs", "")
.build();
p.cargo("build --tests -v")
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
can't find `foo` test at default paths, but found a file at `test/foo.rs`.
Perhaps rename the file to `tests/foo.rs` for target auto-discovery, \
or specify test.path if you want to use a non-default path.",
)
.run();
}
#[cargo_test]
fn commonly_wrong_path_of_example() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "1.0.0"
[lib]
name = "foo"
path = "src/lib.rs"
[[example]]
name = "foo"
"#,
)
.file("src/lib.rs", "")
.file("example/foo.rs", "")
.build();
p.cargo("build --examples -v")
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
can't find `foo` example at default paths, but found a file at `example/foo.rs`.
Perhaps rename the file to `examples/foo.rs` for target auto-discovery, \
or specify example.path if you want to use a non-default path.",
)
.run();
}
#[cargo_test]
fn commonly_wrong_path_of_benchmark() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "1.0.0"
[lib]
name = "foo"
path = "src/lib.rs"
[[bench]]
name = "foo"
"#,
)
.file("src/lib.rs", "")
.file("bench/foo.rs", "")
.build();
p.cargo("build --benches -v")
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
can't find `foo` bench at default paths, but found a file at `bench/foo.rs`.
Perhaps rename the file to `benches/foo.rs` for target auto-discovery, \
or specify bench.path if you want to use a non-default path.",
)
.run();
}
#[cargo_test]
fn commonly_wrong_path_binary() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/lib.rs", "")
.file("src/bins/foo.rs", "")
.build();
p.cargo("build -v")
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
can't find `foo` bin at default paths, but found a file at `src/bins/foo.rs`.
Perhaps rename the file to `src/bin/foo.rs` for target auto-discovery, \
or specify bin.path if you want to use a non-default path.",
)
.run();
}
#[cargo_test]
fn commonly_wrong_path_subdir_binary() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/lib.rs", "")
.file("src/bins/foo/main.rs", "")
.build();
p.cargo("build -v")
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
can't find `foo` bin at default paths, but found a file at `src/bins/foo/main.rs`.
Perhaps rename the file to `src/bin/foo/main.rs` for target auto-discovery, \
or specify bin.path if you want to use a non-default path.",
)
.run();
}
#[cargo_test]
fn found_multiple_target_files() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/lib.rs", "")
.file("src/bin/foo.rs", "")
.file("src/bin/foo/main.rs", "")
.build();
p.cargo("build -v")
.with_status(101)
// Don't assert the inferred paths since the order is non-deterministic.
.with_stderr(
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
cannot infer path for `foo` bin
Cargo doesn't know which to use because multiple target files found \
at `src/bin/foo[..].rs` and `src/bin/foo[..].rs`.",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
2018-07-24 13:01:56 +00:00
fn legacy_binary_paths_warnings() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "1.0.0"
authors = []
2020-09-27 00:59:58 +00:00
[[bin]]
name = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("build -v")
.with_stderr_contains(
2018-03-14 15:17:44 +00:00
"\
2018-08-02 09:18:48 +00:00
[WARNING] path `[..]src/main.rs` was erroneously implicitly accepted for binary `bar`,
2018-03-14 15:17:44 +00:00
please set bin.path in Cargo.toml",
2018-12-08 11:19:47 +00:00
)
.run();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "1.0.0"
authors = []
2020-09-27 00:59:58 +00:00
[[bin]]
name = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.file("src/bin/main.rs", "fn main() {}")
.build();
p.cargo("build -v")
.with_stderr_contains(
2018-03-14 15:17:44 +00:00
"\
2018-08-02 09:18:48 +00:00
[WARNING] path `[..]src/bin/main.rs` was erroneously implicitly accepted for binary `bar`,
2018-03-14 15:17:44 +00:00
please set bin.path in Cargo.toml",
2018-12-08 11:19:47 +00:00
)
.run();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "1.0.0"
authors = []
[[bin]]
name = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/bar.rs", "fn main() {}")
.build();
p.cargo("build -v")
.with_stderr_contains(
2018-03-14 15:17:44 +00:00
"\
2018-08-02 09:18:48 +00:00
[WARNING] path `[..]src/bar.rs` was erroneously implicitly accepted for binary `bar`,
2018-03-14 15:17:44 +00:00
please set bin.path in Cargo.toml",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn implicit_examples() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"src/lib.rs",
r#"
2020-09-27 00:59:58 +00:00
pub fn get_hello() -> &'static str { "Hello" }
pub fn get_goodbye() -> &'static str { "Goodbye" }
pub fn get_world() -> &'static str { "World" }
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"examples/hello.rs",
r#"
2020-09-27 00:59:58 +00:00
extern crate foo;
fn main() {
println!("{}, {}!", foo::get_hello(), foo::get_world());
}
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"examples/goodbye.rs",
r#"
2020-09-27 00:59:58 +00:00
extern crate foo;
fn main() {
println!("{}, {}!", foo::get_goodbye(), foo::get_world());
}
"#,
2018-12-08 11:19:47 +00:00
)
.build();
2014-07-10 22:13:53 +00:00
2019-02-19 17:32:07 +00:00
p.cargo("build --examples").run();
p.process(&p.bin("examples/hello"))
.with_stdout("Hello, World!\n")
.run();
p.process(&p.bin("examples/goodbye"))
.with_stdout("Goodbye, World!\n")
.run();
}
#[cargo_test]
fn standard_build_no_ndebug() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
2018-03-14 15:17:44 +00:00
.file(
"src/foo.rs",
r#"
2020-09-27 00:59:58 +00:00
fn main() {
if cfg!(debug_assertions) {
println!("slow")
} else {
println!("fast")
}
}
2020-09-27 00:59:58 +00:00
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("build").run();
p.process(&p.bin("foo")).with_stdout("slow\n").run();
}
#[cargo_test]
fn release_build_ndebug() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
2018-03-14 15:17:44 +00:00
.file(
"src/foo.rs",
r#"
2020-09-27 00:59:58 +00:00
fn main() {
if cfg!(debug_assertions) {
println!("slow")
} else {
println!("fast")
}
}
2020-09-27 00:59:58 +00:00
"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("build --release").run();
p.process(&p.release_bin("foo")).with_stdout("fast\n").run();
}
#[cargo_test]
fn inferred_main_bin() {
let p = project().file("src/main.rs", "fn main() {}").build();
p.cargo("build").run();
p.process(&p.bin("foo")).run();
}
#[cargo_test]
fn deletion_causes_failure() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[dependencies.bar]
path = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "extern crate bar; fn main() {}")
2018-07-24 22:35:01 +00:00
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
.file("bar/src/lib.rs", "")
.build();
p.cargo("build").run();
2018-07-24 22:35:01 +00:00
p.change_file("Cargo.toml", &basic_manifest("foo", "0.0.1"));
p.cargo("build")
.with_status(101)
.with_stderr_contains("[..]can't find crate for `bar`")
.run();
}
#[cargo_test]
fn bad_cargo_toml_in_target_dir() {
let p = project()
.file("src/main.rs", "fn main() {}")
.file("target/Cargo.toml", "bad-toml")
.build();
p.cargo("build").run();
p.process(&p.bin("foo")).run();
}
#[cargo_test]
fn lib_with_standard_name() {
let p = project()
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("syntax", "0.0.1"))
.file("src/lib.rs", "pub fn foo() {}")
.file(
"src/main.rs",
"extern crate syntax; fn main() { syntax::foo() }",
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("build")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[COMPILING] syntax v0.0.1 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn simple_staticlib() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
authors = []
version = "0.0.1"
2020-09-27 00:59:58 +00:00
[lib]
name = "foo"
crate-type = ["staticlib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "pub fn foo() {}")
.build();
// env var is a test for #1381
p.cargo("build").env("CARGO_LOG", "nekoneko=trace").run();
}
#[cargo_test]
fn staticlib_rlib_and_bin() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
authors = []
version = "0.0.1"
2020-09-27 00:59:58 +00:00
[lib]
name = "foo"
crate-type = ["staticlib", "rlib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "pub fn foo() {}")
.file("src/main.rs", "extern crate foo; fn main() { foo::foo(); }")
.build();
p.cargo("build -v").run();
}
#[cargo_test]
fn opt_out_of_bin() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
bin = []
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
authors = []
version = "0.0.1"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.file("src/main.rs", "bad syntax")
.build();
p.cargo("build").run();
}
#[cargo_test]
fn single_lib() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
authors = []
version = "0.0.1"
2020-09-27 00:59:58 +00:00
[lib]
name = "foo"
path = "src/bar.rs"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/bar.rs", "")
.build();
p.cargo("build").run();
}
2014-08-14 06:08:02 +00:00
#[cargo_test]
fn freshness_ignores_excluded() {
let foo = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.0"
authors = []
build = "build.rs"
exclude = ["src/b*.rs"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("build.rs", "fn main() {}")
.file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
.build();
foo.root().move_into_the_past();
foo.cargo("build")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[COMPILING] foo v0.0.0 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
// Smoke test to make sure it doesn't compile again
println!("first pass");
2023-11-15 22:33:27 +00:00
foo.cargo("build").with_stderr("[FINISHED] [..]").run();
// Modify an ignored file and make sure we don't rebuild
println!("second pass");
foo.change_file("src/bar.rs", "");
2023-11-15 22:33:27 +00:00
foo.cargo("build").with_stderr("[FINISHED] [..]").run();
}
#[cargo_test]
fn rebuild_preserves_out_dir() {
let foo = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.0"
authors = []
build = 'build.rs'
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"build.rs",
r#"
2020-09-27 00:59:58 +00:00
use std::env;
use std::fs::File;
use std::path::Path;
2020-09-27 00:59:58 +00:00
fn main() {
let path = Path::new(&env::var("OUT_DIR").unwrap()).join("foo");
if env::var_os("FIRST").is_some() {
File::create(&path).unwrap();
} else {
File::create(&path).unwrap();
}
}
2020-09-27 00:59:58 +00:00
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
.build();
foo.root().move_into_the_past();
foo.cargo("build")
.env("FIRST", "1")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[COMPILING] foo v0.0.0 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
foo.change_file("src/bar.rs", "");
foo.cargo("build")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[COMPILING] foo v0.0.0 ([CWD])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
2014-09-07 18:48:35 +00:00
#[cargo_test]
fn dep_no_libs() {
let foo = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.0"
authors = []
2014-09-07 18:48:35 +00:00
2020-09-27 00:59:58 +00:00
[dependencies.bar]
path = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
2018-07-24 22:35:01 +00:00
.file("bar/Cargo.toml", &basic_manifest("bar", "0.0.0"))
.file("bar/src/main.rs", "")
.build();
foo.cargo("build").run();
}
#[cargo_test]
fn recompile_space_in_name() {
let foo = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.0.0"
authors = []
2020-09-27 00:59:58 +00:00
[lib]
name = "foo"
path = "src/my lib.rs"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/my lib.rs", "")
.build();
foo.cargo("build").run();
foo.root().move_into_the_past();
2023-11-15 22:33:27 +00:00
foo.cargo("build").with_stderr("[FINISHED] [..]").run();
}
#[cfg(unix)]
#[cargo_test]
fn credentials_is_unreadable() {
use cargo_test_support::paths::home;
use std::os::unix::prelude::*;
let p = project()
.file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
.file("src/lib.rs", "")
.build();
let credentials = home().join(".cargo/credentials.toml");
t!(fs::create_dir_all(credentials.parent().unwrap()));
t!(fs::write(
&credentials,
r#"
[registry]
token = "api-token"
"#
));
let stat = fs::metadata(credentials.as_path()).unwrap();
let mut perms = stat.permissions();
perms.set_mode(0o000);
2020-01-17 11:19:12 +00:00
fs::set_permissions(credentials, perms).unwrap();
p.cargo("build").run();
}
#[cfg(unix)]
#[cargo_test]
fn ignore_bad_directories() {
use std::os::unix::prelude::*;
let foo = project()
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("foo", "0.0.0"))
.file("src/lib.rs", "")
.build();
let dir = foo.root().join("tmp");
fs::create_dir(&dir).unwrap();
let stat = fs::metadata(&dir).unwrap();
let mut perms = stat.permissions();
perms.set_mode(0o644);
fs::set_permissions(&dir, perms.clone()).unwrap();
foo.cargo("build").run();
perms.set_mode(0o755);
fs::set_permissions(&dir, perms).unwrap();
}
#[cargo_test]
fn bad_cargo_config() {
let foo = project()
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("foo", "0.0.0"))
.file("src/lib.rs", "")
2024-01-26 19:40:46 +00:00
.file(".cargo/config.toml", "this is not valid toml")
.build();
foo.cargo("build -v")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[ERROR] could not load Cargo configuration
Caused by:
could not parse TOML configuration in `[..]`
Caused by:
TOML parse error at line 1, column 6
|
1 | this is not valid toml
| ^
expected `.`, `=`
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn cargo_platform_specific_dependency() {
let host = rustc_host();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
&format!(
r#"
[package]
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.5.0"
authors = ["wycats@example.com"]
build = "build.rs"
[target.{host}.dependencies]
dep = {{ path = "dep" }}
[target.{host}.build-dependencies]
build = {{ path = "build" }}
[target.{host}.dev-dependencies]
dev = {{ path = "dev" }}
"#,
2018-03-14 15:17:44 +00:00
host = host
),
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "extern crate dep; fn main() { dep::dep() }")
.file(
"tests/foo.rs",
"extern crate dev; #[test] fn foo() { dev::dev() }",
2018-12-08 11:19:47 +00:00
)
.file(
"build.rs",
"extern crate build; fn main() { build::build(); }",
2018-12-08 11:19:47 +00:00
)
.file("dep/Cargo.toml", &basic_manifest("dep", "0.5.0"))
.file("dep/src/lib.rs", "pub fn dep() {}")
2018-07-24 22:35:01 +00:00
.file("build/Cargo.toml", &basic_manifest("build", "0.5.0"))
.file("build/src/lib.rs", "pub fn build() {}")
2018-07-24 22:35:01 +00:00
.file("dev/Cargo.toml", &basic_manifest("dev", "0.5.0"))
.file("dev/src/lib.rs", "pub fn dev() {}")
.build();
p.cargo("build").run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
p.cargo("test").run();
}
#[cargo_test]
fn cargo_platform_specific_dependency_build_dependencies_conflicting_warning() {
let host = rustc_host();
let p = project()
.file(
"Cargo.toml",
&format!(
r#"
[package]
name = "foo"
version = "0.5.0"
authors = ["wycats@example.com"]
build = "build.rs"
[target.{host}.build-dependencies]
build = {{ path = "build" }}
[target.{host}.build_dependencies]
build = {{ path = "build" }}
"#,
host = host
),
)
.file("src/main.rs", "fn main() { }")
.file(
"build.rs",
"extern crate build; fn main() { build::build(); }",
)
.file("build/Cargo.toml", &basic_manifest("build", "0.5.0"))
.file("build/src/lib.rs", "pub fn build() {}")
.build();
p.cargo("build")
.with_stderr_contains(
format!("[WARNING] conflicting between `build-dependencies` and `build_dependencies` in the `{}` platform target.\n
`build_dependencies` is ignored and not recommended for use in the future", host)
)
.run();
assert!(p.bin("foo").is_file());
}
#[cargo_test]
fn cargo_platform_specific_dependency_dev_dependencies_conflicting_warning() {
let host = rustc_host();
let p = project()
.file(
"Cargo.toml",
&format!(
r#"
[package]
name = "foo"
version = "0.5.0"
authors = ["wycats@example.com"]
[target.{host}.dev-dependencies]
dev = {{ path = "dev" }}
[target.{host}.dev_dependencies]
dev = {{ path = "dev" }}
"#,
host = host
),
)
.file("src/main.rs", "fn main() { }")
.file(
"tests/foo.rs",
"extern crate dev; #[test] fn foo() { dev::dev() }",
)
.file("dev/Cargo.toml", &basic_manifest("dev", "0.5.0"))
.file("dev/src/lib.rs", "pub fn dev() {}")
.build();
p.cargo("build")
.with_stderr_contains(
format!("[WARNING] conflicting between `dev-dependencies` and `dev_dependencies` in the `{}` platform target.\n
`dev_dependencies` is ignored and not recommended for use in the future", host)
)
.run();
assert!(p.bin("foo").is_file());
p.cargo("test").run();
}
#[cargo_test]
fn bad_platform_specific_dependency() {
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.5.0"
authors = ["wycats@example.com"]
2020-09-27 00:59:58 +00:00
[target.wrong-target.dependencies.bar]
path = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
2018-07-24 22:35:01 +00:00
.file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0"))
.file(
"bar/src/lib.rs",
r#"pub fn gimme() -> String { format!("") }"#,
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("build")
.with_status(101)
.with_stderr_contains("[..]can't find crate for `bar`")
.run();
}
#[cargo_test]
fn cargo_platform_specific_dependency_wrong_platform() {
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.5.0"
authors = ["wycats@example.com"]
2020-09-27 00:59:58 +00:00
[target.non-existing-triplet.dependencies.bar]
path = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "fn main() {}")
2018-07-24 22:35:01 +00:00
.file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0"))
.file(
"bar/src/lib.rs",
"invalid rust file, should not be compiled",
2018-12-08 11:19:47 +00:00
)
.build();
p.cargo("build").run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
p.process(&p.bin("foo")).run();
let lockfile = p.read_lockfile();
assert!(lockfile.contains("bar"));
}
#[cargo_test]
fn example_as_lib() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[[example]]
name = "ex"
crate-type = ["lib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.file("examples/ex.rs", "")
.build();
p.cargo("build --example=ex").run();
2018-08-29 06:11:10 +00:00
assert!(p.example_lib("ex", "lib").is_file());
}
#[cargo_test]
fn example_as_rlib() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[[example]]
name = "ex"
crate-type = ["rlib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.file("examples/ex.rs", "")
.build();
p.cargo("build --example=ex").run();
2018-08-29 06:11:10 +00:00
assert!(p.example_lib("ex", "rlib").is_file());
}
#[cargo_test]
fn example_as_dylib() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[[example]]
name = "ex"
crate-type = ["dylib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.file("examples/ex.rs", "")
.build();
p.cargo("build --example=ex").run();
2018-08-29 06:11:10 +00:00
assert!(p.example_lib("ex", "dylib").is_file());
}
#[cargo_test]
fn example_as_proc_macro() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[[example]]
name = "ex"
crate-type = ["proc-macro"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.file(
"examples/ex.rs",
r#"
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro]
pub fn eat(_item: TokenStream) -> TokenStream {
"".parse().unwrap()
}
"#,
)
.build();
p.cargo("build --example=ex").run();
2018-08-29 06:11:10 +00:00
assert!(p.example_lib("ex", "proc-macro").is_file());
}
#[cargo_test]
fn example_bin_same_name() {
let p = project()
.file("src/main.rs", "fn main() {}")
.file("examples/foo.rs", "fn main() {}")
.build();
2019-02-19 17:32:07 +00:00
p.cargo("build --examples").run();
2018-08-29 06:11:10 +00:00
assert!(!p.bin("foo").is_file());
// We expect a file of the form bin/foo-{metadata_hash}
2018-08-29 06:11:10 +00:00
assert!(p.bin("examples/foo").is_file());
2019-02-19 17:32:07 +00:00
p.cargo("build --examples").run();
2018-08-29 06:11:10 +00:00
assert!(!p.bin("foo").is_file());
// We expect a file of the form bin/foo-{metadata_hash}
2018-08-29 06:11:10 +00:00
assert!(p.bin("examples/foo").is_file());
}
#[cargo_test]
fn compile_then_delete() {
let p = project().file("src/main.rs", "fn main() {}").build();
p.cargo("run -v").run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
if cfg!(windows) {
2015-03-16 13:27:58 +00:00
// On windows unlinking immediately after running often fails, so sleep
sleep_ms(100);
}
fs::remove_file(&p.bin("foo")).unwrap();
p.cargo("run -v").run();
}
#[cargo_test]
fn transitive_dependencies_not_available() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[dependencies.aaaaa]
path = "a"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"src/main.rs",
"extern crate bbbbb; extern crate aaaaa; fn main() {}",
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"a/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "aaaaa"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies.bbbbb]
path = "../b"
"#,
2018-12-08 11:19:47 +00:00
)
.file("a/src/lib.rs", "extern crate bbbbb;")
2018-07-24 22:35:01 +00:00
.file("b/Cargo.toml", &basic_manifest("bbbbb", "0.0.1"))
.file("b/src/lib.rs", "")
.build();
p.cargo("build -v")
.with_status(101)
.with_stderr_contains("[..] can't find crate for `bbbbb`[..]")
.run();
}
#[cargo_test]
fn cyclic_deps_rejected() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[dependencies.a]
path = "a"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
2018-03-14 15:17:44 +00:00
.file(
"a/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "a"
version = "0.0.1"
authors = []
2020-09-27 00:59:58 +00:00
[dependencies.foo]
path = ".."
"#,
2018-12-08 11:19:47 +00:00
)
.file("a/src/lib.rs", "")
.build();
p.cargo("build -v")
.with_status(101)
.with_stderr(
"[ERROR] cyclic package dependency: package `a v0.0.1 ([CWD]/a)` depends on itself. Cycle:
package `a v0.0.1 ([CWD]/a)`
... which satisfies path dependency `a` of package `foo v0.0.1 ([CWD])`
... which satisfies path dependency `foo` of package `a v0.0.1 ([..])`",
).run();
}
#[cargo_test]
fn predictable_filenames() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[lib]
name = "foo"
crate-type = ["dylib", "rlib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
p.cargo("build -v").run();
2018-08-29 06:11:10 +00:00
assert!(p.root().join("target/debug/libfoo.rlib").is_file());
2018-03-14 15:17:44 +00:00
let dylib_name = format!("{}foo{}", env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX);
2018-08-29 06:11:10 +00:00
assert!(p.root().join("target/debug").join(dylib_name).is_file());
}
#[cargo_test]
fn dashes_to_underscores() {
let p = project()
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_manifest("foo-bar", "0.0.1"))
.file("src/lib.rs", "")
.file("src/main.rs", "extern crate foo_bar; fn main() {}")
.build();
p.cargo("build -v").run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo-bar").is_file());
}
#[cargo_test]
fn dashes_in_crate_name_bad() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[lib]
name = "foo-bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.file("src/main.rs", "extern crate foo_bar; fn main() {}")
.build();
p.cargo("build -v")
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[..]/foo/Cargo.toml`
Caused by:
library target names cannot contain hyphens: foo-bar
",
)
.run();
}
#[cargo_test]
fn rustc_env_var() {
let p = project().file("src/lib.rs", "").build();
p.cargo("build -v")
.env("RUSTC", "rustc-that-does-not-exist")
.with_status(101)
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
2016-09-14 18:10:30 +00:00
[ERROR] could not execute process `rustc-that-does-not-exist -vV` ([..])
Caused by:
[..]
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
2018-08-29 06:11:10 +00:00
assert!(!p.bin("a").is_file());
}
#[cargo_test]
fn filtering() {
let p = project()
.file("src/lib.rs", "")
.file("src/bin/a.rs", "fn main() {}")
.file("src/bin/b.rs", "fn main() {}")
.file("examples/a.rs", "fn main() {}")
.file("examples/b.rs", "fn main() {}")
.build();
p.cargo("build --lib").run();
2018-08-29 06:11:10 +00:00
assert!(!p.bin("a").is_file());
p.cargo("build --bin=a --example=a").run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("a").is_file());
assert!(!p.bin("b").is_file());
assert!(p.bin("examples/a").is_file());
assert!(!p.bin("examples/b").is_file());
}
#[cargo_test]
fn filtering_implicit_bins() {
let p = project()
.file("src/lib.rs", "")
.file("src/bin/a.rs", "fn main() {}")
.file("src/bin/b.rs", "fn main() {}")
.file("examples/a.rs", "fn main() {}")
.file("examples/b.rs", "fn main() {}")
.build();
p.cargo("build --bins").run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("a").is_file());
assert!(p.bin("b").is_file());
assert!(!p.bin("examples/a").is_file());
assert!(!p.bin("examples/b").is_file());
}
#[cargo_test]
fn filtering_implicit_examples() {
let p = project()
.file("src/lib.rs", "")
.file("src/bin/a.rs", "fn main() {}")
.file("src/bin/b.rs", "fn main() {}")
.file("examples/a.rs", "fn main() {}")
.file("examples/b.rs", "fn main() {}")
.build();
p.cargo("build --examples").run();
2018-08-29 06:11:10 +00:00
assert!(!p.bin("a").is_file());
assert!(!p.bin("b").is_file());
assert!(p.bin("examples/a").is_file());
assert!(p.bin("examples/b").is_file());
}
#[cargo_test]
fn ignore_dotfile() {
let p = project()
.file("src/bin/.a.rs", "")
.file("src/bin/a.rs", "fn main() {}")
.build();
p.cargo("build").run();
}
#[cargo_test]
fn ignore_dotdirs() {
let p = project()
.file("src/bin/a.rs", "fn main() {}")
.file(".git/Cargo.toml", "")
.file(".pc/dummy-fix.patch/Cargo.toml", "")
.build();
p.cargo("build").run();
}
#[cargo_test]
fn dotdir_root() {
let p = ProjectBuilder::new(root().join(".foo"))
.file("src/bin/a.rs", "fn main() {}")
.build();
p.cargo("build").run();
}
#[cargo_test]
fn custom_target_dir_env() {
let p = project().file("src/main.rs", "fn main() {}").build();
let exe_name = format!("foo{}", env::consts::EXE_SUFFIX);
p.cargo("build").env("CARGO_TARGET_DIR", "foo/target").run();
2018-08-29 06:11:10 +00:00
assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
assert!(!p.root().join("target/debug").join(&exe_name).is_file());
p.cargo("build").run();
2018-08-29 06:11:10 +00:00
assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
assert!(p.root().join("target/debug").join(&exe_name).is_file());
p.cargo("build")
.env("CARGO_BUILD_TARGET_DIR", "foo2/target")
.run();
assert!(p.root().join("foo2/target/debug").join(&exe_name).is_file());
p.change_file(
2024-01-26 19:40:46 +00:00
".cargo/config.toml",
r#"
[build]
target-dir = "foo/target"
"#,
);
p.cargo("build").env("CARGO_TARGET_DIR", "bar/target").run();
2018-08-29 06:11:10 +00:00
assert!(p.root().join("bar/target/debug").join(&exe_name).is_file());
assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
assert!(p.root().join("target/debug").join(&exe_name).is_file());
}
#[cargo_test]
fn custom_target_dir_line_parameter() {
let p = project().file("src/main.rs", "fn main() {}").build();
let exe_name = format!("foo{}", env::consts::EXE_SUFFIX);
p.cargo("build --target-dir foo/target").run();
2018-08-29 06:11:10 +00:00
assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
assert!(!p.root().join("target/debug").join(&exe_name).is_file());
p.cargo("build").run();
2018-08-29 06:11:10 +00:00
assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
assert!(p.root().join("target/debug").join(&exe_name).is_file());
p.change_file(
2024-01-26 19:40:46 +00:00
".cargo/config.toml",
r#"
[build]
target-dir = "foo/target"
"#,
);
p.cargo("build --target-dir bar/target").run();
2018-08-29 06:11:10 +00:00
assert!(p.root().join("bar/target/debug").join(&exe_name).is_file());
assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
assert!(p.root().join("target/debug").join(&exe_name).is_file());
p.cargo("build --target-dir foobar/target")
.env("CARGO_TARGET_DIR", "bar/target")
.run();
2018-12-08 11:19:47 +00:00
assert!(p
.root()
.join("foobar/target/debug")
.join(&exe_name)
.is_file());
2018-08-29 06:11:10 +00:00
assert!(p.root().join("bar/target/debug").join(&exe_name).is_file());
assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
assert!(p.root().join("target/debug").join(&exe_name).is_file());
}
#[cargo_test]
fn build_multiple_packages() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[dependencies.d1]
path = "d1"
[dependencies.d2]
path = "d2"
2020-09-27 00:59:58 +00:00
[[bin]]
name = "foo"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
2018-07-24 22:35:01 +00:00
.file("d1/Cargo.toml", &basic_bin_manifest("d1"))
.file("d1/src/lib.rs", "")
.file("d1/src/main.rs", "fn main() { println!(\"d1\"); }")
2018-03-14 15:17:44 +00:00
.file(
"d2/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "d2"
2020-09-27 00:59:58 +00:00
version = "0.0.1"
authors = []
[[bin]]
name = "d2"
doctest = false
"#,
2018-12-08 11:19:47 +00:00
)
.file("d2/src/main.rs", "fn main() { println!(\"d2\"); }")
.build();
p.cargo("build -p d1 -p d2 -p foo").run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
p.process(&p.bin("foo")).with_stdout("i am foo\n").run();
let d1_path = &p
.build_dir()
2018-03-14 15:17:44 +00:00
.join("debug")
.join(format!("d1{}", env::consts::EXE_SUFFIX));
let d2_path = &p
.build_dir()
2018-03-14 15:17:44 +00:00
.join("debug")
.join(format!("d2{}", env::consts::EXE_SUFFIX));
2018-08-29 06:11:10 +00:00
assert!(d1_path.is_file());
p.process(d1_path).with_stdout("d1").run();
2015-09-24 21:47:50 +00:00
2018-08-29 06:11:10 +00:00
assert!(d2_path.is_file());
p.process(d2_path).with_stdout("d2").run();
}
#[cargo_test]
fn invalid_spec() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[dependencies.d1]
path = "d1"
2020-09-27 00:59:58 +00:00
[[bin]]
name = "foo"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/bin/foo.rs", &main_file(r#""i am foo""#, &[]))
2018-07-24 22:35:01 +00:00
.file("d1/Cargo.toml", &basic_bin_manifest("d1"))
.file("d1/src/lib.rs", "")
.file("d1/src/main.rs", "fn main() { println!(\"d1\"); }")
.build();
p.cargo("build -p notAValidDep")
.with_status(101)
2021-01-22 21:37:52 +00:00
.with_stderr("[ERROR] package ID specification `notAValidDep` did not match any packages")
.run();
p.cargo("build -p d1 -p notAValidDep")
.with_status(101)
2021-01-22 21:37:52 +00:00
.with_stderr("[ERROR] package ID specification `notAValidDep` did not match any packages")
.run();
}
#[cargo_test]
fn manifest_with_bom_is_ok() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
"\u{FEFF}
[package]
name = \"foo\"
version = \"0.0.1\"
authors = []
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
p.cargo("build -v").run();
}
#[cargo_test]
fn panic_abort_compiles_with_panic_abort() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[profile.dev]
panic = 'abort'
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
p.cargo("build -v")
.with_stderr_contains("[..] -C panic=abort [..]")
.run();
}
2016-06-09 20:55:17 +00:00
#[cargo_test]
2016-08-11 21:47:49 +00:00
fn compiler_json_error_format() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
[package]
2016-08-11 21:47:49 +00:00
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.5.0"
authors = ["wycats@example.com"]
2016-08-11 21:47:49 +00:00
2020-09-27 00:59:58 +00:00
[dependencies.bar]
path = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
"build.rs",
"fn main() { println!(\"cargo::rustc-cfg=xyz\") }",
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "fn main() { let unused = 92; }")
2018-07-24 22:35:01 +00:00
.file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0"))
.file("bar/src/lib.rs", r#"fn dead() {}"#)
.build();
2016-08-11 21:47:49 +00:00
2019-09-25 01:17:36 +00:00
let output = |fresh| {
r#"
2020-09-27 00:59:58 +00:00
{
"reason":"compiler-artifact",
"package_id":"path+file:///[..]/foo#0.5.0",
"manifest_path": "[..]",
2020-09-27 00:59:58 +00:00
"target":{
"kind":["custom-build"],
"crate_types":["bin"],
"doc": false,
2020-09-27 00:59:58 +00:00
"doctest": false,
"edition": "2015",
"name":"build-script-build",
"src_path":"[..]build.rs",
"test": false
},
"profile": {
"debug_assertions": true,
"debuginfo": 0,
2020-09-27 00:59:58 +00:00
"opt_level": "0",
"overflow_checks": true,
"test": false
},
"executable": null,
"features": [],
"filenames": "{...}",
"fresh": $FRESH
}
2020-09-27 00:59:58 +00:00
{
"reason":"compiler-message",
"package_id":"path+file:///[..]/bar#0.5.0",
"manifest_path": "[..]",
2020-09-27 00:59:58 +00:00
"target":{
"kind":["lib"],
"crate_types":["lib"],
"doc": true,
2020-09-27 00:59:58 +00:00
"doctest": true,
"edition": "2015",
"name":"bar",
"src_path":"[..]lib.rs",
"test": true
},
"message":"{...}"
}
2020-09-27 00:59:58 +00:00
{
"reason":"compiler-artifact",
"profile": {
"debug_assertions": true,
"debuginfo": 2,
"opt_level": "0",
"overflow_checks": true,
"test": false
},
"executable": null,
"features": [],
"package_id":"path+file:///[..]/bar#0.5.0",
"manifest_path": "[..]",
2020-09-27 00:59:58 +00:00
"target":{
"kind":["lib"],
"crate_types":["lib"],
"doc": true,
2020-09-27 00:59:58 +00:00
"doctest": true,
"edition": "2015",
"name":"bar",
"src_path":"[..]lib.rs",
"test": true
},
"filenames":[
"[..].rlib",
"[..].rmeta"
],
"fresh": $FRESH
}
2020-09-27 00:59:58 +00:00
{
"reason":"build-script-executed",
"package_id":"path+file:///[..]/foo#0.5.0",
2020-09-27 00:59:58 +00:00
"linked_libs":[],
"linked_paths":[],
"env":[],
"cfgs":["xyz"],
"out_dir": "[..]target/debug/build/foo-[..]/out"
}
2020-09-27 00:59:58 +00:00
{
"reason":"compiler-message",
"package_id":"path+file:///[..]/foo#0.5.0",
"manifest_path": "[..]",
2020-09-27 00:59:58 +00:00
"target":{
"kind":["bin"],
"crate_types":["bin"],
"doc": true,
2020-09-27 00:59:58 +00:00
"doctest": false,
"edition": "2015",
"name":"foo",
"src_path":"[..]main.rs",
"test": true
},
"message":"{...}"
}
2020-09-27 00:59:58 +00:00
{
"reason":"compiler-artifact",
"package_id":"path+file:///[..]/foo#0.5.0",
"manifest_path": "[..]",
2020-09-27 00:59:58 +00:00
"target":{
"kind":["bin"],
"crate_types":["bin"],
"doc": true,
2020-09-27 00:59:58 +00:00
"doctest": false,
"edition": "2015",
"name":"foo",
"src_path":"[..]main.rs",
"test": true
},
"profile": {
"debug_assertions": true,
"debuginfo": 2,
"opt_level": "0",
"overflow_checks": true,
"test": false
},
"executable": "[..]/foo/target/debug/foo[EXE]",
"features": [],
"filenames": "{...}",
"fresh": $FRESH
}
2020-04-05 01:54:20 +00:00
2020-09-27 00:59:58 +00:00
{"reason": "build-finished", "success": true}
"#
2019-09-25 01:17:36 +00:00
.replace("$FRESH", fresh)
};
// Use `jobs=1` to ensure that the order of messages is consistent.
p.cargo("build -v --message-format=json --jobs=1")
2020-04-07 13:23:43 +00:00
.with_json_contains_unordered(&output("false"))
2018-12-08 11:19:47 +00:00
.run();
// With fresh build, we should repeat the artifacts,
2019-09-25 01:17:36 +00:00
// and replay the cached compiler warnings.
p.cargo("build -v --message-format=json --jobs=1")
2020-04-07 13:23:43 +00:00
.with_json_contains_unordered(&output("true"))
2018-12-08 11:19:47 +00:00
.run();
2016-08-11 21:47:49 +00:00
}
#[cargo_test]
2016-08-11 21:47:49 +00:00
fn wrong_message_format_option() {
let p = project()
2016-08-11 21:47:49 +00:00
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/main.rs", "fn main() {}")
.build();
2016-08-11 21:47:49 +00:00
p.cargo("build --message-format XML")
Add support for customizing JSON diagnostics from Cargo Cargo has of #7143 enabled pipelined compilation by default which affects how the compiler is invoked, especially with respect to JSON messages. This, in some testing, has proven to cause quite a few issues with rustbuild's current integration with Cargo. This commit is aimed at adding features to Cargo to solve this issue. This commit adds the ability to customize the stream of JSON messages coming from Cargo. The new feature for Cargo is that it now also mirrors rustc in how you can configure the JSON stream. Multiple `--message-format` arguments are now supported and the value specified is a comma-separated list of directives. In addition to the existing `human`, `short`, and `json` directives these new directives have been added: * `json-render-diagnostics` - instructs Cargo to render rustc diagnostics and only print out JSON messages for artifacts and Cargo things. * `json-diagnostic-short` - indicates that the `rendered` field of rustc diagnostics should use the "short" rendering. * `json-diagnostic-rendered-ansi` - indicates that the `rendered` field of rustc diagnostics should embed ansi color codes. The first option here, `json-render-diagnostics`, will be used by rustbuild unconditionally. Additionally `json-diagnostic-short` will be conditionally used based on the input to rustbuild itself. This should be enough for external tools to customize how Cargo is invoked and how all kinds of JSON diagnostics get printed, and it's thought that we can relatively easily tweak this as necessary to extend it and such.
2019-08-05 16:42:28 +00:00
.with_status(101)
.with_stderr_contains(
2018-03-14 15:17:44 +00:00
"\
Add support for customizing JSON diagnostics from Cargo Cargo has of #7143 enabled pipelined compilation by default which affects how the compiler is invoked, especially with respect to JSON messages. This, in some testing, has proven to cause quite a few issues with rustbuild's current integration with Cargo. This commit is aimed at adding features to Cargo to solve this issue. This commit adds the ability to customize the stream of JSON messages coming from Cargo. The new feature for Cargo is that it now also mirrors rustc in how you can configure the JSON stream. Multiple `--message-format` arguments are now supported and the value specified is a comma-separated list of directives. In addition to the existing `human`, `short`, and `json` directives these new directives have been added: * `json-render-diagnostics` - instructs Cargo to render rustc diagnostics and only print out JSON messages for artifacts and Cargo things. * `json-diagnostic-short` - indicates that the `rendered` field of rustc diagnostics should use the "short" rendering. * `json-diagnostic-rendered-ansi` - indicates that the `rendered` field of rustc diagnostics should embed ansi color codes. The first option here, `json-render-diagnostics`, will be used by rustbuild unconditionally. Additionally `json-diagnostic-short` will be conditionally used based on the input to rustbuild itself. This should be enough for external tools to customize how Cargo is invoked and how all kinds of JSON diagnostics get printed, and it's thought that we can relatively easily tweak this as necessary to extend it and such.
2019-08-05 16:42:28 +00:00
error: invalid message format specifier: `xml`
2018-03-14 15:17:44 +00:00
",
2018-12-08 11:19:47 +00:00
)
.run();
2016-08-11 21:47:49 +00:00
}
#[cargo_test]
fn message_format_json_forward_stderr() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/main.rs", "fn main() { let unused = 0; }")
.build();
p.cargo("rustc --release --bin foo --message-format JSON")
2020-04-07 13:23:43 +00:00
.with_json_contains_unordered(
2018-03-14 15:17:44 +00:00
r#"
2020-09-27 00:59:58 +00:00
{
"reason":"compiler-message",
"package_id":"path+file:///[..]/foo#0.5.0",
"manifest_path": "[..]",
2020-09-27 00:59:58 +00:00
"target":{
"kind":["bin"],
"crate_types":["bin"],
"doc": true,
2020-09-27 00:59:58 +00:00
"doctest": false,
"edition": "2015",
"name":"foo",
"src_path":"[..]",
"test": true
},
"message":"{...}"
}
2020-09-27 00:59:58 +00:00
{
"reason":"compiler-artifact",
"package_id":"path+file:///[..]/foo#0.5.0",
"manifest_path": "[..]",
2020-09-27 00:59:58 +00:00
"target":{
"kind":["bin"],
"crate_types":["bin"],
"doc": true,
2020-09-27 00:59:58 +00:00
"doctest": false,
"edition": "2015",
"name":"foo",
"src_path":"[..]",
"test": true
},
"profile":{
"debug_assertions":false,
"debuginfo":0,
2020-09-27 00:59:58 +00:00
"opt_level":"3",
"overflow_checks": false,
"test":false
},
"executable": "{...}",
"features":[],
"filenames": "{...}",
"fresh": false
}
2020-04-05 01:54:20 +00:00
2020-09-27 00:59:58 +00:00
{"reason": "build-finished", "success": true}
"#,
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn no_warn_about_package_metadata() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"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
[package.metadata]
foo = "bar"
a = true
b = 3
2020-09-27 00:59:58 +00:00
[package.metadata.another]
bar = 3
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
p.cargo("build")
.with_stderr(
2018-03-14 15:17:44 +00:00
"[..] foo v0.0.1 ([..])\n\
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
2018-12-08 11:19:47 +00:00
)
.run();
}
2016-10-25 18:52:47 +00:00
#[cargo_test]
fn no_warn_about_workspace_metadata() {
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["foo"]
[workspace.metadata]
something = "something_else"
x = 1
y = 2
[workspace.metadata.another]
bar = 12
"#,
)
.file(
"foo/Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
"#,
)
.file("foo/src/lib.rs", "")
.build();
p.cargo("build")
.with_stderr(
"[..] foo v0.0.1 ([..])\n\
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
)
.run();
}
#[cargo_test]
2016-10-25 18:52:47 +00:00
fn cargo_build_empty_target() {
let p = project()
2016-10-25 18:52:47 +00:00
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/main.rs", "fn main() {}")
.build();
2016-10-25 18:52:47 +00:00
p.cargo("build --target")
.arg("")
.with_status(101)
.with_stderr_contains("[..] target was empty")
.run();
2016-10-25 18:52:47 +00:00
}
#[cargo_test]
fn cargo_build_with_unsupported_short_target_flag() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("build -t")
.arg("")
.with_stderr(
"\
error: unexpected argument '-t' found
tip: a similar argument exists: '--target'
Usage: cargo[EXE] build [OPTIONS]
For more information, try '--help'.
",
)
.with_status(1)
.run();
}
#[cargo_test]
fn build_all_workspace() {
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.1.0"
2020-09-27 00:59:58 +00:00
[dependencies]
bar = { path = "bar" }
2020-09-27 00:59:58 +00:00
[workspace]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "fn main() {}")
2018-07-24 22:35:01 +00:00
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "pub fn bar() {}")
.build();
2019-08-12 12:31:20 +00:00
p.cargo("build --workspace")
.with_stderr(
"\
[COMPILING] bar v0.1.0 ([..])
[COMPILING] foo v0.1.0 ([..])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
2017-05-12 13:44:15 +00:00
fn build_all_exclude() {
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.1.0"
2017-05-12 13:44:15 +00:00
2020-09-27 00:59:58 +00:00
[workspace]
members = ["bar", "baz"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "fn main() {}")
2018-07-24 22:35:01 +00:00
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "pub fn bar() {}")
2018-07-24 22:35:01 +00:00
.file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
.file("baz/src/lib.rs", "pub fn baz() { break_the_build(); }")
.build();
2017-05-12 13:44:15 +00:00
2019-08-12 12:31:20 +00:00
p.cargo("build --workspace --exclude baz")
.with_stderr_does_not_contain("[COMPILING] baz v0.1.0 [..]")
2020-10-10 00:05:24 +00:00
.with_stderr_unordered(
"\
2020-10-10 00:05:24 +00:00
[COMPILING] foo v0.1.0 ([..])
[COMPILING] bar v0.1.0 ([..])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}
#[cargo_test]
fn cargo_build_with_unsupported_short_exclude_flag() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[workspace]
members = ["bar", "baz"]
"#,
)
.file("src/main.rs", "fn main() {}")
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "pub fn bar() {}")
.file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
.file("baz/src/lib.rs", "pub fn baz() { break_the_build(); }")
.build();
p.cargo("build --workspace -x baz")
.with_stderr(
"\
error: unexpected argument '-x' found
tip: a similar argument exists: '--exclude'
Usage: cargo[EXE] build [OPTIONS]
For more information, try '--help'.
",
)
.with_status(1)
.run();
}
#[cargo_test]
fn build_all_exclude_not_found() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[workspace]
members = ["bar"]
"#,
)
.file("src/main.rs", "fn main() {}")
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "pub fn bar() {}")
.build();
p.cargo("build --workspace --exclude baz")
.with_stderr_does_not_contain("[COMPILING] baz v0.1.0 [..]")
2020-10-10 00:05:24 +00:00
.with_stderr_unordered(
"\
[WARNING] excluded package(s) `baz` not found in workspace [..]
2020-10-10 00:05:24 +00:00
[COMPILING] foo v0.1.0 ([..])
[COMPILING] bar v0.1.0 ([..])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}
#[cargo_test]
fn build_all_exclude_glob() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[workspace]
members = ["bar", "baz"]
"#,
)
.file("src/main.rs", "fn main() {}")
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "pub fn bar() {}")
.file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
.file("baz/src/lib.rs", "pub fn baz() { break_the_build(); }")
.build();
p.cargo("build --workspace --exclude '*z'")
.with_stderr_does_not_contain("[COMPILING] baz v0.1.0 [..]")
2020-10-10 00:05:24 +00:00
.with_stderr_unordered(
"\
2020-10-10 00:05:24 +00:00
[COMPILING] foo v0.1.0 ([..])
[COMPILING] bar v0.1.0 ([..])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}
#[cargo_test]
fn build_all_exclude_glob_not_found() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[workspace]
members = ["bar"]
"#,
)
.file("src/main.rs", "fn main() {}")
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "pub fn bar() {}")
.build();
p.cargo("build --workspace --exclude '*z'")
.with_stderr_does_not_contain("[COMPILING] baz v0.1.0 [..]")
.with_stderr(
"\
[WARNING] excluded package pattern(s) `*z` not found in workspace [..]
[COMPILING] [..] v0.1.0 ([..])
[COMPILING] [..] v0.1.0 ([..])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}
#[cargo_test]
fn build_all_exclude_broken_glob() {
let p = project().file("src/main.rs", "fn main() {}").build();
p.cargo("build --workspace --exclude '[*z'")
.with_status(101)
.with_stderr_contains("[ERROR] cannot build glob pattern from `[*z`")
.run();
2017-05-12 13:44:15 +00:00
}
#[cargo_test]
fn build_all_workspace_implicit_examples() {
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.1.0"
2020-09-27 00:59:58 +00:00
[dependencies]
bar = { path = "bar" }
2020-09-27 00:59:58 +00:00
[workspace]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.file("src/bin/a.rs", "fn main() {}")
.file("src/bin/b.rs", "fn main() {}")
.file("examples/c.rs", "fn main() {}")
.file("examples/d.rs", "fn main() {}")
2018-07-24 22:35:01 +00:00
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "")
.file("bar/src/bin/e.rs", "fn main() {}")
.file("bar/src/bin/f.rs", "fn main() {}")
.file("bar/examples/g.rs", "fn main() {}")
.file("bar/examples/h.rs", "fn main() {}")
.build();
2019-08-12 12:31:20 +00:00
p.cargo("build --workspace --examples")
.with_stderr(
2018-03-14 15:17:44 +00:00
"[..] Compiling bar v0.1.0 ([..])\n\
[..] Compiling foo v0.1.0 ([..])\n\
[..] Finished dev [unoptimized + debuginfo] target(s) in [..]\n",
2018-12-08 11:19:47 +00:00
)
.run();
2018-08-29 06:11:10 +00:00
assert!(!p.bin("a").is_file());
assert!(!p.bin("b").is_file());
assert!(p.bin("examples/c").is_file());
assert!(p.bin("examples/d").is_file());
assert!(!p.bin("e").is_file());
assert!(!p.bin("f").is_file());
assert!(p.bin("examples/g").is_file());
assert!(p.bin("examples/h").is_file());
}
#[cargo_test]
fn build_all_virtual_manifest() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[workspace]
members = ["bar", "baz"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "pub fn bar() {}")
2018-07-24 22:35:01 +00:00
.file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
.file("baz/src/lib.rs", "pub fn baz() {}")
.build();
// The order in which bar and baz are built is not guaranteed
2019-08-12 12:31:20 +00:00
p.cargo("build --workspace")
2020-10-10 00:05:24 +00:00
.with_stderr_unordered(
"\
[COMPILING] baz v0.1.0 ([..])
[COMPILING] bar v0.1.0 ([..])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
2017-05-26 21:00:45 +00:00
fn build_virtual_manifest_all_implied() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[workspace]
members = ["bar", "baz"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "pub fn bar() {}")
2018-07-24 22:35:01 +00:00
.file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
.file("baz/src/lib.rs", "pub fn baz() {}")
.build();
2017-05-26 21:00:45 +00:00
2019-02-03 04:01:23 +00:00
// The order in which `bar` and `baz` are built is not guaranteed.
p.cargo("build")
2020-10-10 00:05:24 +00:00
.with_stderr_unordered(
"\
[COMPILING] baz v0.1.0 ([..])
[COMPILING] bar v0.1.0 ([..])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
2018-12-08 11:19:47 +00:00
)
.run();
2017-05-26 21:00:45 +00:00
}
#[cargo_test]
fn build_virtual_manifest_one_project() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[workspace]
members = ["bar", "baz"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "pub fn bar() {}")
2018-07-24 22:35:01 +00:00
.file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
.file("baz/src/lib.rs", "pub fn baz() { break_the_build(); }")
.build();
p.cargo("build -p bar")
.with_stderr_does_not_contain("[..]baz[..]")
.with_stderr(
"\
[COMPILING] bar v0.1.0 ([..])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}
#[cargo_test]
fn build_virtual_manifest_glob() {
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["bar", "baz"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "pub fn bar() { break_the_build(); }")
.file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
.file("baz/src/lib.rs", "pub fn baz() {}")
.build();
p.cargo("build -p '*z'")
.with_stderr_does_not_contain("[..]bar[..]")
.with_stderr(
"\
[COMPILING] baz v0.1.0 ([..])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}
#[cargo_test]
fn build_virtual_manifest_glob_not_found() {
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["bar"]
"#,
)
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "pub fn bar() {}")
.build();
p.cargo("build -p bar -p '*z'")
.with_status(101)
.with_stderr("[ERROR] package pattern(s) `*z` not found in workspace [..]")
.run();
}
#[cargo_test]
fn build_virtual_manifest_broken_glob() {
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["bar"]
"#,
)
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "pub fn bar() {}")
.build();
p.cargo("build -p '[*z'")
.with_status(101)
.with_stderr_contains("[ERROR] cannot build glob pattern from `[*z`")
2018-12-08 11:19:47 +00:00
.run();
}
#[cargo_test]
fn build_all_virtual_manifest_implicit_examples() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[workspace]
members = ["bar", "baz"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "")
.file("bar/src/bin/a.rs", "fn main() {}")
.file("bar/src/bin/b.rs", "fn main() {}")
.file("bar/examples/c.rs", "fn main() {}")
.file("bar/examples/d.rs", "fn main() {}")
2018-07-24 22:35:01 +00:00
.file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
.file("baz/src/lib.rs", "")
.file("baz/src/bin/e.rs", "fn main() {}")
.file("baz/src/bin/f.rs", "fn main() {}")
.file("baz/examples/g.rs", "fn main() {}")
.file("baz/examples/h.rs", "fn main() {}")
.build();
// The order in which bar and baz are built is not guaranteed
2019-08-12 12:31:20 +00:00
p.cargo("build --workspace --examples")
2020-10-10 00:05:24 +00:00
.with_stderr_unordered(
"\
[COMPILING] baz v0.1.0 ([..])
[COMPILING] bar v0.1.0 ([..])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
2018-12-08 11:19:47 +00:00
)
.run();
2018-08-29 06:11:10 +00:00
assert!(!p.bin("a").is_file());
assert!(!p.bin("b").is_file());
assert!(p.bin("examples/c").is_file());
assert!(p.bin("examples/d").is_file());
assert!(!p.bin("e").is_file());
assert!(!p.bin("f").is_file());
assert!(p.bin("examples/g").is_file());
assert!(p.bin("examples/h").is_file());
}
#[cargo_test]
fn build_all_member_dependency_same_name() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[workspace]
members = ["a"]
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"a/Cargo.toml",
r#"
[package]
2020-09-27 00:59:58 +00:00
name = "a"
version = "0.1.0"
2020-09-27 00:59:58 +00:00
[dependencies]
a = "0.1.0"
"#,
2018-12-08 11:19:47 +00:00
)
.file("a/src/lib.rs", "pub fn a() {}")
.build();
Package::new("a", "0.1.0").publish();
2019-08-12 12:31:20 +00:00
p.cargo("build --workspace")
.with_stderr(
2018-09-14 20:33:18 +00:00
"[UPDATING] `[..]` index\n\
[DOWNLOADING] crates ...\n\
[DOWNLOADED] a v0.1.0 ([..])\n\
[COMPILING] a v0.1.0\n\
[COMPILING] a v0.1.0 ([..])\n\
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
2017-01-28 23:56:30 +00:00
fn run_proper_binary() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
authors = []
version = "0.0.0"
[[bin]]
name = "main"
[[bin]]
name = "other"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.file(
"src/bin/main.rs",
r#"fn main() { panic!("This should never be run."); }"#,
2018-12-08 11:19:47 +00:00
)
.file("src/bin/other.rs", "fn main() {}")
.build();
2017-01-28 23:56:30 +00:00
p.cargo("run --bin other").run();
2017-01-28 23:56:30 +00:00
}
#[cargo_test]
fn run_proper_binary_main_rs() {
let p = project()
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/lib.rs", "")
.file("src/bin/main.rs", "fn main() {}")
.build();
p.cargo("run --bin foo").run();
}
2017-04-04 21:58:31 +00:00
#[cargo_test]
2017-05-14 20:47:24 +00:00
fn run_proper_alias_binary_from_src() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
authors = []
version = "0.0.0"
[[bin]]
name = "foo"
[[bin]]
name = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/foo.rs", r#"fn main() { println!("foo"); }"#)
.file("src/bar.rs", r#"fn main() { println!("bar"); }"#)
.build();
2017-05-14 20:47:24 +00:00
2019-08-12 12:31:20 +00:00
p.cargo("build --workspace").run();
p.process(&p.bin("foo")).with_stdout("foo\n").run();
p.process(&p.bin("bar")).with_stdout("bar\n").run();
2017-05-14 20:47:24 +00:00
}
#[cargo_test]
2017-05-14 20:47:24 +00:00
fn run_proper_alias_binary_main_rs() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
authors = []
version = "0.0.0"
[[bin]]
name = "foo"
[[bin]]
name = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", r#"fn main() { println!("main"); }"#)
.build();
2017-05-14 20:47:24 +00:00
2019-08-12 12:31:20 +00:00
p.cargo("build --workspace").run();
p.process(&p.bin("foo")).with_stdout("main\n").run();
p.process(&p.bin("bar")).with_stdout("main\n").run();
2017-05-14 20:47:24 +00:00
}
#[cargo_test]
2017-04-04 21:58:31 +00:00
fn run_proper_binary_main_rs_as_foo() {
let p = project()
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file(
"src/foo.rs",
r#" fn main() { panic!("This should never be run."); }"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "fn main() {}")
.build();
2017-04-04 21:58:31 +00:00
p.cargo("run --bin foo").run();
2017-04-04 21:58:31 +00:00
}
#[cargo_test]
fn rustc_wrapper() {
let p = project().file("src/lib.rs", "").build();
let wrapper = tools::echo_wrapper();
let running = format!(
"[RUNNING] `{} rustc --crate-name foo [..]",
wrapper.display()
);
p.cargo("build -v")
.env("RUSTC_WRAPPER", &wrapper)
.with_stderr_contains(&running)
.run();
p.build_dir().rm_rf();
p.cargo("build -v")
.env("RUSTC_WORKSPACE_WRAPPER", &wrapper)
.with_stderr_contains(&running)
.run();
}
#[cargo_test]
fn rustc_wrapper_relative() {
Package::new("bar", "1.0.0").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
bar = "1.0"
"#,
)
.file("src/lib.rs", "")
.build();
let wrapper = tools::echo_wrapper();
let exe_name = wrapper.file_name().unwrap().to_str().unwrap();
let relative_path = format!("./{}", exe_name);
fs::hard_link(&wrapper, p.root().join(exe_name)).unwrap();
let running = format!("[RUNNING] `[ROOT]/foo/./{} rustc[..]", exe_name);
p.cargo("build -v")
.env("RUSTC_WRAPPER", &relative_path)
.with_stderr_contains(&running)
.run();
p.build_dir().rm_rf();
2020-12-13 22:50:15 +00:00
p.cargo("build -v")
.env("RUSTC_WORKSPACE_WRAPPER", &relative_path)
.with_stderr_contains(&running)
.run();
p.build_dir().rm_rf();
p.change_file(
".cargo/config.toml",
&format!(
r#"
build.rustc-wrapper = "./{}"
"#,
exe_name
),
);
p.cargo("build -v").with_stderr_contains(&running).run();
}
#[cargo_test]
fn rustc_wrapper_from_path() {
let p = project().file("src/lib.rs", "").build();
2020-12-13 22:50:15 +00:00
p.cargo("build -v")
.env("RUSTC_WRAPPER", "wannabe_sccache")
.with_status(101)
.with_stderr_contains("[..]`wannabe_sccache rustc [..]")
.run();
p.build_dir().rm_rf();
2020-12-13 22:50:15 +00:00
p.cargo("build -v")
.env("RUSTC_WORKSPACE_WRAPPER", "wannabe_sccache")
.with_status(101)
.with_stderr_contains("[..]`wannabe_sccache rustc [..]")
.run();
}
#[cargo_test]
fn cdylib_not_lifted() {
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"
authors = []
version = "0.1.0"
2020-09-27 00:59:58 +00:00
[lib]
crate-type = ["cdylib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
p.cargo("build").run();
let files = if cfg!(windows) {
2020-04-20 16:57:56 +00:00
if cfg!(target_env = "msvc") {
vec!["foo.dll.lib", "foo.dll.exp", "foo.dll"]
} else {
vec!["libfoo.dll.a", "foo.dll"]
}
} else if cfg!(target_os = "macos") {
vec!["libfoo.dylib"]
} else {
vec!["libfoo.so"]
};
for file in files {
println!("checking: {}", file);
2018-08-29 06:11:10 +00:00
assert!(p.root().join("target/debug/deps").join(&file).is_file());
}
}
#[cargo_test]
fn cdylib_final_outputs() {
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-bar"
authors = []
version = "0.1.0"
2020-09-27 00:59:58 +00:00
[lib]
crate-type = ["cdylib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
p.cargo("build").run();
let files = if cfg!(windows) {
2020-04-20 16:57:56 +00:00
if cfg!(target_env = "msvc") {
vec!["foo_bar.dll.lib", "foo_bar.dll"]
} else {
vec!["foo_bar.dll", "libfoo_bar.dll.a"]
2020-04-20 16:57:56 +00:00
}
} else if cfg!(target_os = "macos") {
vec!["libfoo_bar.dylib"]
} else {
vec!["libfoo_bar.so"]
};
for file in files {
println!("checking: {}", file);
2018-08-29 06:11:10 +00:00
assert!(p.root().join("target/debug").join(&file).is_file());
}
}
#[cargo_test]
// NOTE: Windows MSVC and wasm32-unknown-emscripten do not use metadata. Skip them.
// See <https://github.com/rust-lang/cargo/issues/9325#issuecomment-1030662699>
#[cfg(not(all(target_os = "windows", target_env = "msvc")))]
fn no_dep_info_collision_when_cdylib_and_bin_coexist() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "1.0.0"
[lib]
crate-type = ["cdylib"]
"#,
)
.file("src/main.rs", "fn main() {}")
.file("src/lib.rs", "")
.build();
p.cargo("build -v")
.with_stderr_unordered(
"\
[COMPILING] foo v1.0.0 ([CWD])
[RUNNING] `rustc [..] --crate-type bin [..] -C metadata=[..]`
[RUNNING] `rustc [..] --crate-type cdylib [..] -C metadata=[..]`
[FINISHED] [..]
",
)
.run();
let deps_dir = p.target_debug_dir().join("deps");
assert!(deps_dir.join("foo.d").exists());
let dep_info_count = deps_dir
.read_dir()
.unwrap()
.filter(|e| {
let filename = e.as_ref().unwrap().file_name();
let filename = filename.to_str().unwrap();
filename.starts_with("foo") && filename.ends_with(".d")
})
.count();
// cdylib -> foo.d
// bin -> foo-<meta>.d
assert_eq!(dep_info_count, 2);
}
#[cargo_test]
fn deterministic_cfg_flags() {
2019-02-03 04:01:23 +00:00
// This bug is non-deterministic.
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.1.0"
authors = []
build = "build.rs"
[features]
default = ["f_a", "f_b", "f_c", "f_d"]
f_a = []
f_b = []
f_c = []
f_d = []
"#,
2018-12-08 11:19:47 +00:00
)
.file(
2018-03-14 15:17:44 +00:00
"build.rs",
r#"
fn main() {
println!("cargo::rustc-cfg=cfg_a");
println!("cargo::rustc-cfg=cfg_b");
println!("cargo::rustc-cfg=cfg_c");
println!("cargo::rustc-cfg=cfg_d");
println!("cargo::rustc-cfg=cfg_e");
}
2018-03-14 15:17:44 +00:00
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("build -v")
.with_stderr(
2018-03-14 15:17:44 +00:00
"\
[COMPILING] foo v0.1.0 [..]
[RUNNING] [..]
[RUNNING] [..]
[RUNNING] `rustc --crate-name foo [..] \
--cfg[..]default[..]--cfg[..]f_a[..]--cfg[..]f_b[..]\
--cfg[..]f_c[..]--cfg[..]f_d[..] \
--cfg cfg_a --cfg cfg_b --cfg cfg_c --cfg cfg_d --cfg cfg_e`
2018-03-14 15:17:44 +00:00
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
2018-12-08 11:19:47 +00:00
)
.run();
}
2017-06-16 19:41:27 +00:00
#[cargo_test]
2017-06-16 19:41:27 +00:00
fn explicit_bins_without_paths() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.1.0"
authors = []
2017-06-16 19:41:27 +00:00
2020-09-27 00:59:58 +00:00
[[bin]]
name = "foo"
2017-06-16 19:41:27 +00:00
2020-09-27 00:59:58 +00:00
[[bin]]
name = "bar"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
2017-06-16 19:41:27 +00:00
.file("src/main.rs", "fn main() {}")
.file("src/bin/bar.rs", "fn main() {}")
.build();
2017-06-16 19:41:27 +00:00
p.cargo("build").run();
2017-06-16 19:41:27 +00:00
}
#[cargo_test]
fn no_bin_in_src_with_lib() {
let p = project()
2018-07-24 22:35:01 +00:00
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/lib.rs", "")
.file("src/foo.rs", "fn main() {}")
.build();
p.cargo("build")
.with_status(101)
.with_stderr_contains(
2018-03-14 15:17:44 +00:00
"\
[ERROR] failed to parse manifest at `[..]`
Caused by:
can't find `foo` bin at `src/bin/foo.rs` or `src/bin/foo/main.rs`. [..]",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
2017-10-23 09:18:12 +00:00
fn inferred_bins() {
let p = project()
.file("src/main.rs", "fn main() {}")
.file("src/bin/bar.rs", "fn main() {}")
2017-10-23 09:18:12 +00:00
.file("src/bin/baz/main.rs", "fn main() {}")
.build();
p.cargo("build").run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("foo").is_file());
assert!(p.bin("bar").is_file());
assert!(p.bin("baz").is_file());
}
#[cargo_test]
2017-10-23 09:18:12 +00:00
fn inferred_bins_duplicate_name() {
// this should fail, because we have two binaries with the same name
let p = project()
.file("src/main.rs", "fn main() {}")
.file("src/bin/bar.rs", "fn main() {}")
.file("src/bin/bar/main.rs", "fn main() {}")
.build();
p.cargo("build").with_status(101).with_stderr_contains(
"[..]found duplicate binary name bar, but all binary targets must have a unique name[..]",
)
.run();
}
#[cargo_test]
2017-10-23 09:18:12 +00:00
fn inferred_bin_path() {
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.1.0"
authors = []
2020-09-27 00:59:58 +00:00
[[bin]]
name = "bar"
# Note, no `path` key!
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/bin/bar/main.rs", "fn main() {}")
.build();
p.cargo("build").run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("bar").is_file());
}
#[cargo_test]
2017-09-15 13:37:34 +00:00
fn inferred_examples() {
let p = project()
2017-09-15 13:37:34 +00:00
.file("src/lib.rs", "fn main() {}")
.file("examples/bar.rs", "fn main() {}")
.file("examples/baz/main.rs", "fn main() {}")
.build();
2017-09-15 13:37:34 +00:00
2019-02-19 17:32:07 +00:00
p.cargo("build --examples").run();
2018-08-29 06:11:10 +00:00
assert!(p.bin("examples/bar").is_file());
assert!(p.bin("examples/baz").is_file());
2017-09-15 13:37:34 +00:00
}
#[cargo_test]
2017-09-15 13:37:34 +00:00
fn inferred_tests() {
let p = project()
2017-09-15 13:37:34 +00:00
.file("src/lib.rs", "fn main() {}")
.file("tests/bar.rs", "fn main() {}")
.file("tests/baz/main.rs", "fn main() {}")
.build();
2017-09-15 13:37:34 +00:00
p.cargo("test --test=bar --test=baz").run();
2017-09-15 13:37:34 +00:00
}
#[cargo_test]
2017-10-23 09:18:12 +00:00
fn inferred_benchmarks() {
let p = project()
2017-09-15 13:37:34 +00:00
.file("src/lib.rs", "fn main() {}")
.file("benches/bar.rs", "fn main() {}")
2017-10-23 09:18:12 +00:00
.file("benches/baz/main.rs", "fn main() {}")
.build();
2017-09-15 13:37:34 +00:00
p.cargo("bench --bench=bar --bench=baz").run();
2017-09-15 13:37:34 +00:00
}
#[cargo_test]
fn no_infer_dirs() {
let p = project()
.file("src/lib.rs", "fn main() {}")
.file("examples/dir.rs/dummy", "")
.file("benches/dir.rs/dummy", "")
.file("tests/dir.rs/dummy", "")
.build();
p.cargo("build --examples --benches --tests").run(); // should not fail with "is a directory"
}
#[cargo_test]
fn target_edition() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
[lib]
edition = "2018"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
p.cargo("build -v")
.with_stderr_contains(
"\
[COMPILING] foo v0.0.1 ([..])
[RUNNING] `rustc [..]--edition=2018 [..]
",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn target_edition_override() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2018"
[lib]
edition = "2015"
"#,
2018-12-08 11:19:47 +00:00
)
.file(
"src/lib.rs",
"
pub fn async() {}
pub fn try() {}
pub fn await() {}
2018-12-08 11:19:47 +00:00
",
)
.build();
p.cargo("build -v").run();
}
#[cargo_test]
fn same_metadata_different_directory() {
// A top-level crate built in two different workspaces should have the
// same metadata hash.
let p = project()
.at("foo1")
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.build();
let output = t!(String::from_utf8(
t!(p.cargo("build -v").exec_with_output()).stderr,
));
let metadata = output
.split_whitespace()
2017-09-24 14:26:37 +00:00
.find(|arg| arg.starts_with("metadata="))
.unwrap();
let p = project()
.at("foo2")
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.build();
p.cargo("build -v")
.with_stderr_contains(format!("[..]{}[..]", metadata))
.run();
}
#[cargo_test]
fn building_a_dependent_crate_without_bin_should_fail() {
Package::new("testless", "0.1.0")
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
[package]
2020-09-27 00:59:58 +00:00
name = "testless"
version = "0.1.0"
2020-09-27 00:59:58 +00:00
[[bin]]
name = "a_bin"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.publish();
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.1.0"
2020-09-27 00:59:58 +00:00
[dependencies]
testless = "0.1.0"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/lib.rs", "")
.build();
p.cargo("build")
.with_status(101)
.with_stderr_contains(
"[..]can't find `a_bin` bin at `src/bin/a_bin.rs` or `src/bin/a_bin/main.rs`[..]",
)
.run();
}
2017-10-13 19:13:32 +00:00
#[cargo_test]
#[cfg(any(target_os = "macos", target_os = "ios"))]
2017-10-13 19:13:32 +00:00
fn uplift_dsym_of_bin_on_mac() {
let p = project()
2017-10-13 19:13:32 +00:00
.file("src/main.rs", "fn main() { panic!(); }")
.file("src/bin/b.rs", "fn main() { panic!(); }")
.file("examples/c.rs", "fn main() { panic!(); }")
.file("tests/d.rs", "fn main() { panic!(); }")
.build();
p.cargo("build --bins --examples --tests")
.enable_mac_dsym()
.run();
assert!(p.target_debug_dir().join("foo.dSYM").is_dir());
assert!(p.target_debug_dir().join("b.dSYM").is_dir());
2022-01-13 21:36:24 +00:00
assert!(p.target_debug_dir().join("b.dSYM").is_symlink());
assert!(p.target_debug_dir().join("examples/c.dSYM").is_dir());
assert!(!p.target_debug_dir().join("c.dSYM").exists());
assert!(!p.target_debug_dir().join("d.dSYM").exists());
2017-10-13 19:13:32 +00:00
}
Fix dSYM uplifting when symlink is broken We were sporadically but persistently seeing errors like failed to link or copy `.../target/debugs/deps/bin-264030cd6c8a02be.dSYM` to `.../target/debug/bin.dSYM` Caused by: the source path is not an existing regular file while running `cargo build`. Once the error occurs once, `cargo build` will fail forever with the same error until `target/debug/bin.dSYM` is manually unlinked. After some investigation, I've determined that this situation arises when the target of `bin.dSYM` goes missing. For example, if bin.dSYM is pointing at `deps/bin-86908f0fa7f1440e.dSYM`, and `deps/bin-86908f0fa7f1440e.dSYM` does not exist, then this error will occur. I'm still not clear on why the underlying dSYM bundle sporadically goes missing--perhaps it's the result of pressing Ctrl-C at the wrong moment?--but Cargo should at least be able to handle this situation better. It turns out that Cargo was getting confused by the broken symlink. When it goes to install the new `target/debug/bin.dSYM` link, it will remove the existing `target/debug/bin.dSYM` file, if it exists. Unfortunately, Cargo was checking whether the *target* of that symlink existed (e.g., `deps/bin-86908f0fa7f1440e.dSYM`, which in the buggy case would not exist), rather than the symlink itself, deciding that there was no existing symlink to remove, and crashing with EEXIST when trying to install the new symlink. This commit adjusts the existence check to evaluate whether the symlink itself exists, rather than its target. Note that while the symptoms are the same as #4671, the root cause is unrelated.
2019-08-19 20:45:42 +00:00
#[cargo_test]
#[cfg(any(target_os = "macos", target_os = "ios"))]
fn uplift_dsym_of_bin_on_mac_when_broken_link_exists() {
let p = project()
.file("src/main.rs", "fn main() { panic!(); }")
.build();
let dsym = p.target_debug_dir().join("foo.dSYM");
p.cargo("build").enable_mac_dsym().run();
Fix dSYM uplifting when symlink is broken We were sporadically but persistently seeing errors like failed to link or copy `.../target/debugs/deps/bin-264030cd6c8a02be.dSYM` to `.../target/debug/bin.dSYM` Caused by: the source path is not an existing regular file while running `cargo build`. Once the error occurs once, `cargo build` will fail forever with the same error until `target/debug/bin.dSYM` is manually unlinked. After some investigation, I've determined that this situation arises when the target of `bin.dSYM` goes missing. For example, if bin.dSYM is pointing at `deps/bin-86908f0fa7f1440e.dSYM`, and `deps/bin-86908f0fa7f1440e.dSYM` does not exist, then this error will occur. I'm still not clear on why the underlying dSYM bundle sporadically goes missing--perhaps it's the result of pressing Ctrl-C at the wrong moment?--but Cargo should at least be able to handle this situation better. It turns out that Cargo was getting confused by the broken symlink. When it goes to install the new `target/debug/bin.dSYM` link, it will remove the existing `target/debug/bin.dSYM` file, if it exists. Unfortunately, Cargo was checking whether the *target* of that symlink existed (e.g., `deps/bin-86908f0fa7f1440e.dSYM`, which in the buggy case would not exist), rather than the symlink itself, deciding that there was no existing symlink to remove, and crashing with EEXIST when trying to install the new symlink. This commit adjusts the existence check to evaluate whether the symlink itself exists, rather than its target. Note that while the symptoms are the same as #4671, the root cause is unrelated.
2019-08-19 20:45:42 +00:00
assert!(dsym.is_dir());
// Simulate the situation where the underlying dSYM bundle goes missing
// but the uplifted symlink to it remains. This would previously cause
// builds to permanently fail until the bad symlink was manually removed.
dsym.rm_rf();
p.symlink(
p.target_debug_dir()
.join("deps")
.join("foo-baaaaaadbaaaaaad.dSYM"),
&dsym,
);
2022-01-13 21:36:24 +00:00
assert!(dsym.is_symlink());
Fix dSYM uplifting when symlink is broken We were sporadically but persistently seeing errors like failed to link or copy `.../target/debugs/deps/bin-264030cd6c8a02be.dSYM` to `.../target/debug/bin.dSYM` Caused by: the source path is not an existing regular file while running `cargo build`. Once the error occurs once, `cargo build` will fail forever with the same error until `target/debug/bin.dSYM` is manually unlinked. After some investigation, I've determined that this situation arises when the target of `bin.dSYM` goes missing. For example, if bin.dSYM is pointing at `deps/bin-86908f0fa7f1440e.dSYM`, and `deps/bin-86908f0fa7f1440e.dSYM` does not exist, then this error will occur. I'm still not clear on why the underlying dSYM bundle sporadically goes missing--perhaps it's the result of pressing Ctrl-C at the wrong moment?--but Cargo should at least be able to handle this situation better. It turns out that Cargo was getting confused by the broken symlink. When it goes to install the new `target/debug/bin.dSYM` link, it will remove the existing `target/debug/bin.dSYM` file, if it exists. Unfortunately, Cargo was checking whether the *target* of that symlink existed (e.g., `deps/bin-86908f0fa7f1440e.dSYM`, which in the buggy case would not exist), rather than the symlink itself, deciding that there was no existing symlink to remove, and crashing with EEXIST when trying to install the new symlink. This commit adjusts the existence check to evaluate whether the symlink itself exists, rather than its target. Note that while the symptoms are the same as #4671, the root cause is unrelated.
2019-08-19 20:45:42 +00:00
assert!(!dsym.exists());
p.cargo("build").enable_mac_dsym().run();
Fix dSYM uplifting when symlink is broken We were sporadically but persistently seeing errors like failed to link or copy `.../target/debugs/deps/bin-264030cd6c8a02be.dSYM` to `.../target/debug/bin.dSYM` Caused by: the source path is not an existing regular file while running `cargo build`. Once the error occurs once, `cargo build` will fail forever with the same error until `target/debug/bin.dSYM` is manually unlinked. After some investigation, I've determined that this situation arises when the target of `bin.dSYM` goes missing. For example, if bin.dSYM is pointing at `deps/bin-86908f0fa7f1440e.dSYM`, and `deps/bin-86908f0fa7f1440e.dSYM` does not exist, then this error will occur. I'm still not clear on why the underlying dSYM bundle sporadically goes missing--perhaps it's the result of pressing Ctrl-C at the wrong moment?--but Cargo should at least be able to handle this situation better. It turns out that Cargo was getting confused by the broken symlink. When it goes to install the new `target/debug/bin.dSYM` link, it will remove the existing `target/debug/bin.dSYM` file, if it exists. Unfortunately, Cargo was checking whether the *target* of that symlink existed (e.g., `deps/bin-86908f0fa7f1440e.dSYM`, which in the buggy case would not exist), rather than the symlink itself, deciding that there was no existing symlink to remove, and crashing with EEXIST when trying to install the new symlink. This commit adjusts the existence check to evaluate whether the symlink itself exists, rather than its target. Note that while the symptoms are the same as #4671, the root cause is unrelated.
2019-08-19 20:45:42 +00:00
assert!(dsym.is_dir());
}
#[cargo_test]
#[cfg(all(target_os = "windows", target_env = "msvc"))]
fn uplift_pdb_of_bin_on_windows() {
let p = project()
.file("src/main.rs", "fn main() { panic!(); }")
.file("src/bin/b.rs", "fn main() { panic!(); }")
.file("src/bin/foo-bar.rs", "fn main() { panic!(); }")
.file("examples/c.rs", "fn main() { panic!(); }")
.file("tests/d.rs", "fn main() { panic!(); }")
.build();
p.cargo("build --bins --examples --tests").run();
2018-08-29 06:11:10 +00:00
assert!(p.target_debug_dir().join("foo.pdb").is_file());
assert!(p.target_debug_dir().join("b.pdb").is_file());
assert!(p.target_debug_dir().join("examples/c.pdb").exists());
assert!(p.target_debug_dir().join("foo-bar.exe").is_file());
assert!(p.target_debug_dir().join("foo_bar.pdb").is_file());
assert!(!p.target_debug_dir().join("c.pdb").exists());
assert!(!p.target_debug_dir().join("d.pdb").exists());
}
#[cargo_test]
#[cfg(target_os = "linux")]
fn uplift_dwp_of_bin_on_linux() {
let p = project()
.file("src/main.rs", "fn main() { panic!(); }")
.file("src/bin/b.rs", "fn main() { panic!(); }")
.file("src/bin/foo-bar.rs", "fn main() { panic!(); }")
.file("examples/c.rs", "fn main() { panic!(); }")
.file("tests/d.rs", "fn main() { panic!(); }")
.build();
p.cargo("build --bins --examples --tests")
.enable_split_debuginfo_packed()
.run();
assert!(p.target_debug_dir().join("foo.dwp").is_file());
assert!(p.target_debug_dir().join("b.dwp").is_file());
assert!(p.target_debug_dir().join("examples/c.dwp").exists());
assert!(p.target_debug_dir().join("foo-bar").is_file());
assert!(p.target_debug_dir().join("foo-bar.dwp").is_file());
assert!(!p.target_debug_dir().join("c.dwp").exists());
assert!(!p.target_debug_dir().join("d.dwp").exists());
}
2019-02-03 04:01:23 +00:00
// Ensure that `cargo build` chooses the correct profile for building
// targets based on filters (assuming `--profile` is not specified).
#[cargo_test]
fn build_filter_infer_profile() {
let p = project()
.file("src/lib.rs", "")
.file("src/main.rs", "fn main() {}")
.file("tests/t1.rs", "")
.file("benches/b1.rs", "")
.file("examples/ex1.rs", "fn main() {}")
.build();
p.cargo("build -v")
.with_stderr_contains(
2019-09-25 01:17:36 +00:00
"[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
--emit=[..]link[..]",
2018-12-08 11:19:47 +00:00
)
.with_stderr_contains(
2019-09-25 01:17:36 +00:00
"[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin \
--emit=[..]link[..]",
2018-12-08 11:19:47 +00:00
)
.run();
p.root().join("target").rm_rf();
p.cargo("build -v --test=t1")
.with_stderr_contains(
2019-09-25 01:17:36 +00:00
"[RUNNING] `rustc --crate-name foo src/lib.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 [..]",
2018-12-08 11:19:47 +00:00
)
.with_stderr_contains(
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
"[RUNNING] `rustc --crate-name t1 tests/t1.rs [..]--emit=[..]link[..]\
2018-12-08 11:19:47 +00:00
-C debuginfo=2 [..]",
)
.with_stderr_contains(
2019-09-25 01:17:36 +00:00
"[RUNNING] `rustc --crate-name foo src/main.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 [..]",
2018-12-08 11:19:47 +00:00
)
.run();
p.root().join("target").rm_rf();
// Bench uses test profile without `--release`.
p.cargo("build -v --bench=b1")
.with_stderr_contains(
2019-09-25 01:17:36 +00:00
"[RUNNING] `rustc --crate-name foo src/lib.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 [..]",
2018-12-08 11:19:47 +00:00
)
.with_stderr_contains(
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
"[RUNNING] `rustc --crate-name b1 benches/b1.rs [..]--emit=[..]link[..]\
2018-12-08 11:19:47 +00:00
-C debuginfo=2 [..]",
)
.with_stderr_does_not_contain("opt-level")
.with_stderr_contains(
2019-09-25 01:17:36 +00:00
"[RUNNING] `rustc --crate-name foo src/main.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 [..]",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn targets_selected_default() {
let p = project().file("src/main.rs", "fn main() {}").build();
p.cargo("build -v")
2019-02-03 04:01:23 +00:00
// Binaries.
2018-12-08 11:19:47 +00:00
.with_stderr_contains(
2019-09-25 01:17:36 +00:00
"[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin \
--emit=[..]link[..]",
2018-12-08 11:19:47 +00:00
)
2019-02-03 04:01:23 +00:00
// Benchmarks.
2018-12-08 11:19:47 +00:00
.with_stderr_does_not_contain(
2019-09-25 01:17:36 +00:00
"[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=[..]link \
2018-12-08 11:19:47 +00:00
-C opt-level=3 --test [..]",
)
2019-02-03 04:01:23 +00:00
// Unit tests.
2018-12-08 11:19:47 +00:00
.with_stderr_does_not_contain(
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
"[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=[..]link[..]\
2018-12-08 11:19:47 +00:00
-C debuginfo=2 --test [..]",
)
.run();
}
#[cargo_test]
fn targets_selected_all() {
let p = project().file("src/main.rs", "fn main() {}").build();
p.cargo("build -v --all-targets")
2019-02-03 04:01:23 +00:00
// Binaries.
2018-12-08 11:19:47 +00:00
.with_stderr_contains(
2019-09-25 01:17:36 +00:00
"[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin \
--emit=[..]link[..]",
2018-12-08 11:19:47 +00:00
)
2019-02-03 04:01:23 +00:00
// Unit tests.
2018-12-08 11:19:47 +00:00
.with_stderr_contains(
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
"[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=[..]link[..]\
-C debuginfo=2 [..]--test [..]",
2018-12-08 11:19:47 +00:00
)
.run();
2018-03-15 15:20:15 +00:00
}
#[cargo_test]
fn all_targets_no_lib() {
let p = project().file("src/main.rs", "fn main() {}").build();
p.cargo("build -v --all-targets")
2019-02-03 04:01:23 +00:00
// Binaries.
2018-12-08 11:19:47 +00:00
.with_stderr_contains(
2019-09-25 01:17:36 +00:00
"[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin \
--emit=[..]link[..]",
2018-12-08 11:19:47 +00:00
)
2019-02-03 04:01:23 +00:00
// Unit tests.
2018-12-08 11:19:47 +00:00
.with_stderr_contains(
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
"[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=[..]link[..]\
-C debuginfo=2 [..]--test [..]",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn no_linkable_target() {
2019-02-03 04:01:23 +00:00
// Issue 3169: this is currently not an error as per discussion in PR #4797.
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.1.0"
authors = []
[dependencies]
the_lib = { path = "the_lib" }
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "fn main() {}")
2018-03-14 15:17:44 +00:00
.file(
"the_lib/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "the_lib"
version = "0.1.0"
[lib]
name = "the_lib"
crate-type = ["staticlib"]
"#,
2018-12-08 11:19:47 +00:00
)
.file("the_lib/src/lib.rs", "pub fn foo() {}")
.build();
p.cargo("build")
.with_stderr_contains(
2019-07-13 23:00:47 +00:00
"[WARNING] The package `the_lib` provides no linkable [..] \
2018-03-14 15:17:44 +00:00
while compiling `foo`. [..] in `the_lib`'s Cargo.toml. [..]",
2018-12-08 11:19:47 +00:00
)
.run();
}
#[cargo_test]
fn avoid_dev_deps() {
Package::new("foo", "1.0.0").publish();
let p = project()
2018-03-14 15:17:44 +00:00
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "bar"
version = "0.1.0"
authors = []
2020-09-27 00:59:58 +00:00
[dev-dependencies]
baz = "1.0.0"
"#,
2018-12-08 11:19:47 +00:00
)
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("build")
.with_status(101)
.with_stderr(
"\
[UPDATING] [..]
[ERROR] no matching package named `baz` found
2021-06-27 19:18:36 +00:00
location searched: registry `crates-io`
required by package `bar v0.1.0 ([..]/foo)`
",
)
.run();
p.cargo("build -Zavoid-dev-deps")
.masquerade_as_nightly_cargo(&["avoid-dev-deps"])
.run();
}
#[cargo_test]
fn default_cargo_config_jobs() {
let p = project()
.file("src/lib.rs", "")
.file(
2024-01-26 19:40:46 +00:00
".cargo/config.toml",
r#"
2020-09-27 00:59:58 +00:00
[build]
jobs = 1
"#,
)
.build();
p.cargo("build -v").run();
}
#[cargo_test]
fn good_cargo_config_jobs() {
let p = project()
.file("src/lib.rs", "")
.file(
2024-01-26 19:40:46 +00:00
".cargo/config.toml",
r#"
2020-09-27 00:59:58 +00:00
[build]
jobs = 4
"#,
)
.build();
p.cargo("build -v").run();
}
#[cargo_test]
fn good_jobs() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.build();
p.cargo("build --jobs 1").run();
p.cargo("build --jobs -1").run();
p.cargo("build --jobs default").run();
}
#[cargo_test]
fn invalid_cargo_config_jobs() {
let p = project()
.file("src/lib.rs", "")
.file(
2024-01-26 19:40:46 +00:00
".cargo/config.toml",
r#"
[build]
jobs = 0
"#,
)
.build();
p.cargo("build -v")
.with_status(101)
.with_stderr_contains("error: jobs may not be 0")
.run();
}
#[cargo_test]
fn invalid_jobs() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.build();
p.cargo("build --jobs 0")
.with_status(101)
2022-07-10 23:31:24 +00:00
.with_stderr_contains("error: jobs may not be 0")
.run();
p.cargo("build --jobs over9000")
.with_status(101)
.with_stderr("error: could not parse `over9000`. Number of parallel jobs should be `default` or a number.")
.run();
}
#[cargo_test]
fn target_filters_workspace() {
let ws = project()
.at("ws")
.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_lib_manifest("a"))
.file("a/src/lib.rs", "")
.file("a/examples/ex1.rs", "fn main() {}")
.file("b/Cargo.toml", &basic_bin_manifest("b"))
2018-11-12 15:13:13 +00:00
.file("b/src/lib.rs", "")
.file("b/src/main.rs", "fn main() {}")
.build();
ws.cargo("build -v --example ex")
.with_status(101)
.with_stderr(
"\
[ERROR] no example target named `ex`
<tab>Did you mean `ex1`?",
)
.run();
ws.cargo("build -v --example 'ex??'")
.with_status(101)
.with_stderr(
"\
[ERROR] no example target matches pattern `ex??`
2019-06-21 18:36:53 +00:00
<tab>Did you mean `ex1`?",
2018-12-08 11:19:47 +00:00
)
.run();
ws.cargo("build -v --lib")
.with_stderr_contains("[RUNNING] `rustc [..]a/src/lib.rs[..]")
2018-11-12 15:13:13 +00:00
.with_stderr_contains("[RUNNING] `rustc [..]b/src/lib.rs[..]")
.run();
ws.cargo("build -v --example ex1")
.with_stderr_contains("[RUNNING] `rustc [..]a/examples/ex1.rs[..]")
.run();
}
#[cargo_test]
fn target_filters_workspace_not_found() {
let ws = project()
.at("ws")
.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"))
.file("a/src/main.rs", "fn main() {}")
.file("b/Cargo.toml", &basic_bin_manifest("b"))
.file("b/src/main.rs", "fn main() {}")
.build();
ws.cargo("build -v --lib")
.with_status(101)
.with_stderr("[ERROR] no library targets found in packages: a, b")
.run();
}
#[cfg(unix)]
#[cargo_test]
fn signal_display() {
// Cause the compiler to crash with a signal.
let foo = project()
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "foo"
version = "0.1.0"
[dependencies]
pm = { path = "pm" }
"#,
)
.file(
"src/lib.rs",
r#"
2020-09-27 00:59:58 +00:00
#[macro_use]
extern crate pm;
2020-09-27 00:59:58 +00:00
#[derive(Foo)]
pub struct S;
"#,
)
.file(
"pm/Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "pm"
version = "0.1.0"
[lib]
proc-macro = true
"#,
)
.file(
"pm/src/lib.rs",
r#"
2020-09-27 00:59:58 +00:00
extern crate proc_macro;
use proc_macro::TokenStream;
2020-09-27 00:59:58 +00:00
#[proc_macro_derive(Foo)]
pub fn derive(_input: TokenStream) -> TokenStream {
std::process::abort()
}
"#,
)
.build();
foo.cargo("build")
2018-12-08 11:19:47 +00:00
.with_stderr(
"\
[COMPILING] pm [..]
[COMPILING] foo [..]
[ERROR] could not compile `foo` [..]
Caused by:
process didn't exit successfully: `rustc [..]` (signal: 6, SIGABRT: process abort signal)
2018-12-08 11:19:47 +00:00
",
)
.with_status(101)
.run();
}
#[cargo_test]
fn tricky_pipelining() {
let foo = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
bar = { path = "bar" }
"#,
)
.file("src/lib.rs", "extern crate bar;")
.file("bar/Cargo.toml", &basic_lib_manifest("bar"))
.file("bar/src/lib.rs", "")
.build();
foo.cargo("build -p bar").run();
foo.cargo("build -p foo").run();
}
#[cargo_test]
fn pipelining_works() {
let foo = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
bar = { path = "bar" }
"#,
)
.file("src/lib.rs", "extern crate bar;")
.file("bar/Cargo.toml", &basic_lib_manifest("bar"))
.file("bar/src/lib.rs", "")
.build();
foo.cargo("build")
.with_stdout("")
2019-05-20 19:36:59 +00:00
.with_stderr(
"\
[COMPILING] [..]
[COMPILING] [..]
[FINISHED] [..]
2019-05-20 19:36:59 +00:00
",
)
.run();
}
#[cargo_test]
fn pipelining_big_graph() {
2019-07-03 14:11:23 +00:00
// Create a crate graph of the form {a,b}{0..29}, where {a,b}(n) depend on {a,b}(n+1)
// Then have `foo`, a binary crate, depend on the whole thing.
let mut project = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
a1 = { path = "a1" }
b1 = { path = "b1" }
"#,
)
.file("src/main.rs", "fn main(){}");
for n in 0..30 {
for x in &["a", "b"] {
project = project
.file(
&format!("{x}{n}/Cargo.toml", x = x, n = n),
&format!(
r#"
[package]
name = "{x}{n}"
version = "0.1.0"
[dependencies]
a{np1} = {{ path = "../a{np1}" }}
b{np1} = {{ path = "../b{np1}" }}
"#,
x = x,
n = n,
np1 = n + 1
),
)
.file(&format!("{x}{n}/src/lib.rs", x = x, n = n), "");
}
}
let foo = project
.file("a30/Cargo.toml", &basic_lib_manifest("a30"))
.file(
"a30/src/lib.rs",
r#"compile_error!("don't actually build me");"#,
)
.file("b30/Cargo.toml", &basic_lib_manifest("b30"))
.file("b30/src/lib.rs", "")
.build();
foo.cargo("build -p foo")
.with_status(101)
.with_stderr_contains("[ERROR] could not compile `a30`[..]")
.run();
}
#[cargo_test]
fn forward_rustc_output() {
let foo = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = '2018'
[dependencies]
bar = { path = "bar" }
"#,
)
.file("src/lib.rs", "bar::foo!();")
.file(
"bar/Cargo.toml",
r#"
[package]
name = "bar"
version = "0.1.0"
[lib]
proc-macro = true
"#,
)
.file(
"bar/src/lib.rs",
r#"
extern crate proc_macro;
use proc_macro::*;
#[proc_macro]
pub fn foo(input: TokenStream) -> TokenStream {
println!("a");
println!("b");
println!("{{}}");
eprintln!("c");
eprintln!("d");
eprintln!("{{a"); // "malformed json"
input
}
"#,
)
.build();
foo.cargo("build")
.with_stdout("a\nb\n{}")
2019-05-20 19:36:59 +00:00
.with_stderr(
"\
[COMPILING] [..]
[COMPILING] [..]
c
d
{a
[FINISHED] [..]
2019-05-20 19:36:59 +00:00
",
)
.run();
}
2019-11-25 02:42:45 +00:00
#[cargo_test]
fn build_lib_only() {
let p = project()
.file("src/main.rs", "fn main() {}")
.file("src/lib.rs", r#" "#)
.build();
p.cargo("build --lib -v")
.with_stderr(
"\
[COMPILING] foo v0.0.1 ([CWD])
[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
--emit=[..]link[..]-C debuginfo=2 [..]\
2019-11-25 02:42:45 +00:00
-C metadata=[..] \
--out-dir [..] \
-L dependency=[CWD]/target/debug/deps`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
)
.run();
}
#[cargo_test]
fn build_with_no_lib() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("build --lib")
.with_status(101)
.with_stderr("[ERROR] no library targets found in package `foo`")
.run();
}
#[cargo_test]
fn build_with_relative_cargo_home_path() {
let p = project()
.file(
"Cargo.toml",
r#"
2020-09-27 00:59:58 +00:00
[package]
2019-11-25 02:42:45 +00:00
2020-09-27 00:59:58 +00:00
name = "foo"
version = "0.0.1"
authors = ["wycats@example.com"]
2019-11-25 02:42:45 +00:00
2020-09-27 00:59:58 +00:00
[dependencies]
2019-11-25 02:42:45 +00:00
2020-09-27 00:59:58 +00:00
"test-dependency" = { path = "src/test_dependency" }
"#,
2019-11-25 02:42:45 +00:00
)
.file("src/main.rs", "fn main() {}")
.file("src/test_dependency/src/lib.rs", r#" "#)
.file(
"src/test_dependency/Cargo.toml",
&basic_manifest("test-dependency", "0.0.1"),
)
.build();
p.cargo("build").env("CARGO_HOME", "./cargo_home/").run();
}
#[cargo_test]
fn user_specific_cfgs_are_filtered_out() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/main.rs", r#"fn main() {}"#)
.file(
"build.rs",
r#"
fn main() {
assert!(std::env::var_os("CARGO_CFG_PROC_MACRO").is_none());
assert!(std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_none());
2020-09-27 00:59:58 +00:00
}
"#,
)
.build();
p.cargo("rustc -- --cfg debug_assertions --cfg proc_macro")
.run();
p.process(&p.bin("foo")).run();
}
#[cargo_test]
fn close_output() {
// What happens when stdout or stderr is closed during a build.
// Server to know when rustc has spawned.
let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
let addr = listener.local_addr().unwrap();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = "2018"
[lib]
proc-macro = true
[[bin]]
name = "foobar"
"#,
)
.file(
"src/lib.rs",
&r#"
use proc_macro::TokenStream;
use std::io::Read;
#[proc_macro]
pub fn repro(_input: TokenStream) -> TokenStream {
println!("hello stdout!");
eprintln!("hello stderr!");
// Tell the test we have started.
let mut socket = std::net::TcpStream::connect("__ADDR__").unwrap();
// Wait for the test to tell us to start printing.
let mut buf = [0];
drop(socket.read_exact(&mut buf));
let use_stderr = std::env::var("__CARGO_REPRO_STDERR").is_ok();
2020-08-04 22:50:17 +00:00
// Emit at least 1MB of data.
// Linux pipes can buffer up to 64KB.
// This test seems to be sensitive to having other threads
// calling fork. My hypothesis is that the stdout/stderr
// file descriptors are duplicated into the child process,
// and during the short window between fork and exec, the
// file descriptor is kept alive long enough for the
// build to finish. It's a half-baked theory, but this
// seems to prevent the spurious errors in CI.
// An alternative solution is to run this test in
// a single-threaded environment.
for i in 0..100000 {
if use_stderr {
2020-08-04 22:50:17 +00:00
eprintln!("0123456789{}", i);
} else {
2020-08-04 22:50:17 +00:00
println!("0123456789{}", i);
}
}
TokenStream::new()
}
"#
.replace("__ADDR__", &addr.to_string()),
)
.file(
"src/bin/foobar.rs",
r#"
foo::repro!();
fn main() {}
"#,
)
.build();
// The `stderr` flag here indicates if this should forcefully close stderr or stdout.
let spawn = |stderr: bool| {
let mut cmd = p.cargo("build").build_command();
cmd.stdout(Stdio::piped()).stderr(Stdio::piped());
if stderr {
cmd.env("__CARGO_REPRO_STDERR", "1");
}
let mut child = cmd.spawn().unwrap();
// Wait for proc macro to start.
let pm_conn = listener.accept().unwrap().0;
// Close stderr or stdout.
if stderr {
drop(child.stderr.take());
} else {
drop(child.stdout.take());
}
// Tell the proc-macro to continue;
drop(pm_conn);
// Read the output from the other channel.
let out: &mut dyn Read = if stderr {
child.stdout.as_mut().unwrap()
} else {
child.stderr.as_mut().unwrap()
};
let mut result = String::new();
out.read_to_string(&mut result).unwrap();
let status = child.wait().unwrap();
assert!(!status.success());
result
};
let stderr = spawn(false);
compare::match_unordered(
"\
[COMPILING] foo [..]
hello stderr!
[ERROR] [..]
[WARNING] build failed, waiting for other jobs to finish...
",
&stderr,
None,
)
.unwrap();
// Try again with stderr.
p.build_dir().rm_rf();
let stdout = spawn(true);
assert_eq!(stdout, "hello stdout!\n");
}
2020-05-22 15:38:40 +00:00
2021-02-24 02:15:44 +00:00
#[cargo_test]
fn close_output_during_drain() {
// Test to close the output during the build phase (drain_the_queue).
// There was a bug where it would hang.
// Server to know when rustc has spawned.
let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
let addr = listener.local_addr().unwrap();
// Create a wrapper so the test can know when compiling has started.
let rustc_wrapper = {
let p = project()
.at("compiler")
.file("Cargo.toml", &basic_manifest("compiler", "1.0.0"))
.file(
"src/main.rs",
&r#"
use std::process::Command;
use std::env;
use std::io::Read;
fn main() {
// Only wait on the first dependency.
if matches!(env::var("CARGO_PKG_NAME").as_deref(), Ok("dep")) {
let mut socket = std::net::TcpStream::connect("__ADDR__").unwrap();
// Wait for the test to tell us to start printing.
let mut buf = [0];
drop(socket.read_exact(&mut buf));
}
let mut cmd = Command::new("rustc");
for arg in env::args_os().skip(1) {
cmd.arg(arg);
}
std::process::exit(cmd.status().unwrap().code().unwrap());
}
"#
.replace("__ADDR__", &addr.to_string()),
)
.build();
p.cargo("build").run();
p.bin("compiler")
};
Package::new("dep", "1.0.0").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
dep = "1.0"
"#,
)
.file("src/lib.rs", "")
.build();
// Spawn cargo, wait for the first rustc to start, and then close stderr.
let mut cmd = process(&cargo_exe())
.arg("check")
.cwd(p.root())
.env("RUSTC", rustc_wrapper)
.build_command();
cmd.stdout(Stdio::piped()).stderr(Stdio::piped());
let mut child = cmd.spawn().expect("cargo should spawn");
// Wait for the rustc wrapper to start.
let rustc_conn = listener.accept().unwrap().0;
// Close stderr to force an error.
drop(child.stderr.take());
// Tell the wrapper to continue.
drop(rustc_conn);
match child.wait() {
Ok(status) => assert!(!status.success()),
Err(e) => panic!("child wait failed: {}", e),
}
}
2020-05-22 15:38:40 +00:00
use cargo_test_support::registry::Dependency;
#[cargo_test]
2020-05-22 18:56:24 +00:00
fn reduced_reproduction_8249() {
// https://github.com/rust-lang/cargo/issues/8249
2020-05-22 18:56:24 +00:00
Package::new("a-src", "0.1.0").links("a").publish();
Package::new("a-src", "0.2.0").links("a").publish();
Package::new("b", "0.1.0")
.add_dep(Dependency::new("a-src", "0.1").optional(true))
2020-05-22 15:38:40 +00:00
.publish();
2020-05-22 18:56:24 +00:00
Package::new("b", "0.2.0")
.add_dep(Dependency::new("a-src", "0.2").optional(true))
2020-05-22 15:38:40 +00:00
.publish();
2020-05-22 18:56:24 +00:00
Package::new("c", "1.0.0")
.add_dep(&Dependency::new("b", "0.1.0"))
2020-05-22 15:38:40 +00:00
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
2020-05-22 18:56:24 +00:00
b = { version = "*", features = ["a-src"] }
a-src = "*"
2020-05-22 15:38:40 +00:00
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("generate-lockfile").run();
2021-03-20 20:43:33 +00:00
cargo_util::paths::append(&p.root().join("Cargo.toml"), b"c = \"*\"").unwrap();
p.cargo("check").run();
2020-05-22 15:38:40 +00:00
p.cargo("check").run();
}
2020-06-24 21:22:20 +00:00
#[cargo_test]
2020-07-01 20:47:38 +00:00
fn target_directory_backup_exclusion() {
2020-06-24 21:22:20 +00:00
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.build();
2020-07-01 20:47:38 +00:00
// Newly created target/ should have CACHEDIR.TAG inside...
2020-06-24 21:22:20 +00:00
p.cargo("build").run();
let cachedir_tag = p.build_dir().join("CACHEDIR.TAG");
2020-06-24 21:22:20 +00:00
assert!(cachedir_tag.is_file());
assert!(fs::read_to_string(&cachedir_tag)
.unwrap()
.starts_with("Signature: 8a477f597d28d172789f06886806bc55"));
2020-07-01 20:47:38 +00:00
// ...but if target/ already exists CACHEDIR.TAG should not be created in it.
2020-06-24 21:22:20 +00:00
fs::remove_file(&cachedir_tag).unwrap();
p.cargo("build").run();
assert!(!&cachedir_tag.is_file());
}
2022-09-23 18:50:03 +00:00
#[cargo_test]
fn simple_terminal_width() {
let p = project()
.file(
"src/lib.rs",
r#"
2022-09-23 18:50:03 +00:00
pub fn foo() {
let _: () = 42;
}
"#,
)
.build();
2022-09-23 18:50:03 +00:00
p.cargo("build -v")
.env("__CARGO_TEST_TTY_WIDTH_DO_NOT_USE_THIS", "20")
.with_status(101)
2022-09-23 18:50:03 +00:00
.with_stderr_contains("[RUNNING] `rustc [..]--diagnostic-width=20[..]")
.run();
p.cargo("doc -v")
.env("__CARGO_TEST_TTY_WIDTH_DO_NOT_USE_THIS", "20")
.with_stderr_contains("[RUNNING] `rustdoc [..]--diagnostic-width=20[..]")
.run();
}
#[cargo_test]
fn build_script_o0_default() {
let p = project()
.file("src/lib.rs", "")
.file("build.rs", "fn main() {}")
.build();
p.cargo("build -v --release")
.with_stderr_does_not_contain("[..]build_script_build[..]opt-level[..]")
.run();
}
#[cargo_test]
fn build_script_o0_default_even_with_release() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[profile.release]
opt-level = 1
"#,
)
.file("src/lib.rs", "")
.file("build.rs", "fn main() {}")
.build();
p.cargo("build -v --release")
.with_stderr_does_not_contain("[..]build_script_build[..]opt-level[..]")
.run();
}
2020-10-12 13:26:40 +00:00
#[cargo_test]
fn primary_package_env_var() {
// Test that CARGO_PRIMARY_PACKAGE is enabled only for "foo" and not for any dependency.
2020-10-12 13:26:40 +00:00
let is_primary_package = r#"
pub fn is_primary_package() -> bool {{
option_env!("CARGO_PRIMARY_PACKAGE").is_some()
}}
"#;
Package::new("qux", "0.1.0")
.file("src/lib.rs", is_primary_package)
2020-10-12 13:26:40 +00:00
.publish();
let baz = git::new("baz", |project| {
project
.file("Cargo.toml", &basic_manifest("baz", "0.1.0"))
.file("src/lib.rs", is_primary_package)
2020-10-12 13:26:40 +00:00
});
let foo = project()
.file(
"Cargo.toml",
&format!(
r#"
[package]
name = "foo"
version = "0.1.0"
2020-10-12 13:26:40 +00:00
[dependencies]
bar = {{ path = "bar" }}
baz = {{ git = '{}' }}
qux = "0.1"
"#,
baz.url()
),
2020-10-12 13:26:40 +00:00
)
.file(
"src/lib.rs",
2020-10-12 13:26:40 +00:00
&format!(
r#"
extern crate bar;
extern crate baz;
extern crate qux;
{}
#[test]
fn verify_primary_package() {{
assert!(!bar::is_primary_package());
assert!(!baz::is_primary_package());
assert!(!qux::is_primary_package());
assert!(is_primary_package());
}}
"#,
is_primary_package
2020-10-12 13:26:40 +00:00
),
)
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", is_primary_package)
2020-10-12 13:26:40 +00:00
.build();
foo.cargo("test").run();
2020-10-12 13:26:40 +00:00
}
#[cargo_test]
fn renamed_uplifted_artifact_remains_unmodified_after_rebuild() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
authors = []
version = "0.0.0"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("build").run();
let bin = p.bin("foo");
let renamed_bin = p.bin("foo-renamed");
fs::rename(&bin, &renamed_bin).unwrap();
p.change_file("src/main.rs", "fn main() { eprintln!(\"hello, world\"); }");
p.cargo("build").run();
let not_the_same = !same_file::is_same_file(bin, renamed_bin).unwrap();
assert!(not_the_same, "renamed uplifted artifact must be unmodified");
}