diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 91fa15874..ca0be16b5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -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' diff --git a/Dockerfile b/Dockerfile index 52a2cbed0..2b8b83b2a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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 diff --git a/src/target.rs b/src/target.rs index 8263af92a..5263f8538 100644 --- a/src/target.rs +++ b/src/target.rs @@ -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 { match os { @@ -117,18 +140,31 @@ fn get_supported_architectures(os: &Os) -> Vec { ], 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], @@ -235,41 +271,53 @@ impl Target { universal2: bool, ) -> Result { 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 @@ -284,24 +332,36 @@ 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); } } } @@ -309,70 +369,9 @@ impl Target { "{}_{}_{}", 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) } diff --git a/test-dockerfile.sh b/test-dockerfile.sh index 65b1b1c95..b0d79780d 100755 --- a/test-dockerfile.sh +++ b/test-dockerfile.sh @@ -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 @@ -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