@@ -32,7 +32,7 @@ struct InterpreterConfig {
32
32
/// Prefix used for determining the directory of libpython
33
33
base_prefix : String ,
34
34
executable : String ,
35
- machine : String ,
35
+ calcsize_pointer : Option < u32 > ,
36
36
}
37
37
38
38
#[ derive( Deserialize , Debug , Clone , PartialEq ) ]
@@ -180,7 +180,7 @@ fn load_cross_compile_info() -> Result<(InterpreterConfig, HashMap<String, Strin
180
180
ld_version : "" . to_string ( ) ,
181
181
base_prefix : "" . to_string ( ) ,
182
182
executable : "" . to_string ( ) ,
183
- machine : "" . to_string ( ) ,
183
+ calcsize_pointer : None ,
184
184
} ;
185
185
186
186
Ok ( ( interpreter_config, fix_config_map ( config_map) ) )
@@ -433,10 +433,11 @@ fn find_interpreter_and_get_config() -> Result<(InterpreterConfig, HashMap<Strin
433
433
/// Extract compilation vars from the specified interpreter.
434
434
fn get_config_from_interpreter ( interpreter : & str ) -> Result < InterpreterConfig > {
435
435
let script = r#"
436
+ import json
437
+ import platform
438
+ import struct
436
439
import sys
437
440
import sysconfig
438
- import platform
439
- import json
440
441
441
442
PYPY = platform.python_implementation() == "PyPy"
442
443
@@ -456,7 +457,7 @@ print(json.dumps({
456
457
"base_prefix": base_prefix,
457
458
"shared": PYPY or bool(sysconfig.get_config_var('Py_ENABLE_SHARED')),
458
459
"executable": sys.executable,
459
- "machine ": platform.machine()
460
+ "calcsize_pointer ": struct.calcsize("P"),
460
461
}))
461
462
"# ;
462
463
let json = run_python_script ( interpreter, script) ?;
@@ -475,7 +476,7 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<String> {
475
476
}
476
477
}
477
478
478
- check_target_architecture ( & interpreter_config. machine ) ?;
479
+ check_target_architecture ( interpreter_config) ?;
479
480
480
481
let is_extension_module = env:: var_os ( "CARGO_FEATURE_EXTENSION_MODULE" ) . is_some ( ) ;
481
482
if !is_extension_module || cfg ! ( target_os = "windows" ) {
@@ -517,32 +518,39 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<String> {
517
518
Ok ( flags)
518
519
}
519
520
520
- fn check_target_architecture ( python_machine : & str ) -> Result < ( ) > {
521
+ fn check_target_architecture ( interpreter_config : & InterpreterConfig ) -> Result < ( ) > {
521
522
// 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.
523
+ let rust_target = match env:: var ( "CARGO_CFG_TARGET_POINTER_WIDTH" ) ?. as_str ( ) {
524
+ "64" => "64-bit" ,
525
+ "32" => "32-bit" ,
526
+ x => bail ! ( "unexpected Rust target pointer width: {}" , x) ,
529
527
} ;
530
528
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.
529
+ // The reason we don't use platform.architecture() here is that it's not
530
+ // reliable on macOS. See https://stackoverflow.com/a/1405971/823869.
531
+ // Similarly, sys.maxsize is not reliable on Windows. See
532
+ // https://stackoverflow.com/questions/1405913/how-do-i-determine-if-my-python-shell-is-executing-in-32bit-or-64bit-mode-on-os/1405971#comment6209952_1405971
533
+ // and https://stackoverflow.com/a/3411134/823869.
534
+ let python_target = match interpreter_config. calcsize_pointer {
535
+ Some ( 8 ) => "64-bit" ,
536
+ Some ( 4 ) => "32-bit" ,
537
+ None => {
538
+ // Unset, e.g. because we're cross-compiling. Don't check anything
539
+ // in this case.
540
+ return Ok ( ( ) ) ;
541
+ }
542
+ Some ( n) => bail ! ( "unexpected Python calcsize_pointer value: {}" , n) ,
535
543
} ;
536
544
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 ! (
545
+ if rust_target != python_target {
546
+ bail ! (
540
547
"Your Rust target architecture ({}) does not match your python interpreter ({})" ,
541
- t,
542
- p
543
- ) ,
544
- _ => Ok ( ( ) ) ,
548
+ rust_target,
549
+ python_target
550
+ ) ;
545
551
}
552
+
553
+ Ok ( ( ) )
546
554
}
547
555
548
556
fn check_rustc_version ( ) -> Result < ( ) > {
0 commit comments