Skip to content

Commit

Permalink
Add Linux powerpc64le & s390x support. (#109)
Browse files Browse the repository at this point in the history
Closes #39

---------

Signed-off-by: John Sirois <john.sirois@gmail.com>
Co-authored-by: Benjy Weinberger <benjyw@gmail.com>
  • Loading branch information
jsirois and benjyw authored Dec 20, 2024
1 parent 36e7d1d commit 0371fbf
Show file tree
Hide file tree
Showing 16 changed files with 91 additions and 24 deletions.
31 changes: 24 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ jobs:
- os: ubuntu-24.04
name: Linux armv7l
docker-platform: linux/arm/v7
- os: ubuntu-24.04
name: Linux s390x
docker-platform: linux/s390x
- os: ubuntu-24.04
name: Linux powerpc64le
docker-platform: linux/ppc64le
- os: macos-13
name: macOS x86-64
- os: macos-14
Expand Down Expand Up @@ -91,17 +97,28 @@ jobs:
- name: Unit Tests
if: matrix.docker-platform != ''
run: |
cat << EOF > _ci_test.sh
set -euo pipefail
if [[ "${{ matrix.docker-platform }}" == "linux/s390x" ]]; then
# This hack gets the PyPy provider tests working on this image. The old PyPy s390x
# distributions dynamically link libffi at an older version than I've been able to
# find a multi-platform image with s390x support for.
ln -s /usr/lib/s390x-linux-gnu/libffi.so.8 /usr/lib/s390x-linux-gnu/libffi.so.6
elif [[ "${{ matrix.docker-platform }}" == "linux/ppc64le" ]]; then
echo "Skipping tests on ppc64le."
exit 0
fi
pip install nox
addgroup --gid $(id -g) build
adduser --disabled-password --gecos '' --gid $(id -g) --uid $(id -u) build
su build -c "nox -e test -- -vvs"
EOF
docker run --rm \
-v $PWD:/code \
-w /code \
--platform ${{ matrix.docker-platform }} \
python:3.12-bookworm \
bash -c "
pip install nox &&
addgroup --gid $(id -g) build &&
adduser --disabled-password --gecos '' --gid $(id -g) --uid $(id -u) build &&
su build -c 'nox -e test -- -vvs'
"
python:3.12-bookworm bash _ci_test.sh
- name: Build & Package
if: matrix.docker-platform == ''
run: nox -e package
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ jobs:
- os: ubuntu-24.04
name: Linux armv7l
docker-platform: linux/arm/v7
- os: ubuntu-24.04
name: Linux s390x
docker-platform: linux/s390x
- os: ubuntu-24.04
name: Linux powerpc64le
docker-platform: linux/ppc64le
- os: macos-13
name: macOS x86-64
- os: macos-14
Expand Down
8 changes: 6 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Release Notes

## 0.10.0

This release adds support for Linux powerpc64le and Linux s390x.

## 0.9.0

This release adds support for Linux ARM (armv7l and armv8l 32 bit mode).
Expand Down Expand Up @@ -45,7 +49,7 @@ release at https://downloads.python.org/pypy/.

Add support to the PythonBuildStandalone interpreter provider for the new `install_only_stripped`
distribution flavor introduced in the [20240726 PBS release](
https://github.com/indygreg/python-build-standalone/releases/tag/20240726) and use this flavor to
https://github.com/astral-sh/python-build-standalone/releases/tag/20240726) and use this flavor to
ship smaller science fat binaries.

## 0.4.3
Expand Down Expand Up @@ -124,4 +128,4 @@ the science binary used to build the scie.

The 1st public release of the project.

[PBS]: https://github.com/indygreg/python-build-standalone/
[PBS]: https://github.com/astral-sh/python-build-standalone/
2 changes: 2 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ function determine_arch() {
aarch64*) echo "aarch64" ;;
armv7l*) echo "armv7l" ;;
armv8l*) echo "armv7l" ;;
s390x*) echo "s390x" ;;
ppc64le*) echo "powerpc64" ;;
*) die "unknown arch: ${read_arch}" ;;
esac
}
Expand Down
8 changes: 7 additions & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ def current(cls) -> OperatingSystem:
else platform.machine().lower()
) in ("aarch64", "arm64")
IS_ARMV7L = platform.machine().lower() in ("armv7l", "armv8l")
IS_S390X = platform.machine().lower() == "s390x"
IS_POWERPC64LE = platform.machine().lower() == "ppc64le"


