@@ -33,6 +33,7 @@ struct InterpreterConfig {
33
33
base_prefix : String ,
34
34
executable : String ,
35
35
machine : String ,
36
+ maxsize_bits : Option < u32 > ,
36
37
}
37
38
38
39
#[ derive( Deserialize , Debug , Clone , PartialEq ) ]
@@ -181,6 +182,7 @@ fn load_cross_compile_info() -> Result<(InterpreterConfig, HashMap<String, Strin
181
182
base_prefix : "" . to_string ( ) ,
182
183
executable : "" . to_string ( ) ,
183
184
machine : "" . to_string ( ) ,
185
+ maxsize_bits : None ,
184
186
} ;
185
187
186
188
Ok ( ( interpreter_config, fix_config_map ( config_map) ) )
@@ -456,7 +458,8 @@ print(json.dumps({
456
458
"base_prefix": base_prefix,
457
459
"shared": PYPY or bool(sysconfig.get_config_var('Py_ENABLE_SHARED')),
458
460
"executable": sys.executable,
459
- "machine": platform.machine()
461
+ "machine": platform.machine(),
462
+ "maxsize_bits": sys.maxsize.bit_length(),
460
463
}))
461
464
"# ;
462
465
let json = run_python_script ( interpreter, script) ?;
@@ -475,7 +478,7 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<String> {
475
478
}
476
479
}
477
480
478
- check_target_architecture ( & interpreter_config. machine ) ?;
481
+ check_target_architecture ( interpreter_config) ?;
479
482
480
483
let is_extension_module = env:: var_os ( "CARGO_FEATURE_EXTENSION_MODULE" ) . is_some ( ) ;
481
484
if !is_extension_module || cfg ! ( target_os = "windows" ) {
@@ -517,32 +520,39 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<String> {
517
520
Ok ( flags)
518
521
}
519
522
520
- fn check_target_architecture ( python_machine : & str ) -> Result < ( ) > {
523
+ fn check_target_architecture ( interpreter_config : & InterpreterConfig ) -> Result < ( ) > {
521
524
// Try to check whether the target architecture matches the python library
522
- let target_arch = match env:: var ( "CARGO_CFG_TARGET_ARCH" )
523
- . as_ref ( )
524
- . map ( |e| e. as_str ( ) )
525
- {
526
- Ok ( "x86_64" ) => Some ( "64-bit" ) ,
527
- Ok ( "x86" ) => Some ( "32-bit" ) ,
528
- _ => None , // It might be possible to recognise other architectures, this will do for now.
525
+ let rust_target = match env:: var ( "CARGO_CFG_TARGET_POINTER_WIDTH" ) ?. as_str ( ) {
526
+ "64" => "64-bit" ,
527
+ "32" => "32-bit" ,
528
+ x => bail ! ( "unexpected Rust target pointer width: {}" , x) ,
529
529
} ;
530
530
531
- let python_arch = match python_machine {
532
- "AMD64" | "x86_64" => Some ( "64-bit" ) ,
533
- "i686" | "x86" => Some ( "32-bit" ) ,
534
- _ => None , // It might be possible to recognise other architectures, this will do for now.
531
+ // Why are we using at sys.maxsize here, rather than just
532
+ // platform.architecture()? Because the latter can give weird results on
533
+ // macOS. See https://stackoverflow.com/a/1405971/823869.
534
+ let python_target = match interpreter_config. maxsize_bits {
535
+ // sys.maxsize is a signed value, so it's one bit shorter than the
536
+ // pointer width.
537
+ Some ( 63 ) => "64-bit" ,
538
+ Some ( 31 ) => "32-bit" ,
539
+ None => {
540
+ // Unset, e.g. because we're cross-compiling. Don't check anything
541
+ // in this case.
542
+ return Ok ( ( ) ) ;
543
+ }
544
+ Some ( n) => panic ! ( "unexpected Python maxsize_bits: {}" , n) ,
535
545
} ;
536
546
537
- match ( target_arch, python_arch) {
538
- // If we could recognise both, and they're different, fail.
539
- ( Some ( t) , Some ( p) ) if p != t => bail ! (
547
+ if rust_target != python_target {
548
+ bail ! (
540
549
"Your Rust target architecture ({}) does not match your python interpreter ({})" ,
541
- t,
542
- p
543
- ) ,
544
- _ => Ok ( ( ) ) ,
550
+ rust_target,
551
+ python_target
552
+ ) ;
545
553
}
554
+
555
+ Ok ( ( ) )
546
556
}
547
557
548
558
fn check_rustc_version ( ) -> Result < ( ) > {
0 commit comments