@@ -16,7 +16,8 @@ use std::path::PathBuf;
16
16
use std:: process:: Command ;
17
17
use walkdir:: WalkDir ;
18
18
19
- use crate :: builder:: Kind ;
19
+ use crate :: builder:: { Builder , Kind } ;
20
+ use crate :: core:: build_steps:: tool;
20
21
use crate :: core:: config:: Target ;
21
22
use crate :: utils:: helpers:: output;
22
23
use crate :: Build ;
@@ -35,6 +36,10 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[
35
36
// just a dummy comment so the list doesn't get onelined
36
37
] ;
37
38
39
+ /// Minimum version threshold for libstdc++ required when using prebuilt LLVM
40
+ /// from CI (with`llvm.download-ci-llvm` option).
41
+ const LIBSTDCXX_MIN_VERSION_THRESHOLD : usize = 8 ;
42
+
38
43
impl Finder {
39
44
pub fn new ( ) -> Self {
40
45
Self { cache : HashMap :: new ( ) , path : env:: var_os ( "PATH" ) . unwrap_or_default ( ) }
@@ -99,6 +104,35 @@ pub fn check(build: &mut Build) {
99
104
cmd_finder. must_have ( "git" ) ;
100
105
}
101
106
107
+ // Ensure that a compatible version of libstdc++ is available on the system when using `llvm.download-ci-llvm`.
108
+ if !build. config . dry_run ( ) && !build. build . is_msvc ( ) && build. config . llvm_from_ci {
109
+ let builder = Builder :: new ( build) ;
110
+ let libcxx_version = builder. ensure ( tool:: LibcxxVersionTool { target : build. build } ) ;
111
+
112
+ match libcxx_version {
113
+ tool:: LibcxxVersion :: Gnu ( version) => {
114
+ if LIBSTDCXX_MIN_VERSION_THRESHOLD > version {
115
+ eprintln ! (
116
+ "\n Your system's libstdc++ version is too old for the `llvm.download-ci-llvm` option."
117
+ ) ;
118
+ eprintln ! ( "Current version detected: '{}'" , version) ;
119
+ eprintln ! ( "Minimum required version: '{}'" , LIBSTDCXX_MIN_VERSION_THRESHOLD ) ;
120
+ eprintln ! (
121
+ "Consider upgrading libstdc++ or disabling the `llvm.download-ci-llvm` option."
122
+ ) ;
123
+ crate :: exit!( 1 ) ;
124
+ }
125
+ }
126
+ tool:: LibcxxVersion :: Llvm ( _) => {
127
+ eprintln ! (
128
+ "\n Your system is using libc++, which is incompatible with the `llvm.download-ci-llvm` option."
129
+ ) ;
130
+ eprintln ! ( "Disable `llvm.download-ci-llvm` or switch to libstdc++." ) ;
131
+ crate :: exit!( 1 ) ;
132
+ }
133
+ }
134
+ }
135
+
102
136
// We need cmake, but only if we're actually building LLVM or sanitizers.
103
137
let building_llvm = build
104
138
. hosts
@@ -199,11 +233,15 @@ than building it.
199
233
if ![ "A-A" , "B-B" , "C-C" ] . contains ( & target_str. as_str ( ) ) {
200
234
let mut has_target = false ;
201
235
202
- let missing_targets_hashset: HashSet < _ > = STAGE0_MISSING_TARGETS . iter ( ) . map ( |t| t. to_string ( ) ) . collect ( ) ;
203
- let duplicated_targets: Vec < _ > = stage0_supported_target_list. intersection ( & missing_targets_hashset) . collect ( ) ;
236
+ let missing_targets_hashset: HashSet < _ > =
237
+ STAGE0_MISSING_TARGETS . iter ( ) . map ( |t| t. to_string ( ) ) . collect ( ) ;
238
+ let duplicated_targets: Vec < _ > =
239
+ stage0_supported_target_list. intersection ( & missing_targets_hashset) . collect ( ) ;
204
240
205
241
if !duplicated_targets. is_empty ( ) {
206
- println ! ( "Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list." ) ;
242
+ println ! (
243
+ "Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list."
244
+ ) ;
207
245
for duplicated_target in duplicated_targets {
208
246
println ! ( " {duplicated_target}" ) ;
209
247
}
0 commit comments