@@ -17,6 +17,7 @@ use super::errors::AnyError;
1717lazy_static ! {
1818 static ref LDCONFIG_STDC_RE : Regex = Regex :: new( r"libstdc\+\+.* => (.+)" ) . unwrap( ) ;
1919 static ref LDD_VERSION_RE : BinRegex = BinRegex :: new( r"^ldd.*(.+)\.(.+)\s" ) . unwrap( ) ;
20+ static ref GENERIC_VERSION_RE : Regex = Regex :: new( r"^([0-9]+)\.([0-9]+)$" ) . unwrap( ) ;
2021 static ref LIBSTD_CXX_VERSION_RE : BinRegex =
2122 BinRegex :: new( r"GLIBCXX_([0-9]+)\.([0-9]+)(?:\.([0-9]+))?" ) . unwrap( ) ;
2223 static ref MIN_CXX_VERSION : SimpleSemver = SimpleSemver :: new( 3 , 4 , 18 ) ;
@@ -116,13 +117,23 @@ async fn check_musl_interpreter() -> Result<(), String> {
116117
117118#[ allow( dead_code) ]
118119async fn check_glibc_version ( ) -> Result < ( ) , String > {
119- let ldd_version = capture_command ( "ldd" , [ "--version" ] )
120- . await
121- . ok ( )
122- . and_then ( |o| extract_ldd_version ( & o. stdout ) ) ;
120+ #[ cfg( target_env = "gnu" ) ]
121+ let version = {
122+ let v = unsafe { libc:: gnu_get_libc_version ( ) } ;
123+ let v = unsafe { std:: ffi:: CStr :: from_ptr ( v) } ;
124+ let v = v. to_str ( ) . unwrap ( ) ;
125+ extract_generic_version ( v)
126+ } ;
127+ #[ cfg( not( target_env = "gnu" ) ) ]
128+ let version = {
129+ capture_command ( "ldd" , [ "--version" ] )
130+ . await
131+ . ok ( )
132+ . and_then ( |o| extract_ldd_version ( & o. stdout ) )
133+ } ;
123134
124- if let Some ( v) = ldd_version {
125- return if v. gte ( & MIN_LDD_VERSION ) {
135+ if let Some ( v) = version {
136+ return if v >= * MIN_LDD_VERSION {
126137 Ok ( ( ) )
127138 } else {
128139 Err ( format ! (
@@ -181,7 +192,7 @@ fn check_for_sufficient_glibcxx_versions(contents: Vec<u8>) -> Result<(), String
181192 } )
182193 . collect ( ) ;
183194
184- if !all_versions. iter ( ) . any ( |v| MIN_CXX_VERSION . gte ( v ) ) {
195+ if !all_versions. iter ( ) . any ( |v| & * MIN_CXX_VERSION >= v ) {
185196 return Err ( format ! (
186197 "find GLIBCXX >= 3.4.18 (but found {} instead) for GNU environments" ,
187198 all_versions
@@ -195,6 +206,7 @@ fn check_for_sufficient_glibcxx_versions(contents: Vec<u8>) -> Result<(), String
195206 Ok ( ( ) )
196207}
197208
209+ #[ allow( dead_code) ]
198210fn extract_ldd_version ( output : & [ u8 ] ) -> Option < SimpleSemver > {
199211 LDD_VERSION_RE . captures ( output) . map ( |m| SimpleSemver {
200212 major : m. get ( 1 ) . map_or ( 0 , |s| u32_from_bytes ( s. as_bytes ( ) ) ) ,
@@ -203,6 +215,15 @@ fn extract_ldd_version(output: &[u8]) -> Option<SimpleSemver> {
203215 } )
204216}
205217
218+ #[ allow( dead_code) ]
219+ fn extract_generic_version ( output : & str ) -> Option < SimpleSemver > {
220+ GENERIC_VERSION_RE . captures ( output) . map ( |m| SimpleSemver {
221+ major : m. get ( 1 ) . map_or ( 0 , |s| s. as_str ( ) . parse ( ) . unwrap ( ) ) ,
222+ minor : m. get ( 2 ) . map_or ( 0 , |s| s. as_str ( ) . parse ( ) . unwrap ( ) ) ,
223+ patch : 0 ,
224+ } )
225+ }
226+
206227fn extract_libstd_from_ldconfig ( output : & [ u8 ] ) -> Option < String > {
207228 String :: from_utf8_lossy ( output)
208229 . lines ( )
@@ -215,13 +236,35 @@ fn u32_from_bytes(b: &[u8]) -> u32 {
215236 String :: from_utf8_lossy ( b) . parse :: < u32 > ( ) . unwrap_or ( 0 )
216237}
217238
218- #[ derive( Debug , PartialEq ) ]
239+ #[ derive( Debug , Default , PartialEq , Eq ) ]
219240struct SimpleSemver {
220241 major : u32 ,
221242 minor : u32 ,
222243 patch : u32 ,
223244}
224245
246+ impl PartialOrd for SimpleSemver {
247+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
248+ Some ( self . cmp ( other) )
249+ }
250+ }
251+
252+ impl Ord for SimpleSemver {
253+ fn cmp ( & self , other : & Self ) -> Ordering {
254+ let major = self . major . cmp ( & other. major ) ;
255+ if major != Ordering :: Equal {
256+ return major;
257+ }
258+
259+ let minor = self . minor . cmp ( & other. minor ) ;
260+ if minor != Ordering :: Equal {
261+ return minor;
262+ }
263+
264+ self . patch . cmp ( & other. patch )
265+ }
266+ }
267+
225268impl From < & SimpleSemver > for String {
226269 fn from ( s : & SimpleSemver ) -> Self {
227270 format ! ( "v{}.{}.{}" , s. major, s. minor, s. patch)
@@ -243,18 +286,6 @@ impl SimpleSemver {
243286 patch,
244287 }
245288 }
246-
247- fn gte ( & self , other : & SimpleSemver ) -> bool {
248- match self . major . cmp ( & other. major ) {
249- Ordering :: Greater => true ,
250- Ordering :: Less => false ,
251- Ordering :: Equal => match self . minor . cmp ( & other. minor ) {
252- Ordering :: Greater => true ,
253- Ordering :: Less => false ,
254- Ordering :: Equal => self . patch >= other. patch ,
255- } ,
256- }
257- }
258289}
259290
260291#[ cfg( test) ]
@@ -284,13 +315,13 @@ mod tests {
284315
285316 #[ test]
286317 fn test_gte ( ) {
287- assert ! ( SimpleSemver :: new( 1 , 2 , 3 ) . gte ( & SimpleSemver :: new( 1 , 2 , 3 ) ) ) ;
288- assert ! ( SimpleSemver :: new( 1 , 2 , 3 ) . gte ( & SimpleSemver :: new( 0 , 10 , 10 ) ) ) ;
289- assert ! ( SimpleSemver :: new( 1 , 2 , 3 ) . gte ( & SimpleSemver :: new( 1 , 1 , 10 ) ) ) ;
318+ assert ! ( SimpleSemver :: new( 1 , 2 , 3 ) >= SimpleSemver :: new( 1 , 2 , 3 ) ) ;
319+ assert ! ( SimpleSemver :: new( 1 , 2 , 3 ) >= SimpleSemver :: new( 0 , 10 , 10 ) ) ;
320+ assert ! ( SimpleSemver :: new( 1 , 2 , 3 ) >= SimpleSemver :: new( 1 , 1 , 10 ) ) ;
290321
291- assert ! ( ! SimpleSemver :: new( 1 , 2 , 3 ) . gte ( & SimpleSemver :: new( 1 , 2 , 10 ) ) ) ;
292- assert ! ( ! SimpleSemver :: new( 1 , 2 , 3 ) . gte ( & SimpleSemver :: new( 1 , 3 , 1 ) ) ) ;
293- assert ! ( ! SimpleSemver :: new( 1 , 2 , 3 ) . gte ( & SimpleSemver :: new( 2 , 2 , 1 ) ) ) ;
322+ assert ! ( SimpleSemver :: new( 1 , 2 , 3 ) < SimpleSemver :: new( 1 , 2 , 10 ) ) ;
323+ assert ! ( SimpleSemver :: new( 1 , 2 , 3 ) < SimpleSemver :: new( 1 , 3 , 1 ) ) ;
324+ assert ! ( SimpleSemver :: new( 1 , 2 , 3 ) < SimpleSemver :: new( 2 , 2 , 1 ) ) ;
294325 }
295326
296327 #[ test]
0 commit comments