@@ -101,7 +101,7 @@ impl Display for DebuginfoLevel {
101101 }
102102}
103103
104- #[ derive( Default , Clone ) ]
104+ #[ derive( Default , Clone , PartialEq , serde_derive :: Serialize , serde_derive :: Deserialize ) ]
105105pub struct LLVMConfig {
106106 pub assertions : bool ,
107107 pub tests : bool ,
@@ -111,9 +111,6 @@ pub struct LLVMConfig {
111111 pub release_debuginfo : bool ,
112112 pub static_stdcpp : bool ,
113113 /// `None` if `llvm_from_ci` is true and we haven't yet downloaded llvm.
114- #[ cfg( not( test) ) ]
115- link_shared : Cell < Option < bool > > ,
116- #[ cfg( test) ]
117114 pub link_shared : Cell < Option < bool > > ,
118115 pub clang_cl : Option < String > ,
119116 pub targets : Option < String > ,
@@ -125,7 +122,6 @@ pub struct LLVMConfig {
125122 pub polly : bool ,
126123 pub clang : bool ,
127124 pub enable_warnings : bool ,
128- pub from_ci : bool ,
129125 pub build_config : HashMap < String , String > ,
130126
131127 pub use_lld : bool ,
@@ -204,6 +200,7 @@ pub struct Config {
204200 pub backtrace_on_ice : bool ,
205201
206202 // llvm codegen options
203+ pub llvm_from_ci : bool ,
207204 pub llvm : LLVMConfig ,
208205
209206 // rust codegen options
@@ -1519,18 +1516,26 @@ impl Config {
15191516 config. llvm . build_config = llvm. build_config . clone ( ) . unwrap_or ( Default :: default ( ) ) ;
15201517
15211518 let asserts = llvm_assertions. unwrap_or ( false ) ;
1522- config. llvm . from_ci = match llvm. download_ci_llvm {
1523- Some ( StringOrBool :: String ( s) ) => {
1524- assert ! ( s == "if-available" , "unknown option `{}` for download-ci-llvm" , s) ;
1525- crate :: llvm:: is_ci_llvm_available ( & config, asserts)
1526- }
1519+ let mut downloaded_config = false ;
1520+ config. llvm_from_ci = match llvm. download_ci_llvm {
1521+ Some ( StringOrBool :: String ( s) ) => match s. as_str ( ) {
1522+ "if-available" => crate :: llvm:: is_ci_llvm_available ( & config, asserts) ,
1523+ "if-identical" => match crate :: llvm:: get_llvm_opts_from_ci ( & config) {
1524+ Some ( config_ci) => {
1525+ downloaded_config = true ;
1526+ is_llvm_config_identical ( & config_ci, & config. llvm )
1527+ }
1528+ None => false ,
1529+ } ,
1530+ _ => panic ! ( "unknown option `{s}` for download-ci-llvm" ) ,
1531+ } ,
15271532 Some ( StringOrBool :: Bool ( b) ) => b,
15281533 None => {
15291534 config. channel == "dev" && crate :: llvm:: is_ci_llvm_available ( & config, asserts)
15301535 }
15311536 } ;
15321537
1533- if config. llvm . from_ci {
1538+ if config. llvm_from_ci && !downloaded_config {
15341539 // None of the LLVM options, except assertions, are supported
15351540 // when using downloaded LLVM. We could just ignore these but
15361541 // that's potentially confusing, so force them to not be
@@ -1561,14 +1566,14 @@ impl Config {
15611566 }
15621567
15631568 // NOTE: can never be hit when downloading from CI, since we call `check_ci_llvm!(thin_lto)` above.
1564- if config. llvm . thin_lto && llvm. link_shared . is_none ( ) {
1569+ if !downloaded_config && config. llvm . thin_lto && llvm. link_shared . is_none ( ) {
15651570 // If we're building with ThinLTO on, by default we want to link
15661571 // to LLVM shared, to avoid re-doing ThinLTO (which happens in
15671572 // the link step) with each stage.
15681573 config. llvm . link_shared . set ( Some ( true ) ) ;
15691574 }
15701575 } else {
1571- config. llvm . from_ci =
1576+ config. llvm_from_ci =
15721577 config. channel == "dev" && crate :: llvm:: is_ci_llvm_available ( & config, false ) ;
15731578 }
15741579
@@ -1620,7 +1625,7 @@ impl Config {
16201625 }
16211626 }
16221627
1623- if config. llvm . from_ci {
1628+ if config. llvm_from_ci {
16241629 let triple = & config. build . triple ;
16251630 let ci_llvm_bin = config. ci_llvm_root ( ) . join ( "bin" ) ;
16261631 let build_target = config
@@ -1860,10 +1865,14 @@ impl Config {
18601865
18611866 /// The absolute path to the downloaded LLVM artifacts.
18621867 pub ( crate ) fn ci_llvm_root ( & self ) -> PathBuf {
1863- assert ! ( self . llvm . from_ci ) ;
1868+ assert ! ( self . llvm_from_ci ) ;
18641869 self . out . join ( & * self . build . triple ) . join ( "ci-llvm" )
18651870 }
18661871
1872+ pub ( crate ) fn ci_llvm_root_opts ( & self ) -> PathBuf {
1873+ self . out . join ( & * self . build . triple ) . join ( "ci-llvm-opts" )
1874+ }
1875+
18671876 /// Directory where the extracted `rustc-dev` component is stored.
18681877 pub ( crate ) fn ci_rustc_dir ( & self ) -> PathBuf {
18691878 assert ! ( self . download_rustc( ) ) ;
@@ -1882,7 +1891,7 @@ impl Config {
18821891 }
18831892
18841893 let llvm_link_shared = * opt. get_or_insert_with ( || {
1885- if self . llvm . from_ci {
1894+ if self . llvm_from_ci {
18861895 self . maybe_download_ci_llvm ( ) ;
18871896 let ci_llvm = self . ci_llvm_root ( ) ;
18881897 let link_type = t ! (
@@ -2089,6 +2098,10 @@ impl Config {
20892098 }
20902099}
20912100
2101+ fn is_llvm_config_identical ( from_ci : & LLVMConfig , current : & LLVMConfig ) -> bool {
2102+ from_ci == current
2103+ }
2104+
20922105fn set < T > ( field : & mut T , val : Option < T > ) {
20932106 if let Some ( v) = val {
20942107 * field = v;
0 commit comments