@@ -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
10011020use 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