Patch sysconfig data at install time (#9857)

## Summary

This PR reimplements
[`sysconfigpatcher`](https://github.com/bluss/sysconfigpatcher) in Rust
and applies it to our Python installations at install-time, ensuring
that the `sysconfig` data is more likely to be correct.

For now, we only rewrite prefixes (i.e., any path that starts with
`/install` gets rewritten to the correct absolute path for the current
machine).

Unlike `sysconfigpatcher`, this PR does not yet do any of the following:

- Patch `pkginfo` files.
- Change `clang` references to `cc`.

A few things that we should do as follow-ups, in my opinion:

1. Rewrite
[`AR`](c1ebf8ab92/src/sysconfigpatcher.py (L61)).
2. Remove `-isysroot`, which we already do for newer builds.
This commit is contained in:
Charlie Marsh 2024-12-13 14:36:22 -05:00 committed by GitHub
parent 5903ce5759
commit d2fb4c585d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 817 additions and 19 deletions

View file

@ -25,7 +25,7 @@ use crate::libc::LibcDetectionError;
use crate::platform::Error as PlatformError;
use crate::platform::{Arch, Libc, Os};
use crate::python_version::PythonVersion;
use crate::{PythonRequest, PythonVariant};
use crate::{sysconfig, PythonRequest, PythonVariant};
#[derive(Error, Debug)]
pub enum Error {
#[error(transparent)]
@ -40,6 +40,8 @@ pub enum Error {
InvalidPythonVersion(String),
#[error(transparent)]
ExtractError(#[from] uv_extract::Error),
#[error(transparent)]
SysconfigError(#[from] sysconfig::Error),
#[error("Failed to copy to: {0}", to.user_display())]
CopyError {
to: PathBuf,
@ -491,6 +493,21 @@ impl ManagedPythonInstallation {
Ok(())
}
/// Ensure that the `sysconfig` data is patched to match the installation path.
pub fn ensure_sysconfig_patched(&self) -> Result<(), Error> {
if cfg!(unix) {
if *self.implementation() == ImplementationName::CPython {
sysconfig::update_sysconfig(
self.path(),
self.key.major,
self.key.minor,
self.key.variant.suffix(),
)?;
}
}
Ok(())
}
/// Create a link to the managed Python executable.
///
/// If the file already exists at the target path, an error will be returned.