Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Target::get_platform_tag to use standard osname-release-machine fallback representation #1318

Merged
merged 3 commits into from
Dec 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ jobs:
test-emscripten:
name: Test Emscripten
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
env:
PYODIDE_VERSION: '0.21.3'
PYTHON_VERSION: '3.10.2'
Expand Down
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ RUN curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
&& python3.8 -m pip install --no-cache-dir cffi \
&& python3.9 -m pip install --no-cache-dir cffi \
&& python3.10 -m pip install --no-cache-dir cffi \
&& python3.11 -m pip install --no-cache-dir cffi \
&& mkdir /io

COPY --from=builder /usr/bin/maturin /usr/bin/maturin
Expand Down
195 changes: 97 additions & 98 deletions src/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,29 @@ impl fmt::Display for Arch {
}
}

impl Arch {
/// Represents the hardware platform.
///
/// This is the same as the native platform's `uname -m` output.
pub fn machine(&self) -> &'static str {
// See https://www.freebsd.org/cgi/man.cgi?query=arch&sektion=7&format=html
// MACHINE_ARCH vs MACHINE_CPUARCH vs MACHINE section
match self {
Arch::Aarch64 => "arm64",
Arch::Armv6L | Arch::Armv7L => "arm",
Arch::Powerpc | Arch::Powerpc64Le | Arch::Powerpc64 => "powerpc",
Arch::X86 => "i386",
Arch::X86_64 => "amd64",
Arch::Riscv64 => "riscv",
Arch::Mips64el | Arch::Mipsel => "mips",
// sparc64 is unsupported since FreeBSD 13.0
Arch::Sparc64 => "sparc64",
Arch::Wasm32 => "wasm32",
Arch::S390X => "s390x",
}
}
}

