Fix "bad slide" on 32-bit ARM shared library #2543
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Copyright (C) Markus Franz Xaver Johannes Oberhumer | |
| # note: GitHub Actions runner images are frequently updated, and | |
| # unfortunately this sometimes breaks builds in mysterious ways... | |
| # see https://github.com/actions/runner-images.git | |
| name: CI | |
| on: [push, workflow_dispatch] | |
| defaults: { run: { shell: bash } } | |
| env: | |
| CMAKE_REQUIRED_QUIET: 'OFF' | |
| CMAKE_VERBOSE_MAKEFILE: 'ON' | |
| CTEST_OUTPUT_ON_FAILURE: 'ON' | |
| DEBIAN_FRONTEND: noninteractive | |
| NO_COLOR: 1 | |
| UPX_CMAKE_BUILD_FLAGS: --verbose | |
| UPX_CMAKE_CONFIG_FLAGS: -Wdev --warn-uninitialized | |
| UPX_CONFIG_HAVE_WORKING_BUILD_RPATH: 'ON' | |
| UPX_DEBUG_TEST_FLOAT_DIVISION_BY_ZERO: 1 | |
| UPX_DEBUG_TEST_LIBC_QSORT: 1 | |
| ZSTD_CLEVEL: 17 | |
| # 2025-10-11 | |
| ZIG_DIST_VERSION: 0.15.2 | |
| jobs: | |
| job-rebuild-and-verify-stubs: | |
| name: Rebuild stubs | |
| runs-on: ubuntu-latest | |
| container: ubuntu:24.04 # provides glibc-2.39 | |
| #container: debian:12-slim # also works; provides glibc-2.36 | |
| #container: debian:testing-slim # also works; currently provides glibc-2.38 | |
| steps: | |
| - run: uname -a; pwd; id; umask | |
| - name: Install packages | |
| run: | | |
| dpkg --add-architecture i386 | |
| apt-get update && apt-get upgrade -y | |
| # install system packages | |
| apt-get install -y --no-install-recommends bash ca-certificates curl git libmpc3 make perl-base python3-minimal tar time xz-utils libc6:i386 zlib1g:i386 | |
| apt-get install -y gcc-riscv64-linux-gnu | |
| mkdir ../deps; cd ../deps; mkdir packages | |
| ### install python2-minimal packages from Debian-11 | |
| ## curl -sS -L -O https://ftp.debian.org/debian/pool/main/p/python2.7/libpython2.7-minimal_2.7.18-8+deb11u1_amd64.deb | |
| ## curl -sS -L -O https://ftp.debian.org/debian/pool/main/p/python2.7/python2.7-minimal_2.7.18-8+deb11u1_amd64.deb | |
| ## dpkg -i ./*python2*.deb && rm ./*python2*.deb && ldconfig | |
| ## ln -s -v python2.7 /usr/bin/python2 | |
| # manually unpack and install compat libs from Ubuntu-16.04 | |
| curl -sS -L -O https://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb | |
| for f in ./*.deb; do dpkg -x $f ./packages; done | |
| mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/ | |
| rm -rf ./*.deb ./packages && ldconfig | |
| # install upx-stubtools | |
| curl -sS -L https://github.com/upx/upx-stubtools/releases/download/v20221212/bin-upx-20221212.tar.xz | tar -xJ | |
| - run: dpkg -l | |
| - name: Check out code | |
| run: | | |
| git config --global --add safe.directory '*' # needed when running in a container | |
| git clone --branch "$GITHUB_REF_NAME" --depth 1 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" . | |
| git submodule update --init -- vendor/lzma-sdk | |
| git fsck --strict --no-progress | |
| - name: Rebuild and verify stubs | |
| run: | | |
| export PATH="$(readlink -en ../deps/bin-upx-20221212):$PATH" | |
| make -C src/stub maintainer-clean extra-clean | |
| git status || true # make sure the stub files got deleted | |
| make -C src/stub extra-all all | |
| if ! git diff --quiet; then git diff; exit 1; fi | |
| - run: bash ./misc/scripts/check_whitespace_git.sh | |
| - name: Check source code formatting | |
| run: | | |
| export UPX_CLANG_FORMAT="$(readlink -en ../deps/bin-upx-20221212/clang-format-15.0.6)" | |
| make -C src clang-format | |
| if ! git diff --quiet; then git diff; exit 1; fi | |
| - name: Rebuild docs | |
| run: | | |
| make -C doc clean all | |
| if ! git diff --quiet; then git diff || true; fi # ignore diff error | |
| - name: Clean up | |
| run: | | |
| git ls-files -z --others --ignored --exclude-standard ./src/stub | xargs -0r rm -v -- | |
| find ./src/stub/src -type d -name tmp -print0 | xargs -0r rmdir -v -- | |
| - run: git status --ignored || true | |
| job-linux-cmake-0: # uses cmake + make | |
| if: true | |
| needs: [ job-rebuild-and-verify-stubs ] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { os: ubuntu-22.04 } | |
| - { os: ubuntu-24.04 } | |
| - { os: ubuntu-22.04-arm } | |
| - { os: ubuntu-24.04-arm } | |
| name: ${{ format('{0}', matrix.os) }}-0 | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - run: uname -a; pwd; id; umask | |
| - run: sudo apt-get update | |
| - run: sudo apt-get install -y dmidecode gdb parallel valgrind | |
| - run: (sudo dmidecode | sed -n -e '/System Information/,/^$/p') || true | |
| - run: sudo dmidecode -q || true | |
| - run: sudo dmidecode || true | |
| - uses: actions/checkout@v6 | |
| with: { submodules: true } | |
| - run: make build/extra/gcc/all | |
| - run: make build/extra/clang/all | |
| - run: ls -l build/*/*/*/upx* || true | |
| - run: file build/*/*/*/upx* || true | |
| - name: Make artifact | |
| run: | | |
| N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}-0" | sed 's/[^0-9a-zA-Z_.-]/-/g') | |
| mkdir -p "tmp/artifact/$N" | |
| (cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N") | |
| if command -v hardlink >/dev/null; then (cd "tmp/artifact/$N" && hardlink .) fi | |
| (cd tmp/artifact && tar --sort=name --zstd -cf "$N.tar.zst" "$N" && rm -rf "./$N" && ls -la && zstd -tq "$N.tar.zst") | |
| echo "artifact_name=$N" >> $GITHUB_ENV | |
| - name: ${{ format('Upload artifact {0}', env.artifact_name) }} | |
| uses: actions/upload-artifact@v5 | |
| with: { name: '${{ env.artifact_name }}', path: tmp/artifact } | |
| - name: Run install tests | |
| run: | | |
| jobs="gcc/debug gcc/release clang/debug clang/release" | |
| echo "===== parallel jobs: $jobs" | |
| DESTDIR="Install with make 2" parallel -kv --lb 'make build/extra/{}+install' ::: $jobs | |
| - name: Mimic ctest tests SIGSEGV | |
| run: | | |
| jobs="gcc/debug gcc/release clang/debug clang/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest_sigsegv.sh' ::: $jobs | |
| ls -ld ./build/*/*/*/upx-* || true | |
| rm -rf ./build/*/*/*/upx-* | |
| - name: Run ctest tests | |
| run: | | |
| jobs="gcc/debug gcc/release clang/debug clang/release" | |
| echo "===== parallel jobs: $jobs" | |
| CTEST_JOBS=2 parallel -kv --lb 'make build/extra/{}+test' ::: $jobs | |
| ls -ld ./build/*/*/*/XTesting/*/* || true | |
| rm -rf ./build/*/*/*/XTesting/*/* | |
| - name: Mimic ctest tests with Valgrind | |
| run: | | |
| export UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS=ON # valgrind is SLOW | |
| export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet --gen-suppressions=all" | |
| # clang/debug does not work before valgrind-3.20, see https://bugs.kde.org/show_bug.cgi?id=452758 | |
| jobs="gcc/debug gcc/release clang/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs | |
| ls -ld ./build/*/*/*/upx-* || true | |
| rm -rf ./build/*/*/*/upx-* | |
| job-linux-cmake: # uses cmake + make | |
| if: true | |
| needs: [ job-rebuild-and-verify-stubs ] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { os: ubuntu-22.04, use_extra: true } | |
| - { os: ubuntu-24.04, use_extra: true, use_wine: true } | |
| name: ${{ format('{0}', matrix.os) }} | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - run: uname -a; pwd; id; umask | |
| - name: Install extra 32-bit and MinGW packages | |
| if: ${{ matrix.use_extra }} | |
| run: | | |
| sudo dpkg --add-architecture i386 | |
| sudo apt-get update && sudo apt-get upgrade -y | |
| sudo apt-get install -y dmidecode gdb libc6-dbg:i386 parallel valgrind | |
| sudo apt-get install -y g++-multilib g++-mingw-w64-i686 g++-mingw-w64-x86-64 | |
| # make sure that we use posix-threads (pthread/winpthreads) and NOT win32-threads | |
| for f in i686-w64-mingw32-g++ i686-w64-mingw32-gcc x86_64-w64-mingw32-g++ x86_64-w64-mingw32-gcc; do | |
| if test -f /usr/bin/$f-posix; then sudo update-alternatives --set $f /usr/bin/$f-posix; fi | |
| ls -l /usr/bin/${f}* | |
| done | |
| ls -l /etc/alternatives/*mingw* || true | |
| - run: (sudo dmidecode | sed -n -e '/System Information/,/^$/p') || true | |
| if: ${{ matrix.use_extra }} | |
| - run: sudo dmidecode -q || true | |
| if: ${{ matrix.use_extra }} | |
| - run: sudo dmidecode || true | |
| if: ${{ matrix.use_extra }} | |
| - name: Install Wine | |
| if: ${{ matrix.use_extra && matrix.use_wine }} | |
| run: | | |
| sudo apt-get install -y wine wine32:i386 wine64 | |
| ls -l /usr/bin/wine* | |
| mkdir -p -v ~/.wine && wineboot --init | |
| - uses: actions/checkout@v6 | |
| with: { submodules: true } | |
| - name: Check out test suite | |
| run: git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite | |
| - run: set -x; clang --version; clang++ --version | |
| - run: set -x; gcc --version; g++ --version | |
| - run: clang -E -x c -dM /dev/null # list predefined macros for C | |
| - run: clang++ -E -x c++ -dM /dev/null # list predefined macros for C++ | |
| - run: gcc -E -x c -dM /dev/null # list predefined macros for C | |
| - run: g++ -E -x c++ -dM /dev/null # list predefined macros for C++ | |
| - run: make build/extra/gcc/all | |
| - run: make build/extra/clang/all | |
| - run: make build/extra/gcc-m32/all | |
| if: ${{ matrix.use_extra }} | |
| - run: make build/extra/gcc-mx32/all | |
| if: ${{ matrix.use_extra }} | |
| - run: make build/extra/cross-windows-mingw32/all | |
| if: ${{ matrix.use_extra }} | |
| - run: make build/extra/cross-windows-mingw64/all | |
| if: ${{ matrix.use_extra }} | |
| - run: ls -l build/*/*/*/upx* || true | |
| - run: file build/*/*/*/upx* || true | |
| - name: Make artifact | |
| run: | | |
| N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}" | sed 's/[^0-9a-zA-Z_.-]/-/g') | |
| mkdir -p "tmp/artifact/$N" | |
| dirs="gcc/debug gcc/release clang/debug clang/release" | |
| if test "${{ matrix.use_extra }}" = "true"; then | |
| dirs="$dirs gcc-m32/debug gcc-m32/release gcc-mx32/debug gcc-mx32/release" | |
| dirs="$dirs cross-windows-mingw32/debug cross-windows-mingw32/release" | |
| dirs="$dirs cross-windows-mingw64/debug cross-windows-mingw64/release" | |
| fi | |
| for d in $dirs; do DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdir/$d" cmake --install build/extra/$d; done | |
| for d in $dirs; do DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdirAndStrip/$d" cmake --install build/extra/$d --strip; done | |
| for d in $dirs; do cmake --install build/extra/$d --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefix/$d"; done | |
| for d in $dirs; do cmake --install build/extra/$d --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefixAndStrip/$d" --strip; done | |
| (cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N") | |
| if command -v hardlink >/dev/null; then (cd "tmp/artifact/$N" && hardlink .) fi | |
| (cd tmp/artifact && tar --sort=name --zstd -cf "$N.tar.zst" "$N" && rm -rf "./$N" && ls -la && zstd -tq "$N.tar.zst") | |
| echo "artifact_name=$N" >> $GITHUB_ENV | |
| - name: ${{ format('Upload artifact {0}', env.artifact_name) }} | |
| uses: actions/upload-artifact@v5 | |
| with: { name: '${{ env.artifact_name }}', path: tmp/artifact } | |
| - name: Run install tests | |
| run: | | |
| (cd build/extra/gcc/release && DESTDIR="$PWD/Install with cmake" cmake --install .) | |
| (cd build/extra/gcc/release && DESTDIR="$PWD/Install with make" make install) | |
| jobs="gcc/debug gcc/release clang/debug clang/release" | |
| test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release" | |
| echo "===== parallel jobs: $jobs" | |
| DESTDIR="Install with make 2" parallel -kv --lb 'make build/extra/{}+install' ::: $jobs | |
| - name: Mimic ctest tests SIGSEGV | |
| run: | | |
| jobs="gcc/debug gcc/release clang/debug clang/release" | |
| test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest_sigsegv.sh' ::: $jobs | |
| ls -ld ./build/*/*/*/upx-* || true | |
| rm -rf ./build/*/*/*/upx-* | |
| - name: Run ctest tests | |
| run: | | |
| jobs="gcc/debug gcc/release clang/debug clang/release" | |
| test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release" | |
| command -v wine >/dev/null && jobs="$jobs cross-windows-mingw32/debug cross-windows-mingw32/release" | |
| command -v wine >/dev/null && jobs="$jobs cross-windows-mingw64/debug cross-windows-mingw64/release" | |
| echo "===== parallel jobs: $jobs" | |
| CTEST_JOBS=2 parallel -kv --lb 'make build/extra/{}+test' ::: $jobs | |
| ls -ld ./build/*/*/*/XTesting/*/* || true | |
| rm -rf ./build/*/*/*/XTesting/*/* | |
| - name: Mimic ctest tests with Valgrind | |
| if: true # note: valgrind is SLOW | |
| run: | | |
| if command -v valgrind >/dev/null; then | |
| export UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS=ON # valgrind is SLOW | |
| export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet --gen-suppressions=all" | |
| # clang/debug does not work before valgrind-3.20, see https://bugs.kde.org/show_bug.cgi?id=452758 | |
| jobs="gcc/debug gcc/release clang/release" | |
| test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs | |
| ls -ld ./build/*/*/*/upx-* || true | |
| rm -rf ./build/*/*/*/upx-* | |
| fi | |
| - name: Run file system tests | |
| run: | | |
| jobs="gcc/debug gcc/release clang/debug clang/release" | |
| test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs | |
| - name: Run file system tests with Valgrind | |
| if: false # note: valgrind is SLOW | |
| run: | | |
| if command -v valgrind >/dev/null; then | |
| export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet --gen-suppressions=all" | |
| # clang/debug does not work before valgrind-3.20, see https://bugs.kde.org/show_bug.cgi?id=452758 | |
| jobs="gcc/debug gcc/release clang/release" | |
| test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs | |
| fi | |
| - name: Run test suite | |
| run: | | |
| export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" | |
| jobs="gcc/debug gcc/release clang/debug clang/release" | |
| test "${{ matrix.use_extra }}" = "true" && jobs="$jobs gcc-m32/debug gcc-m32/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/upx_testsuite_1.sh' ::: $jobs | |
| ls -ld ./build/*/*/*/tmp-upx-testsuite* || true | |
| rm -rf ./build/*/*/*/tmp-upx-testsuite* | |
| job-macos-cmake: # uses cmake + make | |
| if: true | |
| needs: [ job-rebuild-and-verify-stubs ] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # NOTE: Xcode updates regularly tend to break Homebrew clang/gcc; often some ld64 issue; use "xcode_version" as needed; or try "-Wl,-ld_classic" | |
| # NOTE: macos does not have "env -C"; only with brew coreutils | |
| - { os: macos-14, gcc: gcc-13, gxx: g++-13, testsuite: true } | |
| - { os: macos-15, gcc: gcc-14, gxx: g++-14, testsuite: true } | |
| - { os: macos-26, gcc: gcc-15, gxx: g++-15, testsuite: true } | |
| - { os: macos-15-intel, gcc: gcc-14, gxx: g++-14, testsuite: true } | |
| name: ${{ format('{0} {1}{2}', matrix.os, matrix.xcode_version && 'xcode-' || '', matrix.xcode_version) }} | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - run: uname -a; pwd; id; umask | |
| - uses: maxim-lobanov/setup-xcode@v1 | |
| if: ${{ matrix.xcode_version }} | |
| with: { xcode-version: '${{ matrix.xcode_version }}' } | |
| - name: Install brew packages | |
| if: ${{ matrix.testsuite }} | |
| run: | | |
| test -z "$HOMEBREW_PREFIX" && HOMEBREW_PREFIX="$(brew --prefix)" | |
| echo "HOMEBREW_PREFIX=$HOMEBREW_PREFIX" >> $GITHUB_ENV | |
| # testsuite needs working "readlink -en" and "sha256sum -b" | |
| packages="parallel util-linux" | |
| test -e "$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin/readlink" || packages="$packages coreutils" | |
| if test -n "$packages"; then | |
| echo "===== brew leaves:"; brew leaves; echo "===== brew list:"; brew list --versions | |
| # only run "brew update" if needed | |
| if ! brew install $packages; then echo "===== brew update" && brew update && brew install $packages; fi | |
| fi | |
| mkdir -p ~/.parallel && : > ~/.parallel/$(echo 6305-4721 | tr 0-7 leticlwi) | |
| echo "UPX_DEBUG_FORCE_PACK_MACOS=1" >> $GITHUB_ENV | |
| case "${{ matrix.os }}" in | |
| # TODO FIXME: UPX on macos-13+ is broken => disable run-packed for now | |
| macos-[12][3456]*) echo "UPX_CONFIG_DISABLE_RUN_PACKED_TEST=ON" >> $GITHUB_ENV ;; | |
| esac | |
| - uses: actions/checkout@v6 | |
| with: { submodules: true } | |
| - name: Check out test suite | |
| if: ${{ matrix.testsuite }} | |
| run: git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite | |
| - run: set -x; xcode-select -p || true; xcodebuild -version || true | |
| - run: set -x; clang --version; clang++ --version | |
| - run: clang -E -x c -dM /dev/null # list predefined macros for C | |
| - run: clang++ -E -x c++ -dM /dev/null # list predefined macros for C++ | |
| - run: set -x; ${{ matrix.gcc }} --version; ${{ matrix.gxx }} --version | |
| if: ${{ matrix.gcc }} | |
| - run: ${{ matrix.gcc }} -E -x c -dM /dev/null # list predefined macros for C | |
| if: ${{ matrix.gcc }} | |
| - run: ${{ matrix.gxx }} -E -x c++ -dM /dev/null # list predefined macros for C++ | |
| if: ${{ matrix.gcc }} | |
| - run: make build/extra/clang/all | |
| - name: Build extra/gcc/all | |
| if: ${{ matrix.gcc }} | |
| run: make build/extra/gcc/all CC="${{ matrix.gcc }} -static-libgcc" CXX="${{ matrix.gxx }} -static-libgcc -static-libstdc++" | |
| - name: Build xtarget/cross-darwin-arm64/all | |
| run: | | |
| make UPX_XTARGET=xtarget/cross-darwin-arm64 xtarget/all \ | |
| CC="clang -target arm64-apple-darwin" CXX="clang++ -target arm64-apple-darwin" | |
| - run: ls -l build/*/*/*/upx* || true | |
| - run: file build/*/*/*/upx* || true | |
| - name: Make artifact | |
| run: | | |
| X="${{ matrix.xcode_version }}"; test -n "$X" && X="-xcode-$X" | |
| N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.os }}$X" | sed 's/[^0-9a-zA-Z_.-]/-/g') | |
| mkdir -p "tmp/artifact/$N" | |
| dirs="clang/debug clang/release" | |
| test -n "${{ matrix.gcc }}" && dirs="$dirs gcc/debug gcc/release" | |
| for d in $dirs; do DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdir/$d" cmake --install build/extra/$d; done | |
| for d in $dirs; do DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdirAndStrip/$d" cmake --install build/extra/$d --strip; done | |
| for d in $dirs; do cmake --install build/extra/$d --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefix/$d"; done | |
| for d in $dirs; do cmake --install build/extra/$d --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefixAndStrip/$d" --strip; done | |
| (cd build && rsync -R -a */*/*/upx "../tmp/artifact/$N/") | |
| hardlink="$HOMEBREW_PREFIX/opt/util-linux/bin/hardlink" | |
| if test -f "$hardlink"; then (cd "tmp/artifact/$N" && "$hardlink" .) fi | |
| (cd tmp/artifact && gtar --sort=name --zstd -cf "$N.tar.zst" "$N" && rm -rf "./$N" && ls -la && zstd -tq "$N.tar.zst") | |
| echo "artifact_name=$N" >> $GITHUB_ENV | |
| - name: ${{ format('Upload artifact {0}', env.artifact_name) }} | |
| uses: actions/upload-artifact@v5 | |
| with: { name: '${{ env.artifact_name }}', path: tmp/artifact } | |
| - name: Run install tests | |
| run: | | |
| (cd build/extra/clang/release && DESTDIR="$PWD/Install with cmake" cmake --install .) | |
| (cd build/extra/clang/release && DESTDIR="$PWD/Install with make" make install) | |
| - name: Run ctest tests | |
| if: ${{ matrix.testsuite }} | |
| run: | | |
| for f in ./build/extra/*/*/upx; do file $f; done | |
| jobs="clang/debug clang/release" | |
| test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release" | |
| echo "===== parallel jobs: $jobs" | |
| CTEST_JOBS=2 parallel -kv --lb 'make build/extra/{}+test' ::: $jobs | |
| - name: Mimic ctest tests | |
| if: ${{ matrix.testsuite }} | |
| run: | | |
| export PATH="$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin:$PATH" | |
| jobs="clang/debug clang/release" | |
| test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs | |
| - name: Run file system tests | |
| if: ${{ matrix.testsuite }} | |
| run: | | |
| export PATH="$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin:$PATH" | |
| export upx_test_file="$PWD"/build/extra/clang/release/upx | |
| jobs="clang/debug clang/release" | |
| test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs | |
| - name: Run test suite | |
| if: ${{ matrix.testsuite }} | |
| run: | | |
| export PATH="$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin:$PATH" | |
| export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" | |
| jobs="clang/debug clang/release" | |
| test -n "${{ matrix.gcc }}" && jobs="$jobs gcc/debug gcc/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/extra/{} && bash ../../../../misc/testsuite/upx_testsuite_1.sh' ::: $jobs | |
| job-windows-cmake: # uses cmake + msbuild | |
| if: true | |
| needs: [ job-rebuild-and-verify-stubs ] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { name: windows-11-arm64, os: windows-11-arm, vsversion: 2022, vsarch: arm64 } | |
| - { name: windows-11-arm64ec, os: windows-11-arm, vsversion: 2022, vsarch: arm64, use_arm64ec: true } | |
| # { name: windows-11-arm64x, os: windows-11-arm, vsversion: 2022, vsarch: arm64, use_arm64x: true } | |
| - { name: windows-2022-amd64, os: windows-2022, vsversion: 2022, vsarch: amd64 } | |
| - { name: windows-2022-i386, os: windows-2022, vsversion: 2022, vsarch: amd64_x86 } | |
| - { name: windows-2025-amd64, os: windows-2025, vsversion: 2022, vsarch: amd64 } | |
| - { name: windows-2025-i386, os: windows-2025, vsversion: 2022, vsarch: amd64_x86 } | |
| name: ${{ format('{0}', matrix.name) }} | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - run: git config --global core.autocrlf false | |
| - uses: actions/checkout@v6 | |
| with: { submodules: true } | |
| - name: Check out test suite | |
| run: git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite | |
| - uses: ilammy/msvc-dev-cmd@v1 | |
| with: { vsversion: '${{ matrix.vsversion }}', arch: '${{ matrix.vsarch }}' } | |
| - name: Set platform | |
| run: | | |
| if [[ "${{ matrix.use_arm64ec }}" == "true" ]]; then true; | |
| echo "UPX_CMAKE_CONFIG_FLAGS_PLATFORM=-A ARM64EC" >> $GITHUB_ENV | |
| echo "UPX_CONFIG_DISABLE_SELF_PACK_TEST=ON" >> $GITHUB_ENV | |
| elif [[ "${{ matrix.use_arm64x }}" == "true" ]]; then true; | |
| echo "UPX_CMAKE_CONFIG_FLAGS_PLATFORM=-A ARM64X" >> $GITHUB_ENV | |
| echo "UPX_CONFIG_DISABLE_SELF_PACK_TEST=ON" >> $GITHUB_ENV | |
| elif [[ "${{ matrix.vsarch }}" == *amd64 ]]; then true; | |
| echo "UPX_CMAKE_CONFIG_FLAGS_PLATFORM=-A x64" >> $GITHUB_ENV | |
| elif [[ "${{ matrix.vsarch }}" == *arm64 ]]; then true; | |
| echo "UPX_CMAKE_CONFIG_FLAGS_PLATFORM=-A ARM64" >> $GITHUB_ENV | |
| echo "UPX_CONFIG_DISABLE_SELF_PACK_TEST=ON" >> $GITHUB_ENV | |
| elif [[ "${{ matrix.vsarch }}" == *x86 ]]; then true; | |
| echo "UPX_CMAKE_CONFIG_FLAGS_PLATFORM=-A Win32" >> $GITHUB_ENV | |
| else | |
| exit 1 | |
| fi | |
| - run: make build/debug | |
| - run: make build/release | |
| - run: shopt -s globstar; ls -ld build/**/upx* || true | |
| - run: shopt -s globstar; file build/**/upx* || true | |
| - name: Make artifact | |
| run: | | |
| N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-${{ matrix.name }}" | sed 's/[^0-9a-zA-Z_.-]/-/g') | |
| mkdir -p "tmp/artifact/$N" | |
| DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdir/debug" cmake --install build/debug --config Debug | |
| DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdir/release" cmake --install build/release --config Release | |
| DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdirAndStrip/debug" cmake --install build/debug --config Debug --strip | |
| DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdirAndStrip/release" cmake --install build/release --config Release --strip | |
| cmake --install build/debug --config Debug --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefix/debug" | |
| cmake --install build/release --config Release --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefix/release" | |
| cmake --install build/debug --config Debug --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefixAndStrip/debug" --strip | |
| cmake --install build/release --config Release --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefixAndStrip/release" --strip | |
| (cd build && cp -ai --parents */*/upx.exe "../tmp/artifact/$N") | |
| #(cd tmp/artifact && tar --sort=name --zstd -cf "$N.tar.zst" "$N" && rm -rf "./$N" && ls -la && zstd -tq "$N.tar.zst") | |
| (cd tmp/artifact && tar --sort=name --gzip -cf "$N.tar.gz" "$N" && rm -rf "./$N" && ls -la && gzip -tq "$N.tar.gz") | |
| echo "artifact_name=$N" >> $GITHUB_ENV | |
| - name: ${{ format('Upload artifact {0}', env.artifact_name) }} | |
| uses: actions/upload-artifact@v5 | |
| with: { name: '${{ env.artifact_name }}', path: tmp/artifact } | |
| - name: Run ctest tests | |
| run: | | |
| ctest --test-dir build/debug --parallel 8 -C Debug | |
| ctest --test-dir build/release --parallel 8 -C Release | |
| - name: Mimic ctest tests | |
| run: | | |
| env -C build/debug/Debug upx_exe=./upx.exe bash "$PWD"/misc/testsuite/mimic_ctest.sh | |
| env -C build/release/Release upx_exe=./upx.exe bash "$PWD"/misc/testsuite/mimic_ctest.sh | |
| - name: Run test suite build/release | |
| run: | | |
| export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" | |
| env -C build/release/Release upx_exe=./upx.exe bash "$PWD"/misc/testsuite/upx_testsuite_1.sh | |
| job-windows-bh-toolchains: # build "by hand" using cmd.exe | |
| if: github.repository_owner == 'upx' | |
| needs: [ job-rebuild-and-verify-stubs ] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { name: amd64-win64-vs2025, os: windows-2025, vsversion: 2022, vsarch: amd64 } | |
| - { name: arm64-win64-vs2025, os: windows-2025, vsversion: 2022, vsarch: amd64_arm64 } | |
| - { name: arm64ec-win64-vs2025, os: windows-2025, vsversion: 2022, vsarch: amd64_arm64, cl_machine_flags: -arm64EC, link_machine_flags: '/machine:arm64ec' } | |
| # { name: arm64x-win64-vs2025, os: windows-2025, vsversion: 2022, vsarch: amd64_arm64, cl_machine_flags: -arm64EC, link_machine_flags: '/machine:arm64x' } | |
| - { name: i386-win32-vs2025, os: windows-2025, vsversion: 2022, vsarch: amd64_x86 } | |
| name: ${{ format('windows-bh {0}', matrix.name) }} | |
| runs-on: ${{ matrix.os }} | |
| env: | |
| C: ${{ matrix.name }} | |
| B: release | |
| steps: | |
| - run: git config --global core.autocrlf false | |
| - uses: actions/checkout@v6 | |
| with: { submodules: true } | |
| - name: Prepare sources and Check out test suite | |
| run: | | |
| git clone --depth=1 https://github.com/upx/upx-testsuite ../deps/upx-testsuite | |
| mkdir -p -v build/$C/$B/{bzip2,ucl,upx,zlib,zstd} | |
| repository_name="${GITHUB_REPOSITORY##*/}" # basename | |
| echo "H=d:\\a\\$repository_name\\$repository_name" >> $GITHUB_ENV | |
| - uses: ilammy/msvc-dev-cmd@v1 | |
| with: { vsversion: '${{ matrix.vsversion }}', arch: '${{ matrix.vsarch }}' } | |
| - name: Build by hand | |
| shell: cmd | |
| run: | | |
| @REM ===== set vars ===== | |
| where cl & where link | |
| set RUN_CL=cl ${{ matrix.cl_machine_flags }} -MT | |
| set RUN_LIB=link -lib ${{ matrix.link_machine_flags }} | |
| @rem UPX only uses the very basic Windows API | |
| set DEFS=-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=0x0501 | |
| set BDIR=%H%\build\%C%\%B% | |
| git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt | |
| @REM ===== build bzip2 ===== | |
| cd %BDIR%\bzip2 | |
| @rem %RUN_CL% -J -O2 -W4 -wd4127 -wd4244 -wd4267 -WX %DEFS% -DBZ_NO_STDIO -c %H%\vendor\bzip2\*.c | |
| @rem %RUN_LIB% -out:bzip2.lib *.obj | |
| @REM ===== build UCL ===== | |
| cd %BDIR%\ucl | |
| set s=%H%\vendor\ucl | |
| %RUN_CL% -J -O2 -W4 -WX %DEFS% -I%s%\include -I%s% -c %s%\src\*.c | |
| %RUN_LIB% -out:ucl.lib *.obj | |
| @REM ===== build zlib ===== | |
| cd %BDIR%\zlib | |
| set s=%H%\vendor\zlib | |
| %RUN_CL% -J -O2 -W3 -WX %DEFS% -I%s% -DHAVE_VSNPRINTF -c %H%\vendor\zlib\*.c | |
| %RUN_LIB% -out:zlib.lib *.obj | |
| @REM ===== build zstd ===== | |
| cd %BDIR%\zstd | |
| set s=%H%\vendor\zstd\lib | |
| @rem %RUN_CL% -J -O2 -W4 -WX %DEFS% -DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM -c %s%\common\*.c %s%\compress\*.c %s%\decompress\*.c | |
| @rem %RUN_LIB% -out:zstd.lib *.obj | |
| @REM ===== build UPX ===== | |
| cd %BDIR%\upx | |
| set s=%H%\src | |
| cat .GITREV.txt | |
| set /p GITREV=<.GITREV.txt | |
| set UPX_DEFS=-DUPX_CONFIG_DISABLE_WSTRICT=0 -DUPX_CONFIG_DISABLE_WERROR=0 -DWITH_THREADS=0 -DWITH_BZIP2=0 -DWITH_ZSTD=0 | |
| set UPX_LIBS=%BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib | |
| @rem set UPX_LIBS=%BDIR%\bzip2\bzip2.lib %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib %BDIR%\zstd\zstd.lib | |
| set sources=%s%\*.cpp %s%\check\*.cpp %s%\compress\*.cpp %s%\console\*.cpp %s%\filter\*.cpp %s%\util\*.cpp | |
| %RUN_CL% -J -O2 -W4 -WX -std:c++17 -Zc:__cplusplus -EHsc -DUPX_VERSION_GITREV="""%GITREV%""" %DEFS% %UPX_DEFS% -I%H%\vendor -Feupx.exe %sources% %UPX_LIBS% /link ${{ matrix.link_machine_flags }} setargv.obj | |
| - run: shopt -s globstar; ls -ld build/**/upx* || true | |
| - run: shopt -s globstar; file build/**/upx* || true | |
| - name: Make artifact | |
| run: | | |
| N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-windows-bh-${{ matrix.name }}" | sed 's/[^0-9a-zA-Z_.-]/-/g') | |
| mkdir -p "tmp/artifact/$N/$B" | |
| cp -ai build/$C/$B/upx/upx*.exe "tmp/artifact/$N/$B" | |
| #(cd tmp/artifact && tar --sort=name --zstd -cf "$N.tar.zst" "$N" && rm -rf "./$N" && ls -la && zstd -tq "$N.tar.zst") | |
| (cd tmp/artifact && tar --sort=name --gzip -cf "$N.tar.gz" "$N" && rm -rf "./$N" && ls -la && gzip -tq "$N.tar.gz") | |
| echo "artifact_name=$N" >> $GITHUB_ENV | |
| - name: ${{ format('Upload artifact {0}', env.artifact_name) }} | |
| uses: actions/upload-artifact@v5 | |
| with: { name: '${{ env.artifact_name }}', path: tmp/artifact } | |
| - name: Mimic ctest tests | |
| if: ${{ matrix.vsarch != 'amd64_arm64' }} | |
| run: | | |
| env -C build/$C/$B/upx upx_exe=./upx.exe bash "$PWD"/misc/testsuite/mimic_ctest.sh | |
| - name: Run test suite | |
| if: ${{ matrix.vsarch != 'amd64_arm64' }} | |
| run: | | |
| export upx_testsuite_SRCDIR="$(readlink -en ../deps/upx-testsuite)" | |
| env -C build/$C/$B/upx upx_exe=./upx.exe bash "$PWD"/misc/testsuite/upx_testsuite_1.sh | |
| job-linux-zigcc: # uses cmake + make | |
| if: github.repository_owner == 'upx' | |
| needs: [ job-rebuild-and-verify-stubs ] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # only build a few selected targets => more targets are tested in the Weekly CI | |
| - { zig_target: aarch64-linux-musl, qemu: qemu-aarch64 } | |
| - { zig_target: aarch64-linux-musl, qemu: qemu-aarch64, zig_pic: -fPIE, container: 'alpine:3.18' } | |
| - { zig_target: aarch64-macos-none } | |
| - { zig_target: aarch64-windows-gnu } | |
| - { zig_target: arm-linux-musleabihf, qemu: qemu-arm } | |
| - { zig_target: armeb-linux-musleabihf, qemu: qemu-armeb } | |
| - { zig_target: i386-linux-gnu.2.3.4, zig_flags: -march=i586 } | |
| - { zig_target: i386-linux-gnu.2.17, zig_flags: -march=i586 } | |
| - { zig_target: i386-linux-musl, zig_flags: -march=i586, qemu: qemu-i386 } | |
| - { zig_target: i386-linux-musl, zig_flags: -march=i586, qemu: qemu-i386, zig_pic: -fPIE } | |
| - { zig_target: i386-windows-gnu } | |
| - { zig_target: mips-linux-musleabi, qemu: qemu-mips } | |
| - { zig_target: mips-linux-musleabihf, qemu: qemu-mips } | |
| - { zig_target: mipsel-linux-musleabi, qemu: qemu-mipsel } | |
| - { zig_target: mipsel-linux-musleabihf, qemu: qemu-mipsel } | |
| # { zig_target: mips-linux-musleabi-mips32r2, zig_flags: -march=mips32r2, qemu: qemu-mips } | |
| # { zig_target: mips-linux-musleabi-mips32r3, zig_flags: -march=mips32r3, qemu: qemu-mips } | |
| # { zig_target: mips-linux-musleabi-mips32r5, zig_flags: -march=mips32r5, qemu: qemu-mips } | |
| # { zig_target: mips-linux-musleabi-mips32r6, zig_flags: -march=mips32r6, qemu: qemu-mips } | |
| - { zig_target: powerpc-linux-musleabihf, qemu: qemu-ppc } | |
| - { zig_target: powerpc64-linux-musl, qemu: qemu-ppc64 } | |
| - { zig_target: powerpc64-linux-musl, qemu: qemu-ppc64, zig_pic: -fPIE } | |
| - { zig_target: powerpc64le-linux-musl, qemu: qemu-ppc64le } | |
| - { zig_target: powerpc64le-linux-musl, qemu: qemu-ppc64le, zig_pic: -fPIE } | |
| - { zig_target: riscv64-linux-musl, qemu: qemu-riscv64, tt: UPX-UNSUPPORTED } | |
| - { zig_target: riscv64-linux-musl, qemu: qemu-riscv64, tt: UPX-UNSUPPORTED, zig_pic: -fPIE } | |
| - { zig_target: x86_64-linux-gnu.2.3.4, qemu: qemu-x86_64 } # can use QEMU because of gcompat | |
| - { zig_target: x86_64-linux-gnu.2.17, qemu: qemu-x86_64 } # can use QEMU because of gcompat | |
| - { zig_target: x86_64-linux-musl, qemu: qemu-x86_64 } | |
| - { zig_target: x86_64-linux-musl, qemu: qemu-x86_64, zig_pic: -fPIE, container: 'alpine:3.18' } | |
| - { zig_target: x86_64-macos-none } | |
| - { zig_target: x86_64-windows-gnu } | |
| name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }} | |
| runs-on: ubuntu-latest | |
| container: ${{ matrix.container || 'alpine:3.22' }} | |
| env: | |
| container: ${{ matrix.container || 'alpine:3.22' }} | |
| UPX_CONFIG_HAVE_WORKING_BUILD_RPATH: '' | |
| # for zig-cc wrapper scripts (see below): | |
| ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING | |
| ZIG_FLAGS: ${{ matrix.zig_flags }} | |
| ZIG_PIC: ${{ matrix.zig_pic }} | |
| ZIG_TARGET: ${{ matrix.zig_target }} | |
| steps: | |
| - run: uname -a; pwd; id; umask | |
| shell: sh | |
| - name: ${{ format('Install packages {0}', env.container) }} | |
| shell: sh | |
| run: | | |
| apk update && apk upgrade && apk add bash cmake curl dmidecode file gdb git make parallel patch strace sudo tar util-linux xz zstd | |
| # set PATH like in Ubuntu | |
| echo "PATH=$HOME/.local/bin:$PATH" >> $GITHUB_ENV | |
| git config --global --add safe.directory '*' # needed when running in a container | |
| mkdir -p ~/.parallel && : > ~/.parallel/$(echo 6305-4721 | tr 0-7 leticlwi) | |
| - run: (sudo dmidecode | sed -n -e '/System Information/,/^$/p') || true | |
| - uses: actions/checkout@v6 | |
| with: { submodules: true } | |
| - name: ${{ format('Install Zig {0}', env.ZIG_DIST_VERSION) }} | |
| run: | | |
| rev=$(git rev-parse --short=7 HEAD) | |
| echo "UPX_GITREV_SHORT=$rev" >> $GITHUB_ENV | |
| if [[ "${{ matrix.zig_target }}" == i386-linux-gnu.2.3.* ]]; then true; | |
| echo "UPX_CONFIG_DISABLE_SHARED_LIBS=ON" >> $GITHUB_ENV # zig problem when linking in Debug mode | |
| fi | |
| if [[ "${{ matrix.zig_target }}" == x86_64-linux-gnu.2* ]]; then true; | |
| echo "NEED_GCOMPAT=1" >> $GITHUB_ENV | |
| # TODO FIXME: problem with self-packed upx and musl+gcompat: "Not a valid dynamic program" | |
| echo "UPX_CONFIG_DISABLE_RUN_PACKED_TEST=ON" >> $GITHUB_ENV | |
| fi | |
| test -z "${{ matrix.tt }}" || echo "UPX_CONFIG_DISABLE_SELF_PACK_TEST=ON" >> $GITHUB_ENV | |
| # install zig; note that ~/.local/bin is included in the default $PATH on Ubuntu | |
| mkdir -p -v ~/.local/bin | |
| cd ~/.local/bin | |
| ZIG_DIST_VERSION=${ZIG_DIST_VERSION/#zig-/} | |
| ZIG_DIST_NAME=zig-linux-x86_64-${ZIG_DIST_VERSION} | |
| ZIG_DIST_NAME=zig-x86_64-linux-${ZIG_DIST_VERSION} | |
| #curl -sS -L -O https://ziglang.org/builds/${ZIG_DIST_NAME}.tar.xz | |
| #curl -sS -L -O https://ziglang.org/download/0.14.1/${ZIG_DIST_NAME}.tar.xz | |
| curl -sS -L -O https://ziglang.org/download/0.15.2/${ZIG_DIST_NAME}.tar.xz | |
| ls -l ${ZIG_DIST_NAME}.tar.xz | |
| file ${ZIG_DIST_NAME}.tar.xz || true | |
| tar -xoJf ${ZIG_DIST_NAME}.tar.xz | |
| rm ${ZIG_DIST_NAME}.tar.xz | |
| ln -s -v ${ZIG_DIST_NAME}/zig zig | |
| #echo "PATH=$PATH" && which zig | |
| echo -n 'zig version: '; zig version | |
| # patch zig | |
| ls -la "$HOME" "$GITHUB_WORKSPACE" || true | |
| (cd ${ZIG_DIST_NAME} && patch --verbose -p1 -i "$GITHUB_WORKSPACE"/misc/patches/zig/0001-x.patch) | |
| # create wrapper scripts (needed for CMake) | |
| log= | |
| log='set -x\n' | |
| echo -e '#!/bin/sh\n'$log'exec zig ar "$@"' > zig-ar | |
| echo -e '#!/bin/sh\n'$log'exec zig cc -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CFLAGS "$@"' > zig-cc | |
| echo -e '#!/bin/sh\n'$log'exec zig c++ -target $ZIG_TARGET $ZIG_PIC $ZIG_FLAGS $ZIG_CPPFLAGS $ZIG_CXXFLAGS "$@"' > zig-cxx | |
| echo -e '#!/bin/sh\n'$log'exec zig ranlib "$@"' > zig-ranlib | |
| chmod +x zig-ar zig-cc zig-cxx zig-ranlib | |
| ls -la; head zig-ar zig-cc zig-cxx zig-ranlib | |
| # update ZIG_TARGET | |
| [[ $ZIG_TARGET == mips-linux-musleabi-* ]] && ZIG_TARGET=mips-linux-musleabi | |
| [[ $ZIG_TARGET == mips-linux-musleabihf-* ]] && ZIG_TARGET=mips-linux-musleabihf | |
| [[ $ZIG_TARGET == mipsel-linux-musleabi-* ]] && ZIG_TARGET=mipsel-linux-musleabi | |
| [[ $ZIG_TARGET == mipsel-linux-musleabihf-* ]] && ZIG_TARGET=mipsel-linux-musleabihf | |
| ZIG_TARGET=${ZIG_TARGET/#i386-/x86-} # i386 => x86 | |
| echo "ZIG_TARGET=$ZIG_TARGET" >> $GITHUB_ENV | |
| # update ZIG_FLAGS | |
| # -fPIE is for compilation only => also use the correct linker flag "-pie" | |
| # INFO: it seems the zig driver does handle this automatically(??), so not really needed | |
| if test "X$ZIG_PIC" = "X-fPIE"; then true; | |
| ZIG_FLAGS="$ZIG_FLAGS --start-no-unused-arguments -pie --end-no-unused-arguments" | |
| echo "UPX_CONFIG_DISABLE_SHARED_LIBS=ON" >> $GITHUB_ENV # conflicts with ZIG_PIC/ZIG_FLAGS | |
| fi | |
| if [[ $ZIG_TARGET == *-linux-gnu.2.3.* ]]; then true; | |
| # glibc-2.3.3: undefined symbols in Debug build: __snprintf_chk __vsnprintf_chk | |
| # glibc-2.3.4: ld.lld: error: undefined symbol: openat64 | |
| ZIG_FLAGS="$ZIG_FLAGS -fno-sanitize=all" | |
| echo "UPX_CONFIG_DISABLE_SANITIZE=ON" >> $GITHUB_ENV | |
| fi | |
| if [[ $ZIG_TARGET == *-linux-gnu.2.[456789] ]]; then true; | |
| # glibc-2.x: ld.lld: error: undefined symbol: pwritev64 | |
| ZIG_FLAGS="$ZIG_FLAGS -fno-sanitize=all" | |
| echo "UPX_CONFIG_DISABLE_SANITIZE=ON" >> $GITHUB_ENV | |
| fi | |
| echo "ZIG_FLAGS=$ZIG_FLAGS" >> $GITHUB_ENV | |
| - run: set -x; zig version; zig-cc --version || true; zig-cxx --version || true | |
| - run: zig-cc -E -x c -dM /dev/null # list predefined macros for C | |
| - run: zig-cxx -E -x c++ -dM /dev/null # list predefined macros for C++ | |
| - name: ${{ format('Build Release with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }} | |
| run: | | |
| make UPX_XTARGET=zig/${ZIG_TARGET}${ZIG_PIC} xtarget/release \ | |
| CC="zig-cc" CXX="zig-cxx" CMAKE_AR="$HOME/.local/bin/zig-ar" CMAKE_RANLIB="$HOME/.local/bin/zig-ranlib" | |
| - name: ${{ format('Build Debug with zig-cc -target {0} {1}', env.ZIG_TARGET, env.ZIG_PIC) }} | |
| run: | | |
| make UPX_XTARGET=zig/${ZIG_TARGET}${ZIG_PIC} xtarget/debug \ | |
| CC="zig-cc" CXX="zig-cxx" CMAKE_AR="$HOME/.local/bin/zig-ar" CMAKE_RANLIB="$HOME/.local/bin/zig-ranlib" | |
| - run: ls -l build/*/*/*/upx* || true | |
| - run: file build/*/*/*/upx* || true | |
| - name: ${{ format('Make artifact from upx-{0}-{1}', github.ref_name, env.UPX_GITREV_SHORT) }} | |
| run: | | |
| N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-zigcc-${{ matrix.zig_target }}${ZIG_PIC}" | sed 's/[^0-9a-zA-Z_.-]/-/g') | |
| mkdir -p "tmp/artifact/$N" | |
| if [[ "${{ matrix.zig_target }}" == *-linux* ]]; then | |
| dirs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release" | |
| for d in $dirs; do DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdir/$d" cmake --install build/zig/$d; done | |
| for d in $dirs; do DESTDIR="$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithDestdirAndStrip/$d" cmake --install build/zig/$d --strip; done | |
| for d in $dirs; do cmake --install build/zig/$d --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefix/$d"; done | |
| for d in $dirs; do cmake --install build/zig/$d --prefix "$PWD/tmp/artifact/$N/InstallWithCMake/InstallWithPrefixAndStrip/$d" --strip; done | |
| fi | |
| (cd build && shopt -s nullglob && cp -ai --parents */upx{,.exe} */*/*/upx{,.exe} "../tmp/artifact/$N") | |
| if command -v hardlink >/dev/null; then (cd "tmp/artifact/$N" && hardlink .) fi | |
| (cd tmp/artifact && tar --sort=name --zstd -cf "$N.tar.zst" "$N" && rm -rf "./$N" && ls -la && zstd -tq "$N.tar.zst") | |
| echo "artifact_name=$N" >> $GITHUB_ENV | |
| - name: ${{ format('Upload artifact {0}', env.artifact_name) }} | |
| uses: actions/upload-artifact@v5 | |
| with: { name: '${{ env.artifact_name }}', path: tmp/artifact } | |
| - name: Run install tests | |
| if: ${{ contains(matrix.zig_target, '-linux') }} | |
| run: | | |
| (cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR="$PWD/Install with cmake" cmake --install .) | |
| (cd build/zig/${ZIG_TARGET}${ZIG_PIC}/release && DESTDIR="$PWD/Install with make" make install) | |
| - name: Run ctest tests | |
| if: ${{ matrix.zig_target == 'i386-linux-musl' || matrix.zig_target == 'x86_64-linux-musl' || contains(matrix.zig_target, 'x86_64-linux-gnu.2') }} | |
| run: | | |
| test -n "$NEED_GCOMPAT" && apk add gcompat | |
| jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'make build/zig/{}+test' ::: $jobs | |
| - name: Mimic ctest tests | |
| if: ${{ matrix.zig_target == 'i386-linux-musl' || matrix.zig_target == 'x86_64-linux-musl' || contains(matrix.zig_target, 'x86_64-linux-gnu.2') }} | |
| run: | | |
| test -n "$NEED_GCOMPAT" && apk add gcompat | |
| jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/zig/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs | |
| - name: ${{ format('Mimic ctest tests with QEMU {0}', matrix.qemu) }} | |
| if: ${{ matrix.qemu }} | |
| run: | | |
| qemu="${{ matrix.qemu }}" | |
| apk add coreutils "${qemu%% *}" | |
| test -n "$NEED_GCOMPAT" && apk add gcompat | |
| export upx_exe_runner="$qemu" | |
| jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/zig/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs | |
| - name: Mimic ctest tests with Valgrind | |
| #if: ${{ matrix.zig_target == 'x86_64-linux-musl' || contains(matrix.zig_target, 'x86_64-linux-gnu.2') }} | |
| if: false | |
| run: | | |
| export UPX_CONFIG_DISABLE_EXHAUSTIVE_TESTS=ON # valgrind is SLOW | |
| apk add coreutils valgrind | |
| test -n "$NEED_GCOMPAT" && apk add gcompat | |
| export upx_exe_runner="valgrind --leak-check=no --error-exitcode=1 --quiet --gen-suppressions=all" | |
| upx_exe_runner="$upx_exe_runner --suppressions=$PWD/misc/valgrind/musl.supp" | |
| jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/zig/{} && bash ../../../../misc/testsuite/mimic_ctest.sh' ::: $jobs | |
| - name: Run file system tests | |
| if: ${{ matrix.zig_target == 'i386-linux-musl' || matrix.zig_target == 'x86_64-linux-musl' || contains(matrix.zig_target, 'x86_64-linux-gnu.2') }} | |
| run: | | |
| apk add coreutils sudo | |
| test -n "$NEED_GCOMPAT" && apk add gcompat | |
| jobs="${ZIG_TARGET}${ZIG_PIC}/debug ${ZIG_TARGET}${ZIG_PIC}/release" | |
| echo "===== parallel jobs: $jobs" | |
| parallel -kv --lb 'cd build/zig/{} && chmod a+w . && sudo -u nobody bash ../../../../misc/testsuite/test_symlinks.sh' ::: $jobs |