Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -805,45 +805,51 @@ jobs:

${SCCACHE_PATH} --show-stats | grep -e "Cache hits\s*[1-9]"

rust-test-coverage:
# The test cargo "cargo build -Zprofile"
rust-test-Z-profile:
runs-on: ubuntu-latest
needs: build

env:
RUSTC_WRAPPER: /home/runner/.cargo/bin/sccache
CARGO_INCREMENTAL: "0"
RUSTFLAGS: "-Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
RUSTFLAGS: "-Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort -Zprofile"
RUSTDOCFLAGS: "-Cpanic=abort"
# The last nightly rust that still support "-Zprofile"
#
# See https://github.com/rust-lang/rust/pull/131829
RUST_TEST_TOOLCHAIN: nightly-2024-11-01

steps:
- name: Clone repository
uses: actions/checkout@v4

- name: Install rust
uses: ./.github/actions/rust-toolchain
with:
toolchain: ${{ env.RUST_TEST_TOOLCHAIN }}

- uses: actions/download-artifact@v4
with:
name: integration-tests
path: /home/runner/.cargo/bin/
- name: Chmod for binary
run: chmod +x ${SCCACHE_PATH}

- name: Prepare
run: |
rustup toolchain install nightly
cargo new coverage-test
cd coverage-test
echo "serde = { version = \"1.0\", features = [\"derive\"] }" >> Cargo.toml

- name: "Coverage test #1"
working-directory: ./coverage-test
run: cargo clean && cargo +nightly test
run: cargo +${{ env.RUST_TEST_TOOLCHAIN }} clean && cargo +${{ env.RUST_TEST_TOOLCHAIN }} build

- name: Output
run: ${SCCACHE_PATH} --show-stats
run: |
${SCCACHE_PATH} --show-stats

- name: "Coverage test #2"
working-directory: ./coverage-test
run: cargo clean && cargo +nightly test
run: cargo +${{ env.RUST_TEST_TOOLCHAIN }} clean && cargo +${{ env.RUST_TEST_TOOLCHAIN }} build

- name: Output
run: |
${SCCACHE_PATH} --show-stats

${SCCACHE_PATH} --show-stats | grep -e "Cache hits\s*[1-9]"

