@@ -1216,13 +1216,23 @@ impl Config {
12161216 }
12171217 }
12181218
1219+ pub ( crate ) fn get_builder_toml ( & self , build_name : & str ) -> Result < TomlConfig , toml:: de:: Error > {
1220+ if self . dry_run ( ) {
1221+ return Ok ( TomlConfig :: default ( ) ) ;
1222+ }
1223+
1224+ let builder_config_path =
1225+ self . out . join ( self . build . triple ) . join ( build_name) . join ( BUILDER_CONFIG_FILENAME ) ;
1226+ Self :: get_toml ( & builder_config_path)
1227+ }
1228+
12191229 #[ cfg( test) ]
1220- fn get_toml ( _: & Path ) -> Result < TomlConfig , toml:: de:: Error > {
1230+ pub ( crate ) fn get_toml ( _: & Path ) -> Result < TomlConfig , toml:: de:: Error > {
12211231 Ok ( TomlConfig :: default ( ) )
12221232 }
12231233
12241234 #[ cfg( not( test) ) ]
1225- fn get_toml ( file : & Path ) -> Result < TomlConfig , toml:: de:: Error > {
1235+ pub ( crate ) fn get_toml ( file : & Path ) -> Result < TomlConfig , toml:: de:: Error > {
12261236 let contents =
12271237 t ! ( fs:: read_to_string( file) , format!( "config file {} not found" , file. display( ) ) ) ;
12281238 // Deserialize to Value and then TomlConfig to prevent the Deserialize impl of
@@ -1908,34 +1918,9 @@ impl Config {
19081918 "HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false."
19091919 ) ;
19101920 }
1911-
1912- // None of the LLVM options, except assertions, are supported
1913- // when using downloaded LLVM. We could just ignore these but
1914- // that's potentially confusing, so force them to not be
1915- // explicitly set. The defaults and CI defaults don't
1916- // necessarily match but forcing people to match (somewhat
1917- // arbitrary) CI configuration locally seems bad/hard.
1918- check_ci_llvm ! ( optimize_toml) ;
1919- check_ci_llvm ! ( thin_lto) ;
1920- check_ci_llvm ! ( release_debuginfo) ;
1921- check_ci_llvm ! ( targets) ;
1922- check_ci_llvm ! ( experimental_targets) ;
1923- check_ci_llvm ! ( clang_cl) ;
1924- check_ci_llvm ! ( version_suffix) ;
1925- check_ci_llvm ! ( cflags) ;
1926- check_ci_llvm ! ( cxxflags) ;
1927- check_ci_llvm ! ( ldflags) ;
1928- check_ci_llvm ! ( use_libcxx) ;
1929- check_ci_llvm ! ( use_linker) ;
1930- check_ci_llvm ! ( allow_old_toolchain) ;
1931- check_ci_llvm ! ( polly) ;
1932- check_ci_llvm ! ( clang) ;
1933- check_ci_llvm ! ( build_config) ;
1934- check_ci_llvm ! ( plugins) ;
19351921 }
19361922
1937- // NOTE: can never be hit when downloading from CI, since we call `check_ci_llvm!(thin_lto)` above.
1938- if config. llvm_thin_lto && link_shared. is_none ( ) {
1923+ if !config. llvm_from_ci && config. llvm_thin_lto && link_shared. is_none ( ) {
19391924 // If we're building with ThinLTO on, by default we want to link
19401925 // to LLVM shared, to avoid re-doing ThinLTO (which happens in
19411926 // the link step) with each stage.
@@ -2374,18 +2359,15 @@ impl Config {
23742359 self . download_ci_rustc ( commit) ;
23752360
23762361 if let Some ( config_path) = & self . config {
2377- let builder_config_path =
2378- self . out . join ( self . build . triple ) . join ( "ci-rustc" ) . join ( BUILDER_CONFIG_FILENAME ) ;
2379-
2380- let ci_config_toml = match Self :: get_toml ( & builder_config_path) {
2362+ let ci_config_toml = match self . get_builder_toml ( "ci-rustc" ) {
23812363 Ok ( ci_config_toml) => ci_config_toml,
23822364 Err ( e) if e. to_string ( ) . contains ( "unknown field" ) => {
23832365 println ! ( "WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled." ) ;
23842366 println ! ( "HELP: Consider rebasing to a newer commit if available." ) ;
23852367 return None ;
23862368 } ,
23872369 Err ( e) => {
2388- eprintln ! ( "ERROR: Failed to parse CI rustc config at '{}' : {e}" , builder_config_path . display ( ) ) ;
2370+ eprintln ! ( "ERROR: Failed to parse CI rustc config.toml : {e}" ) ;
23892371 exit ! ( 2 ) ;
23902372 } ,
23912373 } ;
@@ -2846,6 +2828,109 @@ impl Config {
28462828 }
28472829}
28482830
2831+ /// Compares the current `Llvm` options against those in the CI LLVM builder and detects any incompatible options.
2832+ /// It does this by destructuring the `Llvm` instance to make sure every `Llvm` field is covered and not missing.
2833+ #[ cfg( not( feature = "bootstrap-self-test" ) ) ]
2834+ pub ( crate ) fn check_incompatible_options_for_ci_llvm (
2835+ current_config_toml : TomlConfig ,
2836+ ci_config_toml : TomlConfig ,
2837+ ) -> Result < ( ) , String > {
2838+ macro_rules! err {
2839+ ( $current: expr, $expected: expr) => {
2840+ if let Some ( current) = & $current {
2841+ if Some ( current) != $expected. as_ref( ) {
2842+ return Err ( format!(
2843+ "ERROR: Setting `llvm.{}` is incompatible with `llvm.download-ci-llvm`. \
2844+ Current value: {:?}, Expected value(s): {}{:?}",
2845+ stringify!( $expected) . replace( "_" , "-" ) ,
2846+ $current,
2847+ if $expected. is_some( ) { "None/" } else { "" } ,
2848+ $expected,
2849+ ) ) ;
2850+ } ;
2851+ } ;
2852+ } ;
2853+ }
2854+
2855+ macro_rules! warn {
2856+ ( $current: expr, $expected: expr) => {
2857+ if let Some ( current) = & $current {
2858+ if Some ( current) != $expected. as_ref( ) {
2859+ println!(
2860+ "WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \
2861+ Current value: {:?}, Expected value(s): {}{:?}",
2862+ stringify!( $expected) . replace( "_" , "-" ) ,
2863+ $current,
2864+ if $expected. is_some( ) { "None/" } else { "" } ,
2865+ $expected,
2866+ ) ;
2867+ } ;
2868+ } ;
2869+ } ;
2870+ }
2871+
2872+ let ( Some ( current_llvm_config) , Some ( ci_llvm_config) ) =
2873+ ( current_config_toml. llvm , ci_config_toml. llvm )
2874+ else {
2875+ return Ok ( ( ) ) ;
2876+ } ;
2877+
2878+ let Llvm {
2879+ optimize,
2880+ thin_lto,
2881+ release_debuginfo,
2882+ assertions : _,
2883+ tests : _,
2884+ plugins,
2885+ ccache : _,
2886+ static_libstdcpp : _,
2887+ libzstd,
2888+ ninja : _,
2889+ targets,
2890+ experimental_targets,
2891+ link_jobs : _,
2892+ link_shared : _,
2893+ version_suffix,
2894+ clang_cl,
2895+ cflags,
2896+ cxxflags,
2897+ ldflags,
2898+ use_libcxx,
2899+ use_linker,
2900+ allow_old_toolchain,
2901+ polly,
2902+ clang,
2903+ enable_warnings,
2904+ download_ci_llvm : _,
2905+ build_config,
2906+ enzyme,
2907+ } = ci_llvm_config;
2908+
2909+ err ! ( current_llvm_config. optimize, optimize) ;
2910+ err ! ( current_llvm_config. thin_lto, thin_lto) ;
2911+ err ! ( current_llvm_config. release_debuginfo, release_debuginfo) ;
2912+ err ! ( current_llvm_config. libzstd, libzstd) ;
2913+ err ! ( current_llvm_config. targets, targets) ;
2914+ err ! ( current_llvm_config. experimental_targets, experimental_targets) ;
2915+ err ! ( current_llvm_config. clang_cl, clang_cl) ;
2916+ err ! ( current_llvm_config. version_suffix, version_suffix) ;
2917+ err ! ( current_llvm_config. cflags, cflags) ;
2918+ err ! ( current_llvm_config. cxxflags, cxxflags) ;
2919+ err ! ( current_llvm_config. ldflags, ldflags) ;
2920+ err ! ( current_llvm_config. use_libcxx, use_libcxx) ;
2921+ err ! ( current_llvm_config. use_linker, use_linker) ;
2922+ err ! ( current_llvm_config. allow_old_toolchain, allow_old_toolchain) ;
2923+ err ! ( current_llvm_config. polly, polly) ;
2924+ err ! ( current_llvm_config. clang, clang) ;
2925+ err ! ( current_llvm_config. build_config, build_config) ;
2926+ err ! ( current_llvm_config. plugins, plugins) ;
2927+ err ! ( current_llvm_config. enzyme, enzyme) ;
2928+
2929+ warn ! ( current_llvm_config. enable_warnings, enable_warnings) ;
2930+
2931+ Ok ( ( ) )
2932+ }
2933+
28492934/// Compares the current Rust options against those in the CI rustc builder and detects any incompatible options.
28502935/// It does this by destructuring the `Rust` instance to make sure every `Rust` field is covered and not missing.
28512936fn check_incompatible_options_for_ci_rustc (
0 commit comments