Skip to content

Commit 34c55f2

Browse files
committed
use sys.maxsize rather than platform.machine()
platform.machine() gives the wrong answer if you're running 32-bit Python on a 64-bit machine. sys.maxsize gives the answer we want. See also https://stackoverflow.com/a/1405971/823869. Also use CARGO_CFG_TARGET_POINTER_WIDTH rather than inferring the pointer width from CARGO_CFG_TARGET_ARCH.
1 parent 1c1d3c4 commit 34c55f2

File tree

1 file changed

+31
-21
lines changed

1 file changed

+31
-21
lines changed

build.rs

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct InterpreterConfig {
3333
base_prefix: String,
3434
executable: String,
3535
machine: String,
36+
maxsize_bits: Option<u32>,
3637
}
3738

3839
#[derive(Deserialize, Debug, Clone, PartialEq)]
@@ -181,6 +182,7 @@ fn load_cross_compile_info() -> Result<(InterpreterConfig, HashMap<String, Strin
181182
base_prefix: "".to_string(),
182183
executable: "".to_string(),
183184
machine: "".to_string(),
185+
maxsize_bits: None,
184186
};
185187

186188
Ok((interpreter_config, fix_config_map(config_map)))
@@ -456,7 +458,8 @@ print(json.dumps({
456458
"base_prefix": base_prefix,
457459
"shared": PYPY or bool(sysconfig.get_config_var('Py_ENABLE_SHARED')),
458460
"executable": sys.executable,
459-
"machine": platform.machine()
461+
"machine": platform.machine(),
462+
"maxsize_bits": sys.maxsize.bit_length(),
460463
}))
461464
"#;
462465
let json = run_python_script(interpreter, script)?;
@@ -475,7 +478,7 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<String> {
475478
}
476479
}
477480

478-
check_target_architecture(&interpreter_config.machine)?;
481+
check_target_architecture(interpreter_config)?;
479482

480483
let is_extension_module = env::var_os("CARGO_FEATURE_EXTENSION_MODULE").is_some();
481484
if !is_extension_module || cfg!(target_os = "windows") {
@@ -517,32 +520,39 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<String> {
517520
Ok(flags)
518521
}
519522

520-
fn check_target_architecture(python_machine: &str) -> Result<()> {
523+
fn check_target_architecture(interpreter_config: &InterpreterConfig) -> Result<()> {
521524
// 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),
529529
};
530530

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),
535545
};
536546

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!(
540549
"Your Rust target architecture ({}) does not match your python interpreter ({})",
541-
t,
542-
p
543-
),
544-
_ => Ok(()),
550+
rust_target,
551+
python_target
552+
);
545553
}
554+
555+
Ok(())
546556
}
547557

548558
fn check_rustc_version() -> Result<()> {

0 commit comments

Comments
 (0)