Skip to content

Commit 989e7e3

Browse files
authored
fix: bring "cargo build -Zprofile" support back (#2306)
1 parent 6ce3950 commit 989e7e3

File tree

2 files changed

+76
-30
lines changed

2 files changed

+76
-30
lines changed

.github/workflows/integration-tests.yml

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -805,45 +805,51 @@ jobs:
805805
806806
${SCCACHE_PATH} --show-stats | grep -e "Cache hits\s*[1-9]"
807807
808-
rust-test-coverage:
808+
# The test cargo "cargo build -Zprofile"
809+
rust-test-Z-profile:
809810
runs-on: ubuntu-latest
810811
needs: build
811812

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

818823
steps:
824+
- name: Clone repository
825+
uses: actions/checkout@v4
826+
827+
- name: Install rust
828+
uses: ./.github/actions/rust-toolchain
829+
with:
830+
toolchain: ${{ env.RUST_TEST_TOOLCHAIN }}
831+
819832
- uses: actions/download-artifact@v4
820833
with:
821834
name: integration-tests
822835
path: /home/runner/.cargo/bin/
823836
- name: Chmod for binary
824837
run: chmod +x ${SCCACHE_PATH}
825838

826-
- name: Prepare
827-
run: |
828-
rustup toolchain install nightly
829-
cargo new coverage-test
830-
cd coverage-test
831-
echo "serde = { version = \"1.0\", features = [\"derive\"] }" >> Cargo.toml
832-
833839
- name: "Coverage test #1"
834-
working-directory: ./coverage-test
835-
run: cargo clean && cargo +nightly test
840+
run: cargo +${{ env.RUST_TEST_TOOLCHAIN }} clean && cargo +${{ env.RUST_TEST_TOOLCHAIN }} build
836841

837842
- name: Output
838-
run: ${SCCACHE_PATH} --show-stats
843+
run: |
844+
${SCCACHE_PATH} --show-stats
839845
840846
- name: "Coverage test #2"
841-
working-directory: ./coverage-test
842-
run: cargo clean && cargo +nightly test
847+
run: cargo +${{ env.RUST_TEST_TOOLCHAIN }} clean && cargo +${{ env.RUST_TEST_TOOLCHAIN }} build
843848

844849
- name: Output
845850
run: |
846851
${SCCACHE_PATH} --show-stats
852+
847853
${SCCACHE_PATH} --show-stats | grep -e "Cache hits\s*[1-9]"
848854
849855
zstd-compression-level:

src/compiler/rust.rs

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,26 @@ pub struct ParsedArguments {
161161
crate_types: CrateTypes,
162162
/// If dependency info is being emitted, the name of the dep info file.
163163
dep_info: Option<PathBuf>,
164-
/// If profile info is being emitted, the name of the profile file.
164+
/// If profile info is being emitted, the path of the profile.
165+
///
166+
/// This could be filled while `-Cprofile-use` been enabled.
167+
///
168+
/// We need to add the profile into our outputs to enable distributed compilation.
169+
/// We don't need to track `profile-generate` since it's users work to make sure
170+
/// the `profdata` been generated from profraw files.
171+
///
172+
/// For more information, see https://doc.rust-lang.org/rustc/profile-guided-optimization.html
165173
profile: Option<PathBuf>,
174+
/// If `-Z profile` has been enabled, we will use a GCC-compatible, gcov-based
175+
/// coverage implementation.
176+
///
177+
/// This is not supported in latest stable rust anymore, but we still keep it here
178+
/// for the old nightly rustc.
179+
///
180+
/// We need to add the profile into our outputs to enable distributed compilation.
181+
///
182+
/// For more information, see https://doc.rust-lang.org/rustc/instrument-coverage.html
183+
gcno: Option<PathBuf>,
166184
/// rustc says that emits .rlib for --emit=metadata
167185
/// https://github.com/rust-lang/rust/issues/54852
168186
emit: HashSet<String>,
@@ -996,6 +1014,7 @@ ArgData! {
9961014
CodeGen(ArgCodegen),
9971015
PassThrough(OsString),
9981016
Target(ArgTarget),
1017+
Unstable(ArgUnstable),
9991018
}
10001019

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

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

1218-
// Figure out the profile filename, if producing profile files with `-C profile-generate`.
1219-
let profile = if profile && emit.contains("link") {
1220-
let mut profile = crate_name.clone();
1245+
// Ignore profile is `link` is not in emit which means we are running `cargo check`.
1246+
let profile = if emit.contains("link") { profile } else { None };
1247+
1248+
// Figure out the gcno filename, if producing gcno files with `-Zprofile`.
1249+
let gcno = if gcno && emit.contains("link") {
1250+
let mut gcno = crate_name.clone();
12211251
if let Some(extra_filename) = extra_filename {
1222-
profile.push_str(&extra_filename[..]);
1252+
gcno.push_str(&extra_filename[..]);
12231253
}
1224-
// LLVM will append ".profraw" to the filename.
1225-
profile.push_str(".profraw");
1226-
Some(profile)
1254+
gcno.push_str(".gcno");
1255+
Some(gcno)
12271256
} else {
12281257
None
12291258
};
@@ -1264,6 +1293,7 @@ fn parse_arguments(arguments: &[OsString], cwd: &Path) -> CompilerArguments<Pars
12641293
crate_name,
12651294
dep_info: dep_info.map(|s| s.into()),
12661295
profile: profile.map(|s| s.into()),
1296+
gcno: gcno.map(|s| s.into()),
12671297
emit,
12681298
color_mode,
12691299
has_json,
@@ -1308,6 +1338,7 @@ where
13081338
emit,
13091339
has_json,
13101340
profile,
1341+
gcno,
13111342
..
13121343
},
13131344
} = *self;
@@ -1541,6 +1572,16 @@ where
15411572
},
15421573
);
15431574
}
1575+
if let Some(gcno) = gcno {
1576+
let p = output_dir.join(&gcno);
1577+
outputs.insert(
1578+
gcno.to_string_lossy().into_owned(),
1579+
ArtifactDescriptor {
1580+
path: p,
1581+
optional: true,
1582+
},
1583+
);
1584+
}
15441585
let mut arguments = arguments;
15451586
// Request color output unless json was requested. The client will strip colors if needed.
15461587
if !has_json {
@@ -3340,6 +3381,7 @@ proc_macro false
33403381
color_mode: ColorMode::Auto,
33413382
has_json: false,
33423383
profile: None,
3384+
gcno: None,
33433385
},
33443386
});
33453387
let creator = new_creator();
@@ -3687,11 +3729,10 @@ proc_macro false
36873729
"--emit=dep-info,link",
36883730
"--out-dir",
36893731
"/out",
3690-
"-C",
3691-
"profile-generate=."
3732+
"-Zprofile"
36923733
);
36933734

3694-
assert_eq!(h.profile, Some("foo.profraw".into()));
3735+
assert_eq!(h.gcno, Some("foo.gcno".into()));
36953736

36963737
let h = parses!(
36973738
"--crate-name",
@@ -3704,10 +3745,9 @@ proc_macro false
37043745
"extra-filename=-a1b6419f8321841f",
37053746
"--out-dir",
37063747
"/out",
3707-
"-C",
3708-
"profile-generate=."
3748+
"-Zprofile"
37093749
);
37103750

3711-
assert_eq!(h.profile, Some("foo-a1b6419f8321841f.profraw".into()));
3751+
assert_eq!(h.gcno, Some("foo-a1b6419f8321841f.gcno".into()));
37123752
}
37133753
}

0 commit comments

Comments
 (0)