Skip to content

Make Linux native flags architecture-safe in CI #14

Make Linux native flags architecture-safe in CI

Make Linux native flags architecture-safe in CI #14

# Build all JNI natives and assemble a final JAR that includes every platform's shared library

Check failure on line 1 in .github/workflows/build-all-and-publish.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/build-all-and-publish.yml

Invalid workflow file

(Line: 30, Col: 30): Unrecognized named-value: 'env'. Located at position 1 within expression: env.NATIVE_X86_EXTRA_CFLAGS, (Line: 36, Col: 30): Unrecognized named-value: 'env'. Located at position 1 within expression: env.NATIVE_X86_EXTRA_CFLAGS
name: Build and publish for all platforms
on:
release:
types: [published]
workflow_dispatch:
inputs:
publish:
description: 'Publish to Maven Central?'
required: false
default: false
type: boolean
jobs:
linux:
name: Linux natives (${{ matrix.arch }})
runs-on: ubuntu-latest
env:
NATIVE_BASE_CFLAGS: -O2 -fno-omit-frame-pointer -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security
NATIVE_X86_EXTRA_CFLAGS: -mno-omit-leaf-frame-pointer -fcf-protection
NATIVE_XXHASH_EXTRA_CFLAGS: -fno-tree-vectorize
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
cc: gcc
arch_cflags: ""
arch_x86_cflags: "${{ env.NATIVE_X86_EXTRA_CFLAGS }}"
ldflags: ""
apt: ""
- arch: i386
cc: gcc
arch_cflags: "-m32"
arch_x86_cflags: "${{ env.NATIVE_X86_EXTRA_CFLAGS }}"
ldflags: "-m32"
apt: "gcc-multilib libc6-dev-i386"
- arch: aarch64
cc: aarch64-linux-gnu-gcc
arch_cflags: ""
arch_x86_cflags: ""
ldflags: ""
apt: "gcc-aarch64-linux-gnu"
- arch: ppc64le
cc: powerpc64le-linux-gnu-gcc
arch_cflags: ""
arch_x86_cflags: ""
ldflags: ""
apt: "gcc-powerpc64le-linux-gnu"
- arch: s390x
cc: s390x-linux-gnu-gcc
arch_cflags: ""
arch_x86_cflags: ""
ldflags: ""
apt: "gcc-s390x-linux-gnu"
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Setup Zulu JDK 7
uses: actions/setup-java@v5
with:
distribution: zulu
java-version: '7'
- name: Setup Temurin JDK 21
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '21'
cache: maven
- name: Install cross toolchain (if needed)
if: ${{ matrix.apt != '' }}
run: |
sudo apt-get update
sudo apt-get install -y ${{ matrix.apt }}
- name: Build (mvn package)
run: |
./mvnw -B -V -DskipTests \
-Darch.id=${{ matrix.arch }} \
-Dnative.cc=${{ matrix.cc }} \
"-Dnative.cflags=${{ env.NATIVE_BASE_CFLAGS }} ${{ matrix.arch_x86_cflags }} ${{ matrix.arch_cflags }}" \
"-Dnative.xxhash.cflags=${{ env.NATIVE_BASE_CFLAGS }} ${{ matrix.arch_x86_cflags }} ${{ matrix.arch_cflags }} ${{ env.NATIVE_XXHASH_EXTRA_CFLAGS }}" \
"-Dnative.ldflags=${{ matrix.ldflags }}" \
package
- name: Upload native library
uses: actions/upload-artifact@v4
with:
name: natives-linux-${{ matrix.arch }}
path: target/classes/net/jpountz/util/linux/*/liblz4-java.so
if-no-files-found: error
macos:
name: macOS natives (${{ matrix.os }} - ${{ matrix.arch }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: macos-15-intel
arch: x86_64
fullbuild: true
- os: macos-14
arch: aarch64
# Build only the native binary for this architecture; it suffices if only one of the macOS builds performs a full Maven build
fullbuild: false
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Setup Zulu JDK 7
uses: actions/setup-java@v5
if: ${{ matrix.fullbuild }}
with:
distribution: zulu
java-version: '7'
- name: Setup Temurin JDK 21
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '21'
cache: maven
- name: Build (native binary build only)
if: ${{ !matrix.fullbuild }}
run: |
./mvnw -B -V -DskipTests \
-Darch.id=${{ matrix.arch }} \
-Dnative.cc=cc \
process-resources
- name: Build (full build)
if: ${{ matrix.fullbuild }}
run: |
./mvnw -B -V \
-Darch.id=${{ matrix.arch }} \
-Dnative.cc=cc \
verify
- name: Upload native library
uses: actions/upload-artifact@v4
with:
name: natives-darwin-${{ matrix.arch }}
path: target/classes/net/jpountz/util/darwin/${{ matrix.arch }}/liblz4-java.dylib
if-no-files-found: error
windows:
name: Windows natives (windows/amd64)
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Setup Zulu JDK 7
uses: actions/setup-java@v5
with:
distribution: zulu
java-version: '7'
- name: Setup Temurin JDK 21
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '21'
cache: maven
# See LZ4FrameIOStreamTest
- name: Download LZ4 CLI for tests
shell: powershell
run: |
curl.exe --fail-with-body --no-progress-meter --output lz4_win64.zip --location https://github.com/lz4/lz4/releases/download/v1.10.0/lz4_win64_v1_10_0.zip
mkdir lz4-cli
tar -x -v -f lz4_win64.zip -C lz4-cli lz4.exe
echo "$(Get-Location)\lz4-cli" >> "$env:GITHUB_PATH"
rm lz4_win64.zip
# Separate step because the change to PATH (through GITHUB_PATH) is not visible in the step which modified it
# See https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-commands#adding-a-system-path
- name: Check LZ4 CLI
run: lz4 -V
- name: Build (mvn verify)
shell: bash
run: |
./mvnw -B -V \
-Darch.id=amd64 \
-Dnative.cc=gcc \
verify
- name: Upload native library
uses: actions/upload-artifact@v4
with:
name: natives-windows-amd64
path: target/classes/net/jpountz/util/windows/amd64/liblz4-java.dll
if-no-files-found: error
assemble:
name: Assemble and deploy final all-platforms JAR
runs-on: ubuntu-latest
needs: [ linux, macos, windows ]
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Setup Zulu JDK 7
uses: actions/setup-java@v5
with:
distribution: zulu
java-version: '7'
# with central credentials
- name: Setup Temurin JDK 21 (publish)
uses: actions/setup-java@v5
if: github.event_name == 'release' || inputs.publish
with:
distribution: temurin
java-version: '21'
cache: maven
gpg-private-key: ${{ secrets.GPG_KEY }}
gpg-passphrase: GPG_PASSWORD
server-id: 'central'
server-username: CENTRAL_TOKEN_USERNAME
server-password: CENTRAL_TOKEN_PASSWORD
# without central credentials
- name: Setup Temurin JDK 21
uses: actions/setup-java@v5
if: github.event_name != 'release' && !inputs.publish
with:
distribution: temurin
java-version: '21'
cache: maven
- name: Download natives
uses: actions/download-artifact@v4
with:
path: assemble/natives
# Note: downloads all artifacts; we will merge their folder contents
- name: Prepare target/classes with collected natives
shell: bash
run: |
rm -rf target/classes/net/jpountz/util || true
shopt -s nullglob
for dir in assemble/natives/*; do
base="$(basename "$dir")"
# Expect names like natives-linux-amd64, natives-darwin-aarch64, natives-windows-amd64
os="${base#natives-}"
arch="${os#*-}"; os="${os%%-*}"
case "$os" in
linux) ext=so ;;
darwin) ext=dylib ;;
windows) ext=dll ;;
*) echo "Unknown OS in artifact: $base" >&2; continue ;;
esac
dest="target/classes/net/jpountz/util/$os/$arch"
mkdir -p "$dest"
if [ -f "$dir/liblz4-java.$ext" ]; then
cp -f "$dir/liblz4-java.$ext" "$dest/"
else
found="$(find "$dir" -type f -name "liblz4-java.$ext" | head -n1)"
if [ -n "$found" ]; then
cp -f "$found" "$dest/"
else
echo "No lib found in $dir" >&2
fi
fi
done
echo "Contents of target/classes/net/jpountz/util:"
find target/classes/net/jpountz/util -type f -print
# with maven central
- name: Build and deploy with Maven
run: ./mvnw -B -V -Pdeploy,-native-linux deploy
if: github.event_name == 'release' || inputs.publish
env:
CENTRAL_TOKEN_USERNAME: ${{ secrets.CENTRAL_TOKEN_USERNAME }}
CENTRAL_TOKEN_PASSWORD: ${{ secrets.CENTRAL_TOKEN_PASSWORD }}
GPG_PASSWORD: ${{ secrets.GPG_PASSWORD }}
# without maven central
- name: Build with Maven
run: ./mvnw -B -V -P-native-linux verify
if: github.event_name != 'release' && !inputs.publish
- name: Upload final JAR
uses: actions/upload-artifact@v4
with:
name: lz4-java-all-platforms
path: target/lz4-java-*.jar
if-no-files-found: error