def check_lift_manifest(session: Session):
Expand Down Expand Up @@ -259,7 +261,7 @@ def ensure_PBS_python_dist(target_triple: str) -> PurePath:
pbs_root = BUILD_ROOT / ".nox" / "PBS" / PBS_RELEASE / PBS_VERSION / PBS_FLAVOR
if not pbs_root.exists():
url = (
"https://github.com/indygreg/python-build-standalone/releases/download/"
"https://github.com/astral-sh/python-build-standalone/releases/download/"
f"{PBS_RELEASE}/"
f"cpython-{PBS_VERSION}+{PBS_RELEASE}-{target_triple}-{PBS_FLAVOR}.tar.gz"
)
Expand Down Expand Up @@ -299,6 +301,10 @@ def nox_session() -> Callable[[Callable[[Session], T]], Callable[[Session], T]]:
target_triple = "aarch64-unknown-linux-gnu"
elif IS_ARMV7L:
target_triple = "armv7-unknown-linux-gnueabihf"
elif IS_S390X:
target_triple = "s390x-unknown-linux-gnu"
elif IS_POWERPC64LE:
target_triple = "ppc64le-unknown-linux-gnu"
else:
target_triple = "x86_64-unknown-linux-gnu"
elif OperatingSystem.MAC is OS:
Expand Down
2 changes: 1 addition & 1 deletion science/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@

from packaging.version import Version

__version__ = "0.9.0"
__version__ = "0.10.0"

VERSION = Version(__version__)
9 changes: 5 additions & 4 deletions science/commands/complete.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ class Shell(Enum):
@cache
def current(cls) -> Self | None:
known_shells = tuple(shell.value for shell in cls)
process = psutil.Process()
while process := process.parent():
if (exe := process.name().rstrip(EXE_EXT).lower()) in known_shells:
return cls(exe)
process: psutil.Process | None = psutil.Process()
if process:
while process and (process := process.parent()):
if (exe := process.name().rstrip(EXE_EXT).lower()) in known_shells:
return cls(exe)
return None

