From 7f3e7666c0b8e98648aa15e6113e33ceb2c1545c Mon Sep 17 00:00:00 2001 From: Maxime David Date: Mon, 17 Aug 2026 20:55:41 +0000 Subject: [PATCH] fix: build static library as position-independent code --- .github/workflows/tests.yml | 38 ++++++++++++++++++++++++++++ CMakeLists.txt | 6 ++++- ci/integ/docker/Dockerfile.oci-smoke | 7 +++++ ci/integ/pic-check.sh | 21 +++++++++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) create mode 100755 ci/integ/pic-check.sh diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 69e33ee..1f8ca27 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -59,6 +59,44 @@ jobs: shell: bash run: ./ci/integ/unit-test.sh ${{ matrix.os }} + pic-check: + runs-on: ${{ matrix.runner }} + timeout-minutes: 10 + container: ${{ matrix.container }} + strategy: + fail-fast: false + matrix: + include: + - os: al2023 + container: public.ecr.aws/amazonlinux/amazonlinux:2023 + runner: ubuntu-latest + - os: al2023-arm + container: public.ecr.aws/amazonlinux/amazonlinux:2023 + runner: ubuntu-24.04-arm + - os: alpine + container: public.ecr.aws/docker/library/alpine:3.23 + runner: ubuntu-latest + + steps: + - name: Install checkout prerequisites + shell: sh + run: | + if command -v dnf > /dev/null 2>&1; then + dnf install -y tar gzip git + elif command -v apk > /dev/null 2>&1; then + apk add --no-cache bash tar git + fi + + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + + - name: Install dependencies + shell: bash + run: ./ci/integ/install-deps.sh ${{ matrix.os }} + + - name: Position-independence check + shell: bash + run: ./ci/integ/pic-check.sh ${{ matrix.os }} + integration-test-oci: runs-on: ${{ matrix.build.runner }} timeout-minutes: 10 diff --git a/CMakeLists.txt b/CMakeLists.txt index abdcb82..f418da1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,11 @@ add_library(${PROJECT_NAME} set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION 0 - VERSION ${PROJECT_VERSION}-dev) + VERSION ${PROJECT_VERSION}-dev + # Emit position-independent code so the static archive can be linked into a + # shared object (e.g. the Java runtime interface client's JNI .so). + # PIC links fine into executables too, so this is safe for all consumers. + POSITION_INDEPENDENT_CODE ON) target_include_directories(${PROJECT_NAME} PUBLIC $ diff --git a/ci/integ/docker/Dockerfile.oci-smoke b/ci/integ/docker/Dockerfile.oci-smoke index d64048c..d217d63 100644 --- a/ci/integ/docker/Dockerfile.oci-smoke +++ b/ci/integ/docker/Dockerfile.oci-smoke @@ -13,6 +13,13 @@ COPY main.cpp main.cpp RUN g++ -std=c++11 -O2 -Iinclude main.cpp runtime.a -lcurl -pthread -o bootstrap +# Position-independence guard. The link above only proves the archive works in a +# position-dependent executable; it stays green even for a non-PIC build. But +# downstream consumers embed this .a in a shared object -- e.g. the Java runtime +# interface client's JNI .so +RUN g++ -shared -Wl,--whole-archive runtime.a -Wl,--no-whole-archive \ + -lcurl -pthread -o /build/libaws-lambda-runtime-pic-check.so + FROM public.ecr.aws/lambda/provided:al2023 COPY --from=builder /build/bootstrap ${LAMBDA_RUNTIME_DIR}/bootstrap diff --git a/ci/integ/pic-check.sh b/ci/integ/pic-check.sh new file mode 100755 index 0000000..14ac2ce --- /dev/null +++ b/ci/integ/pic-check.sh @@ -0,0 +1,21 @@ +#!/bin/bash +set -euo pipefail + +OS=${1:-} + +case "$OS" in + ubuntu|arch) + export CC=/usr/bin/clang CXX=/usr/bin/clang++ + ;; +esac + +BUILD_DIR=build-pic-check +cmake -B "$BUILD_DIR" -GNinja -DCMAKE_BUILD_TYPE=Release +cmake --build "$BUILD_DIR" + +"${CXX:-c++}" -shared \ + -Wl,--whole-archive "$BUILD_DIR/libaws-lambda-runtime.a" -Wl,--no-whole-archive \ + -lcurl -pthread \ + -o "$BUILD_DIR/libaws-lambda-runtime-pic-check.so" + +echo "PIC check passed: static archive links into a shared object"