// Returns the set of supported architectures for each operating system
fn get_supported_architectures(os: &Os) -> Vec<Arch> {
match os {
Expand All @@ -117,18 +140,31 @@ fn get_supported_architectures(os: &Os) -> Vec<Arch> {
],
Os::Windows => vec![Arch::X86, Arch::X86_64, Arch::Aarch64],
Os::Macos => vec![Arch::Aarch64, Arch::X86_64],
Os::NetBsd => vec![Arch::Aarch64, Arch::X86, Arch::X86_64],
Os::FreeBsd => vec![
Os::FreeBsd | Os::NetBsd => vec![
Arch::Aarch64,
Arch::Armv6L,
Arch::Armv7L,
Arch::Powerpc,
Arch::Powerpc64,
Arch::Powerpc64Le,
Arch::X86,
Arch::X86_64,
Arch::Riscv64,
Arch::Mips64el,
Arch::Mipsel,
Arch::Sparc64,
],
Os::OpenBsd => vec![
Arch::X86,
Arch::X86_64,
Arch::Aarch64,
Arch::Armv7L,
Arch::Powerpc,
Arch::Powerpc64,
Arch::Powerpc64Le,
Arch::Riscv64,
Arch::Sparc64,
],
Os::OpenBsd => vec![Arch::X86, Arch::X86_64, Arch::Aarch64],
Os::Dragonfly => vec![Arch::X86_64],
Os::Illumos => vec![Arch::X86_64],
Os::Haiku => vec![Arch::X86_64],
Expand Down Expand Up @@ -235,41 +271,53 @@ impl Target {
universal2: bool,
) -> Result<String> {
let tag = match (&self.os, &self.arch) {
// Windows
(Os::Windows, Arch::X86) => "win32".to_string(),
(Os::Windows, Arch::X86_64) => "win_amd64".to_string(),
(Os::Windows, Arch::Aarch64) => "win_arm64".to_string(),
// Linux
(Os::Linux, _) => {
let arch = self.get_platform_arch()?;
let mut platform_tags = platform_tags.to_vec();
platform_tags.sort();
let mut tags = vec![];
for platform_tag in platform_tags {
tags.push(format!("{}_{}", platform_tag, arch));
for alias in platform_tag.aliases() {
tags.push(format!("{}_{}", alias, arch));
}
}
tags.join(".")
}
// macOS
(Os::Macos, Arch::X86_64) | (Os::Macos, Arch::Aarch64) => {
let ((x86_64_major, x86_64_minor), (arm64_major, arm64_minor)) = macosx_deployment_target(env::var("MACOSX_DEPLOYMENT_TARGET").ok().as_deref(), universal2)?;
if universal2 {
format!(
"macosx_{x86_64_major}_{x86_64_minor}_x86_64.macosx_{arm64_major}_{arm64_minor}_arm64.macosx_{x86_64_major}_{x86_64_minor}_universal2",
x86_64_major = x86_64_major,
x86_64_minor = x86_64_minor,
arm64_major = arm64_major,
arm64_minor = arm64_minor
)
} else if self.arch == Arch::Aarch64 {
format!("macosx_{}_{}_arm64", arm64_major, arm64_minor)
} else {
format!("macosx_{}_{}_x86_64", x86_64_major, x86_64_minor)
}
}
// FreeBSD
(Os::FreeBsd, Arch::X86)
| (Os::FreeBsd, Arch::X86_64)
| (Os::FreeBsd, Arch::Aarch64)
| (Os::FreeBsd, Arch::Armv6L)
| (Os::FreeBsd, Arch::Armv7L)
| (Os::FreeBsd, Arch::Powerpc)
| (Os::FreeBsd, Arch::Powerpc64)
| (Os::FreeBsd, Arch::Powerpc64Le)
| (Os::FreeBsd, Arch::Riscv64)
(Os::FreeBsd, _)
// NetBSD
| (Os::NetBsd, Arch::X86)
| (Os::NetBsd, Arch::X86_64)
| (Os::NetBsd, Arch::Aarch64)
| (Os::NetBsd, _)
// OpenBSD
| (Os::OpenBsd, Arch::X86)
| (Os::OpenBsd, Arch::X86_64)
| (Os::OpenBsd, Arch::Aarch64) => {
| (Os::OpenBsd, _) => {
let release = self.get_platform_release()?;
let arch = match self.arch {
Arch::X86_64 => "amd64",
Arch::X86 => "i386",
Arch::Aarch64 => "arm64",
Arch::Armv6L | Arch::Armv7L => "arm",
Arch::Powerpc | Arch::Powerpc64 | Arch::Powerpc64Le => "powerpc",
Arch::Riscv64 => "riscv",
_ => panic!(
"unsupported architecture should not have reached get_platform_tag()"
),
};
format!(
"{}_{}_{}",
self.os.to_string().to_ascii_lowercase(),
release,
arch
self.arch.machine(),
)
}
// DragonFly
Expand All @@ -284,95 +332,46 @@ impl Target {
"x86_64"
)
}
// Solaris and Illumos
(Os::Solaris, Arch::X86_64) |
(Os::Solaris, Arch::Sparc64) |
(Os::Illumos, Arch::X86_64) => {
// Emscripten
(Os::Emscripten, Arch::Wasm32) => {
let os_version = env::var("MATURIN_EMSCRIPTEN_VERSION");
let release = match os_version {
Ok(os_ver) => os_ver,
Err(_) => emcc_version()?,
};
let release = release.replace(['.', '-'], "_");
format!("emscripten_{}_wasm32", release)
}
(Os::Wasi, Arch::Wasm32) => {
"any".to_string()
}
// osname_release_machine fallback for any POSIX system
(_, _) => {
let info = PlatformInfo::new()?;
let mut release = info.release().replace(['.', '-'], "_");
let mut arch = info.machine().replace([' ', '/'], "_");
let mut machine = info.machine().replace([' ', '/'], "_");

let mut os = self.os.to_string().to_ascii_lowercase();
// See https://github.com/python/cpython/blob/46c8d915715aa2bd4d697482aa051fe974d440e1/Lib/sysconfig.py#L722-L730
if os.starts_with("sunos") {
// Solaris / Illumos
if let Some((major, other)) = release.split_once('_') {
let major_ver: u64 = major.parse().context("illumos major version is not a number")?;
if major_ver >= 5 {
// SunOS 5 == Solaris 2
os = "solaris".to_string();
release = format!("{}_{}", major_ver - 3, other);
arch = format!("{}_64bit", arch);
machine = format!("{}_64bit", machine);
}
}
}
format!(
"{}_{}_{}",
os,
release,
arch
machine
)
}
// Linux
(Os::Linux, _) => {
let arch = self.get_platform_arch()?;
let mut platform_tags = platform_tags.to_vec();
platform_tags.sort();
let mut tags = vec![];
for platform_tag in platform_tags {
tags.push(format!("{}_{}", platform_tag, arch));
for alias in platform_tag.aliases() {
tags.push(format!("{}_{}", alias, arch));
}
}
tags.join(".")
}
// macOS
(Os::Macos, Arch::X86_64) => {
let ((x86_64_major, x86_64_minor), (arm64_major, arm64_minor)) = macosx_deployment_target(env::var("MACOSX_DEPLOYMENT_TARGET").ok().as_deref(), universal2)?;
if universal2 {
format!(
"macosx_{x86_64_major}_{x86_64_minor}_x86_64.macosx_{arm64_major}_{arm64_minor}_arm64.macosx_{x86_64_major}_{x86_64_minor}_universal2",
x86_64_major = x86_64_major,
x86_64_minor = x86_64_minor,
arm64_major = arm64_major,
arm64_minor = arm64_minor
)
} else {
format!("macosx_{}_{}_x86_64", x86_64_major, x86_64_minor)
}
}
(Os::Macos, Arch::Aarch64) => {
let ((x86_64_major, x86_64_minor), (arm64_major, arm64_minor)) = macosx_deployment_target(env::var("MACOSX_DEPLOYMENT_TARGET").ok().as_deref(), universal2)?;
if universal2 {
format!(
"macosx_{x86_64_major}_{x86_64_minor}_x86_64.macosx_{arm64_major}_{arm64_minor}_arm64.macosx_{x86_64_major}_{x86_64_minor}_universal2",
x86_64_major = x86_64_major,
x86_64_minor = x86_64_minor,
arm64_major = arm64_major,
arm64_minor = arm64_minor
)
} else {
format!("macosx_{}_{}_arm64", arm64_major, arm64_minor)
}
}
// Windows
(Os::Windows, Arch::X86) => "win32".to_string(),
(Os::Windows, Arch::X86_64) => "win_amd64".to_string(),
(Os::Windows, Arch::Aarch64) => "win_arm64".to_string(),
// Emscripten
(Os::Emscripten, Arch::Wasm32) => {
let os_version = env::var("MATURIN_EMSCRIPTEN_VERSION");
let release = match os_version {
Ok(os_ver) => os_ver,
Err(_) => emcc_version()?,
};
let release = release.replace(['.', '-'], "_");
format!("emscripten_{}_wasm32", release)
}
(Os::Wasi, Arch::Wasm32) => {
"any".to_string()
}
(_, _) => panic!("unsupported target should not have reached get_platform_tag()"),
};
Ok(tag)
}
Expand Down
4 changes: 2 additions & 2 deletions test-dockerfile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
set -e

rm -rf venv-docker
python3.8 -m venv venv-docker
python3.11 -m venv venv-docker
venv-docker/bin/pip install -U pip cffi

# FIXME: Can we run the tests without activate? Currently hello-world fails because then the binary is not in PATH
Expand All @@ -14,7 +14,7 @@ source venv-docker/bin/activate
for test_crate in hello-world cffi-pure cffi-mixed pyo3-pure pyo3-mixed pyo3-mixed-submodule
do
echo "Testing $test_crate"
docker run -e RUST_BACKTRACE=1 --rm -v "$(pwd):/io" -w /io/test-crates/$test_crate maturin build -i python3.8
docker run -e RUST_BACKTRACE=1 --rm -v "$(pwd):/io" -w /io/test-crates/$test_crate maturin build -i python3.11
# --only-binary=:all: stops pip from picking a local already compiled sdist
venv-docker/bin/pip install $test_crate --only-binary=:all: --find-links test-crates/$test_crate/target/wheels/
if [[ $(venv-docker/bin/python test-crates/$test_crate/check_installed/check_installed.py) != 'SUCCESS' ]]; then
Expand Down