Skip to content

Refactoring for MSVC and IntelLLVM #5

Refactoring for MSVC and IntelLLVM

Refactoring for MSVC and IntelLLVM #5

Workflow file for this run

name: CI
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master ]
pull_request:
branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build-linux:
name: Linux ${{ matrix.HOST }} ${{ matrix.CONFIGURE_OPTIONS }} \
${{ matrix.MEVAL }} ${{ matrix.LIBFFI_TEST_OPTIMIZATION }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
# ---------- existing x86-64 variants ----------
- runner: ubuntu-latest
HOST: x86_64-pc-linux-gnu
MEVAL: 'export CC=clang CXX=clang++'
- runner: ubuntu-latest
HOST: i386-pc-linux-gnu
MEVAL: 'export CC="gcc -m32" CXX="g++ -m32"'
- runner: ubuntu-latest
HOST: x86_64-pc-linux-gnu
CONFIGURE_OPTIONS: "--disable-shared"
- runner: ubuntu-latest
HOST: x86_64-pc-linux-gnu
CONFIGURE_OPTIONS: "--enable-shared"
- runner: ubuntu-latest
HOST: x86_64-pc-linux-gnu
CONFIGURE_OPTIONS: "--disable-exec-static-tramp"
# ---------- new native arm64 build ----------
- runner: ubuntu-22.04-arm # or ubuntu-24.04-arm
HOST: aarch64-unknown-linux-gnu
MEVAL: 'export CC=clang CXX=clang++'
steps:
- uses: actions/checkout@v4
- env:
MEVAL: ${{ matrix.MEVAL }}
HOST: ${{ matrix.HOST }}
LDFLAGS: ${{ matrix.LDFLAGS }}
RUNTESTFLAGS: ${{ matrix.RUNTESTFLAGS }}
CONFIGURE_OPTIONS: ${{ matrix.CONFIGURE_OPTIONS }}
QEMU_LD_PREFIX: ${{ matrix.QEMU_LD_PREFIX }}
QEMU_CPU: ${{ matrix.QEMU_CPU }}
run: |
if test x"$MEVAL" != x; then eval ${MEVAL}; fi
./.ci/install.sh
./.ci/build.sh
build-macos:
name: MacOS ${{ matrix.platform }} ${{ matrix.compilers }}
runs-on: ${{ matrix.platform }}
strategy:
fail-fast: false
matrix:
platform: [macos-13, macos-14, macos-15]
compilers: [CC=gcc-15 CXX=g++-15, CC=clang CXX=g++-15]
steps:
- run: git config --global core.autocrlf input
- uses: actions/checkout@v4
- run: ./.ci/install.sh
- run: ${{ matrix.compilers }} ./.ci/build.sh
build-non-msvc:
name: Windows ${{ matrix.width }}-bit ${{ matrix.compiler }}
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
include:
# Cygwin 32-bit
- host: i686-pc-cygwin
width: 32
arch: x86
target: i686-pc-cygwin
gcc_prefix: /usr/i686-pc-cygwin
compiler: gcc
- host: i686-pc-cygwin
width: 32
arch: x86
target: i686-pc-cygwin
gcc_prefix: /usr/i686-pc-cygwin
compiler: clang
# MinGW-w64 64-bit
- host: x86_64-w64-mingw32
width: 64
arch: x64
target: x86_64-w64-mingw32
gcc_prefix: /usr/${{ github.workspace }}/mingw64 # unused but keeps the table homogeneous
compiler: clang
- host: x86_64-w64-mingw32
width: 64
arch: x64
target: x86_64-w64-mingw32
gcc_prefix: /usr/${{ github.workspace }}/mingw64 # unused but keeps the table homogeneous
compiler: gcc
steps:
- run: git config --global core.autocrlf input
- uses: actions/checkout@v4
# ──────────────────────────────── Cygwin & tool-chains ────────────────────────────────
- uses: egor-tensin/setup-cygwin@v4
with:
# gcc / g++ are needed so Clang can reuse their start-files & libraries
packages: >
wget make dejagnu automake autoconf libtool texinfo unzip dos2unix
clang gcc-core gcc-g++
cygwin32-gcc-core cygwin32-gcc-g++ cygwin32-runtime cygwin32-libgcc1
# ──────────────────────────────── Common environment ────────────────────────────────
- name: Export build env
shell: bash
run: |
echo "GCC_PREFIX=${{ matrix.gcc_prefix }}" >> $GITHUB_ENV
echo "CC=${{ matrix.compiler }} --target=${{ matrix.target }} -B${{ matrix.gcc_prefix }}/bin \
-L${{ matrix.gcc_prefix }}/lib -I${{ matrix.gcc_prefix }}/include" >> $GITHUB_ENV
echo "CXX=${{ matrix.compiler }} --target=${{ matrix.target }} -B${{ matrix.gcc_prefix }}/bin \
-L${{ matrix.gcc_prefix }}/lib -I${{ matrix.gcc_prefix }}/include" >> $GITHUB_ENV
# make sure the cross-gcc bin dir is found *before* /usr/bin (64-bit)
echo "${{ matrix.gcc_prefix }}/bin" >> $GITHUB_PATH
# ──────────────────────────────── Pick version from configure.ac ─────────────────────
- id: ver
name: Read libffi version
shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}'
run: |
cd "$(cygpath $RUNNER_WORKSPACE)/libffi"
version=$(sed -nE 's/^AC_INIT\(\[libffi\],[[:space:]]*\[([^]]+)\].*/\1/p' configure.ac)
[[ $version ]] || { echo "Could not parse version"; exit 1; }
echo "version=$version" >> "$GITHUB_OUTPUT"
# ──────────────────────────────── Build & test ───────────────────────────────────────
- name: Build and test
shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}'
run: |
set -euo pipefail
cd "$(cygpath $RUNNER_WORKSPACE)/libffi"
wget https://rl.gl/cli/rlgl-windows-amd64.zip
unzip rlgl-windows-amd64.zip
autoreconf -fvi
./configure \
--enable-shared \
--build=${{ matrix.host }} --host=${{ matrix.host }} \
CPPFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" \
CFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL"
make
# sanity-check
file */.libs/*ffi-*.dll
TERM=none DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci GCC_COLORS= make check || true
./rlgl/rlgl.exe l --key=0LIBFFI-0LIBFFI-0LIBFFI-0LIBFFI https://rl.gl
./rlgl/rlgl.exe e \
-l project=libffi \
-l sha=${GITHUB_SHA:0:7} \
-l CC=${{ matrix.compiler }} \
-l host=${{ matrix.host }} \
--policy=https://github.com/libffi/rlgl-policy.git $(find . -name libffi.log)
build-msvc:
name: Windows ${{ matrix.width }}-bit Visual C++
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
include:
- host: i686-pc-cygwin
width: 32
arch: x86
tools: amd64_x86
- host: x86_64-w64-mingw32
width: 64
arch: x64
tools: amd64
steps:
- run: git config --global core.autocrlf input
- uses: actions/checkout@v4
- uses: egor-tensin/setup-cygwin@v4
with:
platform: x64
packages: wget make dejagnu automake autoconf libtool texinfo unzip dos2unix
- uses: ilammy/msvc-dev-cmd@v1.13.0
with:
arch: ${{ matrix.tools }}
- name: Read libffi version from configure.ac
id: ver
shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}'
run: |
cd $(cygpath $RUNNER_WORKSPACE)/libffi
# Pull the second bracketed field from the AC_INIT line.
# Example line: AC_INIT([libffi],[3.5.0],[http://…])
ls -l
grep AC_INIT configure.ac
ver=$(sed -nE 's/^AC_INIT\(\[libffi\],[[:space:]]*\[([^]]+)\].*/\1/p' configure.ac)
[[ -n "$ver" ]] || { echo "Could not parse version!"; exit 1; }
echo "version=$ver" >> "$GITHUB_OUTPUT"
- name: Build and test
run: |
cd $(cygpath $RUNNER_WORKSPACE)/libffi
wget https://rl.gl/cli/rlgl-windows-amd64.zip
unzip rlgl-windows-amd64.zip
autoreconf -f -v -i
./configure \
--enable-shared \
--build="${{ matrix.host }}" --host="${{ matrix.host }}" \
--disable-docs \
CC="$(pwd)/msvcc.sh -m${{ matrix.width }}" \
CXX="$(pwd)/msvcc.sh -m${{ matrix.width }}" \
LD="link" \
LDFLAGS="-no-undefined" \
CPP="cl -nologo -EP" \
CXXCPP="cl -nologo -EP" \
CPPFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" \
CFLAGS="-DFFI_BUILDING_DLL -DUSE_STATIC_RTL" \
AR='$(pwd)/.ci/ar-lib lib' \
NM='dumpbin -symbols' STRIP=':' \
$DEBUG_ARG || cat */config.log
make
find ./ -type f -name 'libffi*'
ls -l */.libs
cp $(find . -name 'libffi-?.dll') ${{ matrix.host }}/testsuite/
find ./ -name ffi.h
TERM=none DEJAGNU=$(pwd)/.ci/site.exp BOARDSDIR=$(pwd)/.ci GCC_COLORS= make check || true
./rlgl/rlgl.exe l --key=0LIBFFI-0LIBFFI-0LIBFFI-0LIBFFI https://rl.gl
./rlgl/rlgl.exe e \
-l project=libffi \
-l sha=${GITHUB_SHA:0:7} \
-l CC=msvcc.sh \
-l host=${{ matrix.host }} \
--policy=https://github.com/libffi/rlgl-policy.git $(find . -name libffi.log)
shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}'
- name: Add meta information to DLL
shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}'
run: |
cd $(cygpath $RUNNER_WORKSPACE)/libffi
# Deconstruct the libffi version
ver=${{ steps.ver.outputs.version }}
echo "$ver"
base=${ver%%-*}
rc=${ver#*-}
[[ $rc == "$ver" ]] && rc="" # no rc? rc=""
maj=$(cut -d. -f1 <<<"$base")
min=$(cut -d. -f2 <<<"$base")
pat=$(cut -d. -f3 <<<"$base")
# Decide on build number
if [[ $rc =~ ^rc([0-9]+)$ ]]; then
build=${BASH_REMATCH[1]} # rc1 → 1
else
build=0
fi
# Use rcedit to edit the DLLs resources
wget -O rcedit.exe https://github.com/electron/rcedit/releases/download/v2.0.0/rcedit-${{ matrix.arch }}.exe
chmod +x ./rcedit.exe
dll_filename=libffi-8.dll
./rcedit.exe "${{ matrix.host }}"/.libs/$dll_filename \
--set-file-version "$maj.$min.$pat.$build" \
--set-product-version "$maj.$min.$pat.$build" \
--set-version-string "CompanyName" "https://github.com/libffi/libffi" \
--set-version-string "FileDescription" "Portable foreign function interface library (${{ matrix.arch }})" \
--set-version-string "ProductName" "libffi" \
--set-version-string "FileVersion" "${{ steps.ver.outputs.version }}" \
--set-version-string "LegalCopyright" "Copyright (c) 1996-2025 Anthony Green and others" \
--set-version-string "OriginalFilename" "$dll_filename"
- name: Create binary distribution
shell: C:\tools\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}'
run: |
cd $(cygpath $RUNNER_WORKSPACE)/libffi
set -euxo pipefail
pkgdir="libffi-${{ steps.ver.outputs.version }}-x86-${{ matrix.width }}bit-msvc-binaries"
mkdir -p "$pkgdir"
# Copy libraries, headers, and licence into the *same* directory
cp "${{ matrix.host }}"/.libs/libffi-8.* "$pkgdir/"
cp "${{ matrix.host }}"/include/*.h "$pkgdir/"
cp LICENSE "$pkgdir/"
- name: Upload artefact
uses: actions/upload-artifact@v4
with:
name: libffi-${{ steps.ver.outputs.version }}-x86-${{ matrix.width }}bit-msvc-binaries
path: libffi-${{ steps.ver.outputs.version }}-x86-${{ matrix.width }}bit-msvc-binaries
if-no-files-found: error
- name: Upload to GitHub Release
if: github.ref_type == 'tag'
uses: softprops/action-gh-release@v2
with:
files: libffi-${{ steps.ver.outputs.version }}-x86-${{ matrix.width }}bit-msvc-binaries.zip
build-android:
name: Android ${{ matrix.host }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
host: [armv7a-linux-androideabi, aarch64-linux-android, i686-linux-android, x86_64-linux-android]
steps:
- run: git config --global core.autocrlf input
- uses: actions/checkout@v4
- run: ./.ci/install.sh
- env:
HOST: ${{ matrix.HOST }}
ANDROID_API_LEVEL: 23
CONFIGURE_OPTIONS: "--disable-shared --disable-multi-os-directory" # fixes warning about unsupported -print-multi-os-directory with clang
run: |
# Relevant documentation:
# https://developer.android.com/ndk/guides/other_build_systems
# https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md
export TOOLCHAIN="${ANDROID_NDK_ROOT}"/toolchains/llvm/prebuilt/linux-x86_64
export CC="${TOOLCHAIN}"/bin/${HOST}${ANDROID_API_LEVEL}-clang
export CXX="${TOOLCHAIN}"/bin/${HOST}${ANDROID_API_LEVEL}-clang++
export CC_FOR_TARGET="${TOOLCHAIN}"/bin/${HOST}${ANDROID_API_LEVEL}-clang
export CXX_FOR_TARGET="${TOOLCHAIN}"/bin/${HOST}${ANDROID_API_LEVEL}-clang++
export LD="${TOOLCHAIN}"/bin/ld.lld
export AR="${TOOLCHAIN}"/bin/llvm-ar
export AS="${CC}"
export RANLIB="${TOOLCHAIN}"/bin/llvm-ranlib
export STRIP="${TOOLCHAIN}"/bin/llvm-strip
export NM="${TOOLCHAIN}"/bin/llvm-nm
export OBJDUMP="${TOOLCHAIN}"/bin/llvm-objdump
./.ci/build.sh