From 8cda8bcdeaeee0c7ad8a64570a156c7ed8f67489 Mon Sep 17 00:00:00 2001 From: zaniebot <242828183+zaniebot@users.noreply.github.com> Date: Thu, 22 Oct 2026 22:51:06 +0000 Subject: [PATCH] gh-119696: Add CI for relocated shared installations --- .github/workflows/build.yml | 21 +++- .github/workflows/reusable-relocatable.yml | 134 +++++++++++++++++++++ 2 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/reusable-relocatable.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 00d64b3df7e965..a1adcd56fe7b97 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -251,6 +251,22 @@ jobs: if: needs.build-context.outputs.run-ubuntu == 'true' uses: ./.github/workflows/reusable-install.yml + build-ubuntu-relocatable: + name: 'Ubuntu (relocatable)' + needs: build-context + if: needs.build-context.outputs.run-ubuntu == 'true' + uses: ./.github/workflows/reusable-relocatable.yml + with: + os: ubuntu-26.04-arm + + build-macos-relocatable: + name: 'macOS (relocatable)' + needs: build-context + if: needs.build-context.outputs.run-macos == 'true' + uses: ./.github/workflows/reusable-relocatable.yml + with: + os: macos-26 + build-ubuntu-ssltests: name: 'Ubuntu SSL tests' runs-on: ${{ matrix.os }} @@ -651,6 +667,8 @@ jobs: - build-macos - build-ubuntu - build-ubuntu-installed + - build-ubuntu-relocatable + - build-macos-relocatable - build-ubuntu-ssltests - build-ios - build-emscripten @@ -696,12 +714,13 @@ jobs: && 'cifuzz,' || '' }} - ${{ !fromJSON(needs.build-context.outputs.run-macos) && 'build-macos,' || '' }} + ${{ !fromJSON(needs.build-context.outputs.run-macos) && 'build-macos,build-macos-relocatable,' || '' }} ${{ !fromJSON(needs.build-context.outputs.run-ubuntu) && ' build-ubuntu, build-ubuntu-installed, + build-ubuntu-relocatable, build-ubuntu-ssltests, test-hypothesis, build-asan, diff --git a/.github/workflows/reusable-relocatable.yml b/.github/workflows/reusable-relocatable.yml new file mode 100644 index 00000000000000..d031715a3a07ca --- /dev/null +++ b/.github/workflows/reusable-relocatable.yml @@ -0,0 +1,134 @@ +name: Reusable relocatable Python + +on: + workflow_call: + inputs: + os: + type: string + required: true + +permissions: + contents: read + +env: + FORCE_COLOR: 1 + +jobs: + build-install-test: + name: build, relocate and test + runs-on: ${{ inputs.os }} + timeout-minutes: 60 + defaults: + run: + shell: bash + env: + PYTHONSTRICTEXTENSIONBUILD: 1 + HOMEBREW_NO_ANALYTICS: 1 + HOMEBREW_NO_AUTO_UPDATE: 1 + HOMEBREW_NO_INSTALL_CLEANUP: 1 + HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Set build and installation directories + run: | + echo "BUILD_DIR=$RUNNER_TEMP/relocatable-build" >> "$GITHUB_ENV" + echo "INSTALL_DIR=$RUNNER_TEMP/relocatable-install" >> "$GITHUB_ENV" + - name: Install dependencies + if: runner.os == 'Linux' + run: sudo ./.github/workflows/posix-deps-apt.sh + - name: Install Homebrew dependencies + if: runner.os == 'macOS' + run: | + brew bundle --file=Misc/Brewfile + brew install make + echo "GDBM_CFLAGS=-I$(brew --prefix gdbm)/include" >> "$GITHUB_ENV" + echo "GDBM_LIBS=-L$(brew --prefix gdbm)/lib -lgdbm" >> "$GITHUB_ENV" + echo "OPENSSL_DIR=$(brew --prefix openssl@3.5)" >> "$GITHUB_ENV" + - name: Reject unsupported framework relocation + if: runner.os == 'macOS' + run: | + mkdir "$RUNNER_TEMP/framework-configure" + cd "$RUNNER_TEMP/framework-configure" + if "$GITHUB_WORKSPACE/configure" \ + --enable-framework="$RUNNER_TEMP/framework-install" \ + --enable-relocatable --with-openssl="$OPENSSL_DIR" > configure.log 2>&1; then + cat configure.log + exit 1 + fi + cat configure.log + grep -F 'does not support framework builds yet' configure.log + - name: Configure CPython + run: | + mkdir "$BUILD_DIR" + cd "$BUILD_DIR" + configure_args=(--prefix="$INSTALL_DIR" --enable-shared --enable-relocatable) + if [ -n "${OPENSSL_DIR:-}" ]; then + configure_args+=(--with-openssl="$OPENSSL_DIR") + fi + "$GITHUB_WORKSPACE/configure" "${configure_args[@]}" + - name: Build and install CPython + working-directory: ${{ env.BUILD_DIR }} + run: | + make_command="make" + if [ "$RUNNER_OS" = macOS ]; then + make_command="gmake" + fi + "$make_command" -j4 + "$make_command" install + - name: Check build-tree library selection + if: runner.os == 'Linux' + run: | + fixture="$RUNNER_TEMP/library-selection" + mkdir -p "$fixture/build" "$fixture/lib" + cp "$BUILD_DIR/python" "$BUILD_DIR/libpython"*.so.1.0 "$fixture/build/" + cat > "$fixture/wrong-library.c" <<'C' + int Py_BytesMain(int argc, char **argv) { return 79; } + C + library=$(basename "$BUILD_DIR"/libpython*.so.1.0) + cc -shared -fPIC "$fixture/wrong-library.c" \ + -Wl,-soname,"$library" -o "$fixture/lib/$library" + LD_LIBRARY_PATH="$fixture/build" PYTHONHOME="$INSTALL_DIR" \ + "$fixture/build/python" -c 'import sys; print(sys.version)' + - name: Move the installation and build directory + run: | + mv "$INSTALL_DIR" "${INSTALL_DIR} moved" + mv "$BUILD_DIR" "${BUILD_DIR}-unavailable" + echo "INSTALL_DIR=${INSTALL_DIR} moved" >> "$GITHUB_ENV" + - name: Run the relocated interpreter + run: | + unset LD_LIBRARY_PATH LD_PRELOAD + unset DYLD_LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH DYLD_INSERT_LIBRARIES + installed_python="$INSTALL_DIR/bin/python3" + "$installed_python" -I - <<'PY' + import os + import subprocess + import sys + import sysconfig + import tempfile + import venv + + prefix = os.path.realpath(os.environ['INSTALL_DIR']) + assert os.path.realpath(sys.prefix) == prefix, sys.prefix + assert sys.exec_prefix == sys.prefix, sys.exec_prefix + assert sysconfig.get_config_var('RELOCATABLE') == 'yes' + assert not sysconfig.is_python_build() + for entry in sys.path: + assert os.path.commonpath((prefix, os.path.realpath(entry))) == prefix, entry + for symlinks in (False, True): + with tempfile.TemporaryDirectory() as directory: + venv.EnvBuilder(symlinks=symlinks).create(directory) + subprocess.run([ + os.path.join(directory, 'bin', 'python'), '-I', '-c', + 'import ctypes, sys, sysconfig; ' + 'ctypes.CDLL(("@rpath/" if sys.platform == "darwin" else "") + ' + 'sysconfig.get_config_var("INSTSONAME"))', + ], check=True) + PY + "$installed_python" -m test.pythoninfo + if [ "$RUNNER_OS" = Linux ]; then + xvfb-run "$installed_python" -m test --fast-ci --timeout=900 + else + "$installed_python" -m test --fast-ci --timeout=900 + fi