Bash = "bash"
Expand Down
6 changes: 6 additions & 0 deletions science/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
class Platform(Enum):
Linux_aarch64 = "linux-aarch64"
Linux_armv7l = "linux-armv7l"
Linux_powerpc64le = "linux-powerpc64"
Linux_s390x = "linux-s390x"
Linux_x86_64 = "linux-x86_64"
Macos_aarch64 = "macos-aarch64"
Macos_x86_64 = "macos-x86_64"
Expand All @@ -36,6 +38,10 @@ def current(cls) -> Platform:
return cls.Linux_aarch64
case ("linux", "armv7l" | "armv8l"):
return cls.Linux_armv7l
case ("linux", "ppc64le"):
return cls.Linux_powerpc64le
case ("linux", "s390x"):
return cls.Linux_s390x
case ("linux", "amd64" | "x86_64"):
return cls.Linux_x86_64
case ("darwin", "aarch64" | "arm64"):
Expand Down
4 changes: 4 additions & 0 deletions science/providers/pypy.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ class PyPy(Provider[Config]):
@staticmethod
def rank_compatibility(platform: Platform, arch: str) -> int | None:
match platform:
case Platform.Linux_s390x:
match arch:
case "s390x":
return 0
case Platform.Linux_aarch64:
match arch:
case "aarch64-portable":
Expand Down
16 changes: 12 additions & 4 deletions science/providers/python_build_standalone.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class Config:
```{caution}
Python Standalone Builds does not provide all patch versions; so you should check
[their releases](https://github.com/indygreg/python-build-standalone/releases) if you
[their releases](https://github.com/astral-sh/python-build-standalone/releases) if you
wish to pin down to the patch level.
```
"""
Expand All @@ -83,7 +83,7 @@ class Config:
the cache at `{download_cache().base_dir}`.
```
[releases-page]: https://github.com/indygreg/python-build-standalone/releases
[releases-page]: https://github.com/astral-sh/python-build-standalone/releases
"""
),
)
Expand Down Expand Up @@ -141,7 +141,7 @@ class PythonBuildStandalone(Provider[Config]):
partially applied OpenSSL config. This may have security implications for your application.
For more on this see:
https://github.com/indygreg/python-build-standalone/issues/207#issuecomment-1936500903
https://github.com/astral-sh/python-build-standalone/issues/207
```
[PBS]: https://gregoryszorc.com/docs/python-build-standalone/main
Expand All @@ -161,6 +161,14 @@ def rank_compatibility(platform: Platform, target_triple: str) -> int | None:
return 0
case "armv7-unknown-linux-gnueabi":
return 1
case Platform.Linux_powerpc64le:
match target_triple:
case "ppc64le-unknown-linux-gnu":
return 0
case Platform.Linux_s390x:
match target_triple:
case "s390x-unknown-linux-gnu":
return 0
case Platform.Linux_x86_64:
match target_triple:
case "x86_64-unknown-linux-gnu":
Expand All @@ -184,7 +192,7 @@ def rank_compatibility(platform: Platform, target_triple: str) -> int | None:
case Platform.Windows_aarch64 | Platform.Windows_x86_64:
match target_triple:
# N.B.: The -shared tag was removed in
# https://github.com/indygreg/python-build-standalone/releases/tag/20240415
# https://github.com/astral-sh/python-build-standalone/releases/tag/20240415
# but the archive is still dynamically linked.
case "x86_64-pc-windows-msvc" | "x86_64-pc-windows-msvc-shared":
return 0
Expand Down
2 changes: 1 addition & 1 deletion tests/data/interpreter-groups.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "igs"
description = "Test interpreter group selection."

[lift.scie_jump]
version = "1.4.1"
version = "1.5.0"

[[lift.interpreters]]
id = "cpython310"
Expand Down
2 changes: 1 addition & 1 deletion tests/data/unrecognized-config-fields.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ version = "0.11.0"

[lift.scie_jump]
# N.B: `version2` is invalid, should be `version`.
version2 = "1.4.1"
version2 = "1.5.0"

[[lift.interpreters]]
id = "cpython310"
Expand Down
4 changes: 2 additions & 2 deletions tests/test_a_scie.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ def test_ptex_latest(tmp_path_factory: TempPathFactory) -> None:

def test_ptex_version(tmp_path_factory: TempPathFactory) -> None:
dest_dir = tmp_path_factory.mktemp("staging")
latest = a_scie.ptex(dest_dir=dest_dir, specification=Ptex(version=version.parse("1.4.0")))
latest = a_scie.ptex(dest_dir=dest_dir, specification=Ptex(version=version.parse("1.5.0")))
assert (
"1.4.0"
"1.5.0"
== subprocess.run(
args=[str(dest_dir / latest.name), "-V"], stdout=subprocess.PIPE, text=True, check=True
).stdout.strip()
Expand Down
4 changes: 4 additions & 0 deletions tests/test_exe.py
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,10 @@ def test_invert_lazy_non_lazy(tmp_path: Path, science_exe: Path) -> None:

def working_pypy_versions() -> list[str]:
match Platform.current():
case Platform.Linux_s390x:
return ["2.7", "3.8", "3.9", "3.10"]
case Platform.Linux_powerpc64le:
return []
case Platform.Linux_armv7l:
return []
case Platform.Macos_aarch64:
Expand Down
9 changes: 9 additions & 0 deletions tests/test_installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from _pytest.tmpdir import TempPathFactory

from science.os import IS_WINDOWS
from science.platform import Platform


@pytest.fixture(scope="module")
Expand All @@ -30,6 +31,13 @@ def test_installer_help(installer: list):
assert long_help in result.stdout, f"Expected '{long_help}' in tool output"


skip_ppc64le_and_s390x = pytest.mark.skipif(
Platform.current() in (Platform.Linux_powerpc64le, Platform.Linux_s390x),
reason="Requires a release after 0.9.0 containing ppc64le and s390x support.",
)


@skip_ppc64le_and_s390x
def test_installer_fetch_latest(tmp_path_factory: TempPathFactory, installer: list):
"""Invokes install.sh to fetch the latest science release binary, then invokes it."""
test_dir = tmp_path_factory.mktemp("install-test-default")
Expand All @@ -44,6 +52,7 @@ def test_installer_fetch_latest(tmp_path_factory: TempPathFactory, installer: li
assert result.stdout.strip(), "Expected version output in tool stdout"


@skip_ppc64le_and_s390x
def test_installer_fetch_argtest(tmp_path_factory: TempPathFactory, installer: list):
"""Exercises all the options in the installer."""
test_dir = tmp_path_factory.mktemp("install-test")
Expand Down
2 changes: 1 addition & 1 deletion tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def test_distribution() -> None:
),
source=Fetch(
url=Url(
"https://github.com/indygreg/python-build-standalone/releases/download/"
"https://github.com/astral-sh/python-build-standalone/releases/download/"
"20221220/"
"cpython-3.10.9%2B20221220-x86_64-unknown-linux-gnu-install_only.tar.gz"
)
Expand Down

0 comments on commit 0371fbf

Please sign in to comment.