diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2395559..8e8f9a3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -62,9 +62,10 @@ jobs: - py310 - py311 - py312 + - py313 include: - type: roborio - pyversion: py312 + pyversion: py313 steps: - uses: actions/checkout@v4 diff --git a/cross-ubuntu-py/Dockerfile.py313 b/cross-ubuntu-py/Dockerfile.py313 new file mode 100644 index 0000000..5f98163 --- /dev/null +++ b/cross-ubuntu-py/Dockerfile.py313 @@ -0,0 +1,104 @@ + +ARG UBUNTU=22.04 +ARG ARCH=invalid-arch +ARG VERSION=invalid-version + +FROM wpilib/${ARCH}-cross-ubuntu-minimal:${VERSION}-${UBUNTU} AS pycompile + +ARG TARGET_HOST=invalid-target-host +ARG AC_TARGET_HOST=invalid-ac-target-host + +ENV TARGET_HOST=${TARGET_HOST} +ENV AC_TARGET_HOST=${AC_TARGET_HOST} +ENV BUILD_HOST="x86_64" +ENV WORKING_DIRECTORY="/build" +ENV INSTALL_DIRECTORY="/build/crosspy" +ENV PYTHON_VERSION="3.13.0" +ENV PYTHON_FTP_VERSION="3.13.0" +ENV PYTHON_EXE="python3.13" +ENV SOURCE_DIRECTORY="Python-$PYTHON_VERSION" +ENV PYTHON_ARCHIVE="Python-$PYTHON_VERSION.tar.xz" +ENV PREFIX="$INSTALL_DIRECTORY" + +# +# Python compilation prereqs +# + +RUN set -xe; \ + apt-get update; \ + apt-get install -y build-essential checkinstall g++ libreadline-dev libncursesw5-dev libssl-dev \ + libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev liblzma-dev lzma-dev libffi-dev zlib1g-dev; \ + # cleanup + rm -rf /var/lib/apt/lists/* + +# +# Python cross-compilation +# + +RUN set -xe; \ + mkdir -p "$PREFIX"; \ + # Download + cd $WORKING_DIRECTORY; \ + wget -c https://www.python.org/ftp/python/$PYTHON_FTP_VERSION/$PYTHON_ARCHIVE; \ + rm -rf $SOURCE_DIRECTORY; \ + tar -xf $PYTHON_ARCHIVE; \ + cd $SOURCE_DIRECTORY; \ + # Build python for host + cd $WORKING_DIRECTORY;cd $SOURCE_DIRECTORY; \ + ./configure --enable-optimizations --with-ensurepip=install; \ + make -j; \ + make -j altinstall + +RUN set -xe; \ + # Remove build dependencies -- compilation uses host for some reason + apt-get remove -y libreadline-dev libncursesw5-dev libssl-dev \ + libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev liblzma-dev lzma-dev libffi-dev zlib1g-dev; \ + apt-get autoremove -y; + +RUN set -xe; \ + # cross-compile + cd $WORKING_DIRECTORY;cd $SOURCE_DIRECTORY; make distclean; \ + ./configure --host=$TARGET_HOST --build=$BUILD_HOST --prefix=$PREFIX \ + --with-build-python=$(which $PYTHON_EXE) \ + --disable-ipv6 \ + ac_cv_host=$AC_TARGET_HOST \ + ac_cv_buggy_getaddrinfo=no \ + ac_cv_file__dev_ptmx=no ac_cv_file__dev_ptc=no \ + ac_cv_have_long_long_format=yes \ + ac_cv_pthread_is_default=no ac_cv_pthread=yes ac_cv_cxx_thread=yes; \ + make -j; \ + # make install here is fine because we include --prefix in the configure statement + make install + + +# +# Minimal cross-compilation environment +# + +FROM wpilib/${ARCH}-cross-ubuntu-minimal:${VERSION}-${UBUNTU} AS crossenv + +RUN set -xe; \ + apt-get update; \ + apt-get install -y \ + binutils libreadline8 libncursesw5 libssl3 \ + libsqlite3-0 libgdbm6 libbz2-1.0 liblzma5 libffi7 zlib1g; \ + rm -rf /var/lib/apt/lists/* + +COPY --from=pycompile /usr/local /usr/local +COPY --from=pycompile /build/crosspy /build/crosspy + +ARG ARCH=invalid-arch +ARG TARGET_HOST=invalid-target-host +ARG MACHINE_ARG= + +RUN set -xe; \ + ldconfig; \ + python3.13 -m pip install 'crossenv~=1.5.0'; \ + python3.13 -m crossenv /build/crosspy/bin/python3.13 /build/venv ${MACHINE_ARG} --sysroot=$(${TARGET_HOST}-gcc -print-sysroot) --env UNIXCONFDIR=/build/venv/cross/etc; \ + /build/venv/bin/cross-pip install wheel; + +COPY pip-${ARCH}.conf /build/venv/cross/pip.conf +COPY os-release-${ARCH} /build/venv/cross/etc/os-release + +ENV RPYBUILD_PARALLEL=1 + diff --git a/cross-ubuntu-py/os-release-roborio b/cross-ubuntu-py/os-release-roborio index 3a38a4c..fcae265 100644 --- a/cross-ubuntu-py/os-release-roborio +++ b/cross-ubuntu-py/os-release-roborio @@ -1,5 +1,5 @@ ID="nilrt-academic" NAME="NI Linux Real-Time - Academic" -VERSION="8.14" -VERSION_ID="8.14" -PRETTY_NAME="NI Linux Real-Time - Academic 8.14" \ No newline at end of file +VERSION="8.15" +VERSION_ID="8.15" +PRETTY_NAME="NI Linux Real-Time - Academic 8.15" \ No newline at end of file diff --git a/cross-ubuntu-py/pip-aarch64.conf b/cross-ubuntu-py/pip-aarch64.conf index 7f04e29..bc215ac 100644 --- a/cross-ubuntu-py/pip-aarch64.conf +++ b/cross-ubuntu-py/pip-aarch64.conf @@ -1,3 +1,3 @@ [global] -extra-index-url = https://wpilib.jfrog.io/artifactory/api/pypi/wpilib-python-release-2024/simple +extra-index-url = https://wpilib.jfrog.io/artifactory/api/pypi/wpilib-python-release-2025/simple diff --git a/cross-ubuntu-py/pip-raspbian.conf b/cross-ubuntu-py/pip-raspbian.conf index 7f96c46..0383ef7 100644 --- a/cross-ubuntu-py/pip-raspbian.conf +++ b/cross-ubuntu-py/pip-raspbian.conf @@ -1,5 +1,5 @@ [global] extra-index-url = - https://wpilib.jfrog.io/artifactory/api/pypi/wpilib-python-release-2024/simple + https://wpilib.jfrog.io/artifactory/api/pypi/wpilib-python-release-2025/simple https://www.piwheels.org/simple \ No newline at end of file diff --git a/cross-ubuntu-py/pip-roborio.conf b/cross-ubuntu-py/pip-roborio.conf index 7f04e29..bc215ac 100644 --- a/cross-ubuntu-py/pip-roborio.conf +++ b/cross-ubuntu-py/pip-roborio.conf @@ -1,3 +1,3 @@ [global] -extra-index-url = https://wpilib.jfrog.io/artifactory/api/pypi/wpilib-python-release-2024/simple +extra-index-url = https://wpilib.jfrog.io/artifactory/api/pypi/wpilib-python-release-2025/simple diff --git a/cross-ubuntu-py/py.mk b/cross-ubuntu-py/py.mk index d0b910a..2422ff9 100644 --- a/cross-ubuntu-py/py.mk +++ b/cross-ubuntu-py/py.mk @@ -15,15 +15,17 @@ AC_TARGET_HOST_AARCH64=aarch64-bullseye-linux-gnu TYPE_ROBORIO=roborio VERSION_ROBORIO=$(YEAR) +VERSION_ROBORIO_BASE=2024 TARGET_HOST_ROBORIO=arm-frc2024-linux-gnueabi AC_TARGET_HOST_ROBORIO=armv7l-frc2024-linux-gnueabi .PHONY: build/cross-python -build/cross-python: build/cross-raspbian-py39 build/cross-aarch64-py39 build/cross-raspbian-py310 build/cross-aarch64-py310 build/cross-raspbian-py311 build/cross-aarch64-py311 build/cross-roborio-py312 build/cross-raspbian-py312 build/cross-aarch64-py312 +build/cross-python: build/cross-raspbian-py39 build/cross-aarch64-py39 build/cross-raspbian-py310 build/cross-aarch64-py310 build/cross-raspbian-py311 build/cross-aarch64-py311 build/cross-raspbian-py312 build/cross-aarch64-py312 build/cross-roborio-py313 build/cross-raspbian-py313 build/cross-aarch64-py313 + .PHONY: push/cross-python -push/cross-python: push/cross-raspbian-py39 push/cross-aarch64-py39 push/cross-raspbian-py310 push/cross-aarch64-py310 push/cross-raspbian-py311 push/cross-aarch64-py311 push/cross-roborio-py312 push/cross-raspbian-py312 push/cross-aarch64-py312 +push/cross-python: push/cross-raspbian-py39 push/cross-aarch64-py39 push/cross-raspbian-py310 push/cross-aarch64-py310 push/cross-raspbian-py311 push/cross-aarch64-py311 push/cross-raspbian-py312 push/cross-aarch64-py312 push/cross-roborio-py313 push/cross-raspbian-py313 push/cross-aarch64-py313 # @@ -187,3 +189,58 @@ build/cross-aarch64-py312: .PHONY: push/cross-aarch64-py312 push/cross-aarch64-py312: docker push wpilib/$(TYPE_AARCH64)-cross-ubuntu:$(VERSION_AARCH64)-$(UBUNTU)-py312 + + + +# +# Python 3.13 +# + +.PHONY: build/cross-raspbian-py313 +build/cross-raspbian-py313: + cd cross-ubuntu-py && \ + docker build . \ + -t wpilib/$(TYPE_RASPBIAN)-cross-ubuntu:$(VERSION_RASPBIAN)-$(UBUNTU)-py313 \ + --build-arg ARCH=$(TYPE_RASPBIAN) \ + --build-arg TARGET_HOST=$(TARGET_HOST_RASPBIAN) \ + --build-arg AC_TARGET_HOST=$(AC_TARGET_HOST_RASPBIAN) \ + --build-arg VERSION=$(VERSION_RASPBIAN) \ + -f Dockerfile.py313 + +.PHONY: push/cross-raspbian-py313 +push/cross-raspbian-py313: + docker push wpilib/$(TYPE_RASPBIAN)-cross-ubuntu:$(VERSION_RASPBIAN)-$(UBUNTU)-py313 + + +.PHONY: build/cross-roborio-py313 +build/cross-roborio-py313: + cd cross-ubuntu-py && \ + docker build . \ + -t wpilib/$(TYPE_ROBORIO)-cross-ubuntu:$(VERSION_ROBORIO)-$(UBUNTU)-py313 \ + --build-arg ARCH=$(TYPE_ROBORIO) \ + --build-arg TARGET_HOST=$(TARGET_HOST_ROBORIO) \ + --build-arg AC_TARGET_HOST=$(AC_TARGET_HOST_ROBORIO) \ + --build-arg VERSION=$(VERSION_ROBORIO_BASE) \ + --build-arg MACHINE_ARG="--machine=roborio" \ + -f Dockerfile.py313 + +.PHONY: push/cross-roborio-py313 +push/cross-roborio-py313: + docker push wpilib/$(TYPE_ROBORIO)-cross-ubuntu:$(VERSION_ROBORIO)-$(UBUNTU)-py313 + + + +.PHONY: build/cross-aarch64-py313 +build/cross-aarch64-py313: + cd cross-ubuntu-py && \ + docker build . \ + -t wpilib/$(TYPE_AARCH64)-cross-ubuntu:$(VERSION_AARCH64)-$(UBUNTU)-py313 \ + --build-arg ARCH=$(TYPE_AARCH64) \ + --build-arg TARGET_HOST=$(TARGET_HOST_AARCH64) \ + --build-arg AC_TARGET_HOST=$(AC_TARGET_HOST_AARCH64) \ + --build-arg VERSION=$(VERSION_AARCH64) \ + -f Dockerfile.py313 + +.PHONY: push/cross-aarch64-py313 +push/cross-aarch64-py313: + docker push wpilib/$(TYPE_AARCH64)-cross-ubuntu:$(VERSION_AARCH64)-$(UBUNTU)-py313