cargo/tests/testsuite/lto.rs

749 lines
21 KiB
Rust
Raw Normal View History

2020-06-10 22:31:36 +00:00
use cargo::core::compiler::Lto;
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
use cargo_test_support::registry::Package;
2020-08-27 23:41:43 +00:00
use cargo_test_support::{basic_manifest, project, Project};
2020-06-10 22:31:36 +00:00
use std::process::Output;
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
#[cargo_test]
fn with_deps() {
Package::new("bar", "0.0.1").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "test"
version = "0.0.0"
[dependencies]
bar = "*"
[profile.release]
lto = true
"#,
)
.file("src/main.rs", "extern crate bar; fn main() {}")
.build();
p.cargo("build -v --release")
.with_stderr_contains("[..]`rustc[..]--crate-name bar[..]-C linker-plugin-lto[..]`")
.with_stderr_contains("[..]`rustc[..]--crate-name test[..]-C lto[..]`")
.run();
}
#[cargo_test]
fn shared_deps() {
Package::new("bar", "0.0.1").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "test"
version = "0.0.0"
[dependencies]
bar = "*"
[build-dependencies]
bar = "*"
[profile.release]
lto = true
"#,
)
.file("build.rs", "extern crate bar; fn main() {}")
.file("src/main.rs", "extern crate bar; fn main() {}")
.build();
p.cargo("build -v --release")
.with_stderr_contains("[..]`rustc[..]--crate-name test[..]-C lto[..]`")
.run();
}
#[cargo_test]
fn build_dep_not_ltod() {
Package::new("bar", "0.0.1").publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "test"
version = "0.0.0"
[build-dependencies]
bar = "*"
[profile.release]
lto = true
"#,
)
.file("build.rs", "extern crate bar; fn main() {}")
.file("src/main.rs", "fn main() {}")
.build();
p.cargo("build -v --release")
.with_stderr_contains("[..]`rustc[..]--crate-name bar[..]-C embed-bitcode=no[..]`")
.with_stderr_contains("[..]`rustc[..]--crate-name test[..]-C lto[..]`")
.run();
}
#[cargo_test]
fn complicated() {
Package::new("dep-shared", "0.0.1")
.file("src/lib.rs", "pub fn foo() {}")
.publish();
Package::new("dep-normal2", "0.0.1")
.file("src/lib.rs", "pub fn foo() {}")
.publish();
Package::new("dep-normal", "0.0.1")
.dep("dep-shared", "*")
.dep("dep-normal2", "*")
.file(
"src/lib.rs",
"
pub fn foo() {
dep_shared::foo();
dep_normal2::foo();
}
",
)
.publish();
Package::new("dep-build2", "0.0.1")
.file("src/lib.rs", "pub fn foo() {}")
.publish();
Package::new("dep-build", "0.0.1")
.dep("dep-shared", "*")
.dep("dep-build2", "*")
.file(
"src/lib.rs",
"
pub fn foo() {
dep_shared::foo();
dep_build2::foo();
}
",
)
.publish();
Package::new("dep-proc-macro2", "0.0.1")
.file("src/lib.rs", "pub fn foo() {}")
.publish();
Package::new("dep-proc-macro", "0.0.1")
.proc_macro(true)
.dep("dep-shared", "*")
.dep("dep-proc-macro2", "*")
.file(
"src/lib.rs",
"
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn foo(_: TokenStream, a: TokenStream) -> TokenStream {
dep_shared::foo();
dep_proc_macro2::foo();
a
}
",
)
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "test"
version = "0.0.0"
[lib]
crate-type = ['cdylib', 'staticlib']
[dependencies]
dep-normal = "*"
dep-proc-macro = "*"
[build-dependencies]
dep-build = "*"
[profile.release]
lto = true
Build host dependencies with opt-level 0 by default This commit updates Cargo's build of host dependencies to build them with optimization level 0 by default instead of matching the profile of the final binary. Since Cargo's inception build dependencies have, by default, been built in a profile that largely matches the profile of the final target artifact. Build dependencies, however, rarely actually need to be optimized and are often executing very small tasks, which means that optimizing them often wastes a lot of build time. A great example of this is procedural macros where `syn` and friends are pretty heavyweight to optimize, and the amount of Rust code they're parsing is typically quite small, so the time spent optimizing rarely comes as a benefit. The goal of this PR is to improve build times on average in the community by not spending time optimizing build dependencies (build scripts, procedural macros, and their transitive dependencies). The PR will not be a universal win for everyone, however. There's some situations where your build time may actually increase: * In some cases build scripts and procedural macros can take quite a long time to run! * Cargo may not build dependencies more than once if they're shared with the main build. This only applies to builds without `--target` where the same crate is used in the final binary as in a build script. In these cases, however, the `build-override` profile has existed for some time know and allows giving a knob to tweak this behavior. For example to get back the previous build behavior of Cargo you would specify, in `Cargo.toml`: [profile.release.build-override] opt-level = 3 or you can configure this via the environment: export CARGO_PROFILE_RELEASE_BUILD_OVERRIDE_OPT_LEVEL=3 There are two notable features we would like to add in the future which would make the impact of a change like this smaller, but they're not implemented at this time (nor do we have concrete plans to implement them). First we would like crates to have a way of specifying they should be optimized by default, despite default profile options. Often crates, like lalrpop historically, have abysmal performance in debug mode and almost always (even in debug builds) want to be built in release mode. The second feature is that ideally crate authors would be able to tell Cargo to minimize the number of crates built, unifying profiles where possible to avoid double-compiling crates. At this time though the Cargo team feels that the benefit of changing the defaults is well worth this change. Neither today nor directly after this change will be a perfect world, but it's hoped that this change makes things less bad!
2020-07-17 19:39:41 +00:00
# force build deps to share an opt-level with the rest of the
# graph so they only get built once.
[profile.release.build-override]
opt-level = 3
"#,
)
.file("build.rs", "fn main() { dep_build::foo() }")
.file(
"src/main.rs",
"#[dep_proc_macro::foo] fn main() { dep_normal::foo() }",
)
.file(
"src/lib.rs",
"#[dep_proc_macro::foo] pub fn foo() { dep_normal::foo() }",
)
.build();
p.cargo("build -v --release")
// normal deps and their transitive dependencies do not need object
// code, so they should have linker-plugin-lto specified
.with_stderr_contains(
"[..]`rustc[..]--crate-name dep_normal2 [..]-C linker-plugin-lto[..]`",
)
.with_stderr_contains("[..]`rustc[..]--crate-name dep_normal [..]-C linker-plugin-lto[..]`")
// build dependencies and their transitive deps don't need any bitcode,
// so embedding should be turned off
.with_stderr_contains("[..]`rustc[..]--crate-name dep_build2 [..]-C embed-bitcode=no[..]`")
.with_stderr_contains("[..]`rustc[..]--crate-name dep_build [..]-C embed-bitcode=no[..]`")
.with_stderr_contains(
"[..]`rustc[..]--crate-name build_script_build [..]-C embed-bitcode=no[..]`",
)
// proc macro deps are the same as build deps here
.with_stderr_contains(
"[..]`rustc[..]--crate-name dep_proc_macro2 [..]-C embed-bitcode=no[..]`",
)
.with_stderr_contains(
"[..]`rustc[..]--crate-name dep_proc_macro [..]-C embed-bitcode=no[..]`",
)
.with_stderr_contains("[..]`rustc[..]--crate-name test [..]--crate-type bin[..]-C lto[..]`")
.with_stderr_contains(
"[..]`rustc[..]--crate-name test [..]--crate-type cdylib[..]-C lto[..]`",
)
.with_stderr_contains("[..]`rustc[..]--crate-name dep_shared [..]`")
.with_stderr_does_not_contain("[..]--crate-name dep_shared[..]-C lto[..]")
.with_stderr_does_not_contain("[..]--crate-name dep_shared[..]-C linker-plugin-lto[..]")
.with_stderr_does_not_contain("[..]--crate-name dep_shared[..]-C embed-bitcode[..]")
.run();
}
#[cargo_test]
fn off_in_manifest_works() {
Package::new("bar", "0.0.1")
.file("src/lib.rs", "pub fn foo() {}")
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "test"
version = "0.0.0"
[dependencies]
bar = "*"
[profile.release]
lto = "off"
"#,
)
2020-06-10 22:31:36 +00:00
.file("src/lib.rs", "pub fn foo() {}")
.file(
"src/main.rs",
"fn main() {
test::foo();
bar::foo();
}",
)
.build();
2020-06-10 22:31:36 +00:00
p.cargo("build -v --release")
.with_stderr(
"\
[UPDATING] [..]
[DOWNLOADING] [..]
[DOWNLOADED] [..]
[COMPILING] bar v0.0.1
[RUNNING] `rustc --crate-name bar [..]--crate-type lib [..]-C embed-bitcode=no[..]
2020-06-10 22:31:36 +00:00
[COMPILING] test [..]
[RUNNING] `rustc --crate-name test [..]--crate-type lib [..]-C embed-bitcode=no[..]
2020-06-10 22:31:36 +00:00
[RUNNING] `rustc --crate-name test src/main.rs [..]--crate-type bin [..]-C lto=off[..]
[FINISHED] [..]
",
)
.run();
}
#[cargo_test]
fn between_builds() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "test"
version = "0.0.0"
[profile.release]
lto = true
"#,
)
.file("src/lib.rs", "pub fn foo() {}")
.file("src/main.rs", "fn main() { test::foo() }")
.build();
2020-06-10 22:31:36 +00:00
p.cargo("build -v --release --lib")
.with_stderr(
"\
[COMPILING] test [..]
[RUNNING] `rustc [..]--crate-type lib[..]-C linker-plugin-lto[..]
2020-06-10 22:31:36 +00:00
[FINISHED] [..]
",
)
.run();
p.cargo("build -v --release")
.with_stderr_contains(
"\
[COMPILING] test [..]
[RUNNING] `rustc [..]--crate-type bin[..]-C lto[..]
[FINISHED] [..]
",
)
.run();
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
}
#[cargo_test]
fn test_all() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.0"
[profile.release]
lto = true
"#,
)
.file("src/main.rs", "fn main() {}")
.file("tests/a.rs", "")
.file("tests/b.rs", "")
.build();
p.cargo("test --release -v")
.with_stderr_contains("[RUNNING] `rustc[..]--crate-name foo[..]-C lto[..]")
.run();
}
#[cargo_test]
fn test_all_and_bench() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.0"
[profile.release]
lto = true
[profile.bench]
lto = true
"#,
)
.file("src/main.rs", "fn main() {}")
.file("tests/a.rs", "")
.file("tests/b.rs", "")
.build();
p.cargo("test --release -v")
.with_stderr_contains("[RUNNING] `rustc[..]--crate-name a[..]-C lto[..]")
.with_stderr_contains("[RUNNING] `rustc[..]--crate-name b[..]-C lto[..]")
.with_stderr_contains("[RUNNING] `rustc[..]--crate-name foo[..]-C lto[..]")
.run();
}
2020-06-10 22:31:36 +00:00
fn project_with_dep(crate_types: &str) -> Project {
Package::new("registry", "0.0.1")
2020-06-10 22:31:36 +00:00
.file("src/lib.rs", r#"pub fn foo() { println!("registry"); }"#)
.publish();
Package::new("registry-shared", "0.0.1")
2020-06-10 22:31:36 +00:00
.file("src/lib.rs", r#"pub fn foo() { println!("shared"); }"#)
.publish();
2020-06-10 22:31:36 +00:00
project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.0"
[workspace]
[dependencies]
bar = { path = 'bar' }
registry-shared = "*"
[profile.release]
lto = true
"#,
)
.file(
"src/main.rs",
"
fn main() {
bar::foo();
registry_shared::foo();
}
",
)
.file(
"bar/Cargo.toml",
2020-06-10 22:31:36 +00:00
&format!(
r#"
2020-09-27 00:59:58 +00:00
[package]
name = "bar"
version = "0.0.0"
2020-09-27 00:59:58 +00:00
[dependencies]
registry = "*"
registry-shared = "*"
2020-09-27 00:59:58 +00:00
[lib]
crate-type = [{}]
"#,
2020-06-10 22:31:36 +00:00
crate_types
),
)
.file(
"bar/src/lib.rs",
2020-06-10 22:31:36 +00:00
r#"
pub fn foo() {
2020-06-10 22:31:36 +00:00
println!("bar");
registry::foo();
registry_shared::foo();
}
2020-06-10 22:31:36 +00:00
"#,
)
.file("tests/a.rs", "")
.file("bar/tests/b.rs", "")
2020-06-10 22:31:36 +00:00
.build()
}
fn verify_lto(output: &Output, krate: &str, krate_info: &str, expected_lto: Lto) {
let stderr = std::str::from_utf8(&output.stderr).unwrap();
let mut matches = stderr.lines().filter(|line| {
line.contains("Running")
&& line.contains(&format!("--crate-name {} ", krate))
&& line.contains(krate_info)
});
let line = matches.next().unwrap_or_else(|| {
panic!(
"expected to find crate `{}` info: `{}`, not found in output:\n{}",
krate, krate_info, stderr
);
});
if let Some(line2) = matches.next() {
panic!(
"found multiple lines matching crate `{}` info: `{}`:\nline1:{}\nline2:{}\noutput:\n{}",
krate, krate_info, line, line2, stderr
);
}
let actual_lto = if let Some(index) = line.find("-C lto=") {
let s = &line[index..];
let end = s.find(' ').unwrap();
let mode = &line[index..index + end];
if mode == "off" {
Lto::Off
} else {
Lto::Run(Some(mode.into()))
}
} else if line.contains("-C lto") {
Lto::Run(None)
} else if line.contains("-C linker-plugin-lto") {
2020-06-10 22:31:36 +00:00
Lto::OnlyBitcode
} else if line.contains("-C embed-bitcode=no") {
2020-06-10 22:31:36 +00:00
Lto::OnlyObject
} else {
Lto::ObjectAndBitcode
};
assert_eq!(
actual_lto, expected_lto,
"did not find expected LTO in line: {}",
line
);
}
#[cargo_test]
fn cdylib_and_rlib() {
let p = project_with_dep("'cdylib', 'rlib'");
let output = p.cargo("build --release -v").exec_with_output().unwrap();
verify_lto(
&output,
"registry",
"--crate-type lib",
Lto::ObjectAndBitcode,
);
verify_lto(
&output,
"registry_shared",
"--crate-type lib",
Lto::ObjectAndBitcode,
);
verify_lto(
&output,
"bar",
"--crate-type cdylib --crate-type rlib",
Lto::ObjectAndBitcode,
);
verify_lto(&output, "foo", "--crate-type bin", Lto::Run(None));
p.cargo("test --release -v")
.with_stderr_unordered(
"\
[FRESH] registry v0.0.1
[FRESH] registry-shared v0.0.1
[FRESH] bar v0.0.0 [..]
[COMPILING] foo [..]
[RUNNING] `rustc --crate-name foo [..]-C embed-bitcode=no --test[..]
[RUNNING] `rustc --crate-name a [..]-C embed-bitcode=no --test[..]
2020-06-10 22:31:36 +00:00
[FINISHED] [..]
[RUNNING] [..]
[RUNNING] [..]
",
)
.run();
p.cargo("build --release -v --manifest-path bar/Cargo.toml")
2020-06-10 22:31:36 +00:00
.with_stderr_unordered(
"\
[FRESH] registry-shared v0.0.1
[FRESH] registry v0.0.1
[FRESH] bar v0.0.0 [..]
[FINISHED] [..]
",
)
.run();
p.cargo("test --release -v --manifest-path bar/Cargo.toml")
2020-06-10 22:31:36 +00:00
.with_stderr_unordered(
"\
2020-08-27 23:41:43 +00:00
[COMPILING] registry v0.0.1
[COMPILING] registry-shared v0.0.1
[RUNNING] `rustc --crate-name registry [..]-C embed-bitcode=no[..]
[RUNNING] `rustc --crate-name registry_shared [..]-C embed-bitcode=no[..]
2020-06-10 22:31:36 +00:00
[COMPILING] bar [..]
2020-08-27 23:41:43 +00:00
[RUNNING] `rustc --crate-name bar [..]--crate-type cdylib --crate-type rlib [..]-C embed-bitcode=no[..]
[RUNNING] `rustc --crate-name bar [..]-C embed-bitcode=no --test[..]
[RUNNING] `rustc --crate-name b [..]-C embed-bitcode=no --test[..]
2020-06-10 22:31:36 +00:00
[FINISHED] [..]
2020-08-27 23:41:43 +00:00
[RUNNING] [..]target/release/deps/bar-[..]
[RUNNING] [..]target/release/deps/b-[..]
2020-06-10 22:31:36 +00:00
[DOCTEST] bar
2020-08-27 23:41:43 +00:00
[RUNNING] `rustdoc --crate-type cdylib --crate-type rlib --test [..]-C embed-bitcode=no[..]
2020-06-10 22:31:36 +00:00
",
)
.run();
}
#[cargo_test]
fn dylib() {
let p = project_with_dep("'dylib'");
let output = p.cargo("build --release -v").exec_with_output().unwrap();
verify_lto(&output, "registry", "--crate-type lib", Lto::OnlyObject);
verify_lto(
&output,
"registry_shared",
"--crate-type lib",
Lto::ObjectAndBitcode,
);
verify_lto(&output, "bar", "--crate-type dylib", Lto::OnlyObject);
verify_lto(&output, "foo", "--crate-type bin", Lto::Run(None));
p.cargo("test --release -v")
.with_stderr_unordered(
"\
[FRESH] registry v0.0.1
[FRESH] registry-shared v0.0.1
[FRESH] bar v0.0.0 [..]
[COMPILING] foo [..]
[RUNNING] `rustc --crate-name foo [..]-C embed-bitcode=no --test[..]
[RUNNING] `rustc --crate-name a [..]-C embed-bitcode=no --test[..]
2020-06-10 22:31:36 +00:00
[FINISHED] [..]
[RUNNING] [..]
[RUNNING] [..]
",
)
.run();
p.cargo("build --release -v --manifest-path bar/Cargo.toml")
.with_stderr_unordered(
"\
[COMPILING] registry-shared v0.0.1
[FRESH] registry v0.0.1
[RUNNING] `rustc --crate-name registry_shared [..]-C embed-bitcode=no[..]
2020-06-10 22:31:36 +00:00
[COMPILING] bar [..]
[RUNNING] `rustc --crate-name bar [..]--crate-type dylib [..]-C embed-bitcode=no[..]
2020-06-10 22:31:36 +00:00
[FINISHED] [..]
",
)
.run();
p.cargo("test --release -v --manifest-path bar/Cargo.toml")
.with_stderr_unordered(
"\
[FRESH] registry-shared v0.0.1
[FRESH] registry v0.0.1
[COMPILING] bar [..]
[RUNNING] `rustc --crate-name bar [..]-C embed-bitcode=no --test[..]
[RUNNING] `rustc --crate-name b [..]-C embed-bitcode=no --test[..]
2020-06-10 22:31:36 +00:00
[FINISHED] [..]
[RUNNING] [..]
[RUNNING] [..]
",
)
.run();
}
#[cargo_test]
fn test_profile() {
Package::new("bar", "0.0.1")
.file("src/lib.rs", "pub fn foo() -> i32 { 123 } ")
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = "2018"
[profile.test]
lto = 'thin'
[dependencies]
bar = "*"
"#,
)
.file(
"src/lib.rs",
r#"
#[test]
fn t1() {
assert_eq!(123, bar::foo());
}
"#,
)
.build();
p.cargo("test -v")
2020-07-29 05:25:45 +00:00
// unordered because the two `foo` builds start in parallel
.with_stderr_unordered("\
2020-06-10 22:31:36 +00:00
[UPDATING] [..]
[DOWNLOADING] [..]
[DOWNLOADED] [..]
[COMPILING] bar v0.0.1
[RUNNING] `rustc --crate-name bar [..]crate-type lib[..]
[COMPILING] foo [..]
2020-08-27 23:41:43 +00:00
[RUNNING] `rustc --crate-name foo [..]--crate-type lib --emit=dep-info,metadata,link -C linker-plugin-lto[..]
2020-06-10 22:31:36 +00:00
[RUNNING] `rustc --crate-name foo [..]--emit=dep-info,link -C lto=thin [..]--test[..]
[FINISHED] [..]
[RUNNING] [..]
[DOCTEST] foo
[RUNNING] `rustdoc [..]
")
.run();
}
#[cargo_test]
fn dev_profile() {
// Mixing dev=LTO with test=not-LTO
Package::new("bar", "0.0.1")
.file("src/lib.rs", "pub fn foo() -> i32 { 123 } ")
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = "2018"
[profile.dev]
lto = 'thin'
[dependencies]
bar = "*"
"#,
)
.file(
"src/lib.rs",
r#"
#[test]
fn t1() {
assert_eq!(123, bar::foo());
}
"#,
)
.build();
p.cargo("test -v")
2020-07-29 05:25:45 +00:00
// unordered because the two `foo` builds start in parallel
.with_stderr_unordered("\
2020-06-10 22:31:36 +00:00
[UPDATING] [..]
[DOWNLOADING] [..]
[DOWNLOADED] [..]
[COMPILING] bar v0.0.1
[RUNNING] `rustc --crate-name bar [..]crate-type lib[..]
[COMPILING] foo [..]
2020-08-27 23:41:43 +00:00
[RUNNING] `rustc --crate-name foo [..]--crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no [..]
[RUNNING] `rustc --crate-name foo [..]--emit=dep-info,link -C embed-bitcode=no [..]--test[..]
2020-06-10 22:31:36 +00:00
[FINISHED] [..]
[RUNNING] [..]
[DOCTEST] foo
[RUNNING] `rustdoc [..]
")
.run();
}
2020-08-27 23:41:43 +00:00
#[cargo_test]
fn doctest() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = "2018"
[profile.release]
lto = true
[dependencies]
bar = { path = "bar" }
"#,
)
.file(
"src/lib.rs",
r#"
/// Foo!
///
/// ```
/// foo::foo();
/// ```
pub fn foo() { bar::bar(); }
"#,
)
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file(
"bar/src/lib.rs",
r#"
pub fn bar() { println!("hi!"); }
"#,
)
.build();
p.cargo("test --doc --release -v")
.with_stderr_contains("[..]`rustc --crate-name bar[..]-C embed-bitcode=no[..]")
.with_stderr_contains("[..]`rustc --crate-name foo[..]-C embed-bitcode=no[..]")
// embed-bitcode should be harmless here
.with_stderr_contains("[..]`rustdoc [..]-C embed-bitcode=no[..]")
.run();
// Try with bench profile.
p.cargo("test --doc --release -v")
.env("CARGO_PROFILE_BENCH_LTO", "true")
.with_stderr_contains("[..]`rustc --crate-name bar[..]-C linker-plugin-lto[..]")
.with_stderr_contains("[..]`rustc --crate-name foo[..]-C linker-plugin-lto[..]")
.with_stderr_contains("[..]`rustdoc [..]-C lto[..]")
.run();
}