zstd-compression-level:
Expand Down
72 changes: 56 additions & 16 deletions src/compiler/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,26 @@ pub struct ParsedArguments {
crate_types: CrateTypes,
/// If dependency info is being emitted, the name of the dep info file.
dep_info: Option<PathBuf>,
/// If profile info is being emitted, the name of the profile file.
/// If profile info is being emitted, the path of the profile.
///
/// This could be filled while `-Cprofile-use` been enabled.
///
/// We need to add the profile into our outputs to enable distributed compilation.
/// We don't need to track `profile-generate` since it's users work to make sure
/// the `profdata` been generated from profraw files.
///
/// For more information, see https://doc.rust-lang.org/rustc/profile-guided-optimization.html
profile: Option<PathBuf>,
/// If `-Z profile` has been enabled, we will use a GCC-compatible, gcov-based
/// coverage implementation.
///
/// This is not supported in latest stable rust anymore, but we still keep it here
/// for the old nightly rustc.
///
/// We need to add the profile into our outputs to enable distributed compilation.
///
/// For more information, see https://doc.rust-lang.org/rustc/instrument-coverage.html
gcno: Option<PathBuf>,
/// rustc says that emits .rlib for --emit=metadata
/// https://github.com/rust-lang/rust/issues/54852
emit: HashSet<String>,
Expand Down Expand Up @@ -996,6 +1014,7 @@ ArgData! {
CodeGen(ArgCodegen),
PassThrough(OsString),
Target(ArgTarget),
Unstable(ArgUnstable),
}

use self::ArgData::*;
Expand Down Expand Up @@ -1037,6 +1056,7 @@ counted_array!(static ARGS: [ArgInfo<ArgData>; _] = [
take_arg!("-L", ArgLinkPath, CanBeSeparated, LinkPath),
flag!("-V", NotCompilationFlag),
take_arg!("-W", OsString, CanBeSeparated, PassThrough),
take_arg!("-Z", ArgUnstable, CanBeSeparated, Unstable),
take_arg!("-l", ArgLinkLibrary, CanBeSeparated, LinkLibrary),
take_arg!("-o", PathBuf, CanBeSeparated, TooHardPath),
]);
Expand All @@ -1059,7 +1079,8 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
let mut static_link_paths: Vec<PathBuf> = vec![];
let mut color_mode = ColorMode::Auto;
let mut has_json = false;
let mut profile = false;
let mut profile = None;
let mut gcno = false;

for arg in ArgsIter::new(arguments.iter().cloned(), &ARGS[..]) {
let arg = try_or_cannot_cache!(arg, "argument parse");
Expand Down Expand Up @@ -1114,7 +1135,7 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
match (opt.as_ref(), value) {
("extra-filename", Some(value)) => extra_filename = Some(value.to_owned()),
("extra-filename", None) => cannot_cache!("extra-filename"),
("profile-generate", Some(_)) => profile = true,
("profile-use", Some(v)) => profile = Some(v.to_string()),
// Incremental compilation makes a mess of sccache's entire world
// view. It produces additional compiler outputs that we don't cache,
// and just letting rustc do its work in incremental mode is likely
Expand All @@ -1127,6 +1148,12 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
(_, _) => (),
}
}
Some(Unstable(ArgUnstable { opt, value })) => match value.as_deref() {
Some("y") | Some("yes") | Some("on") | None if opt == "profile" => {
gcno = true;
}
_ => (),
},
Some(Color(value)) => {
// We'll just assume the last specified value wins.
color_mode = match value.as_ref() {
Expand Down Expand Up @@ -1215,15 +1242,17 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
None
};

// Figure out the profile filename, if producing profile files with `-C profile-generate`.
let profile = if profile && emit.contains("link") {
let mut profile = crate_name.clone();
// Ignore profile is `link` is not in emit which means we are running `cargo check`.
let profile = if emit.contains("link") { profile } else { None };

// Figure out the gcno filename, if producing gcno files with `-Zprofile`.
let gcno = if gcno && emit.contains("link") {
let mut gcno = crate_name.clone();
if let Some(extra_filename) = extra_filename {
profile.push_str(&extra_filename[..]);
gcno.push_str(&extra_filename[..]);
}
// LLVM will append ".profraw" to the filename.
profile.push_str(".profraw");
Some(profile)
gcno.push_str(".gcno");
Some(gcno)
} else {
None
};
Expand Down Expand Up @@ -1264,6 +1293,7 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
crate_name,
dep_info: dep_info.map(|s| s.into()),
profile: profile.map(|s| s.into()),
gcno: gcno.map(|s| s.into()),
emit,
color_mode,
has_json,
Expand Down Expand Up @@ -1308,6 +1338,7 @@ where
emit,
has_json,
profile,
gcno,
..
},
} = *self;
Expand Down Expand Up @@ -1541,6 +1572,16 @@ where
},
);
}
if let Some(gcno) = gcno {
let p = output_dir.join(&gcno);
outputs.insert(
gcno.to_string_lossy().into_owned(),
ArtifactDescriptor {
path: p,
optional: true,
},
);
}
let mut arguments = arguments;
// Request color output unless json was requested. The client will strip colors if needed.
if !has_json {
Expand Down Expand Up @@ -3340,6 +3381,7 @@ proc_macro false
color_mode: ColorMode::Auto,
has_json: false,
profile: None,
gcno: None,
},
});
let creator = new_creator();
Expand Down Expand Up @@ -3687,11 +3729,10 @@ proc_macro false
"--emit=dep-info,link",
"--out-dir",
"/out",
"-C",
"profile-generate=."
"-Zprofile"
);

assert_eq!(h.profile, Some("foo.profraw".into()));
assert_eq!(h.gcno, Some("foo.gcno".into()));

let h = parses!(
"--crate-name",
Expand All @@ -3704,10 +3745,9 @@ proc_macro false
"extra-filename=-a1b6419f8321841f",
"--out-dir",
"/out",
"-C",
"profile-generate=."
"-Zprofile"
);

assert_eq!(h.profile, Some("foo-a1b6419f8321841f.profraw".into()));
assert_eq!(h.gcno, Some("foo-a1b6419f8321841f.gcno".into()));
}
}
Loading