# Windows on ARM64, clang/lld based. Must precede %%mingw_package_header. %global mingw_build_ucrtarm64 1 # win32/win64 build with the clang supplement drivers: the qemu-ga MSI ships # DLLs from clang/compiler-rt toolchain sysroots, where the GNU runtime DLLs # do not exist, so nothing shipped there may import them. %global mingw_toolchain_win32 clang %global mingw_toolchain_win64 clang %{?mingw_package_header} Name: mingw-libffi Version: 3.5.2 Release: 3.2%{?dist} Summary: A portable foreign function interface library for MinGW License: MIT URL: http://sourceware.org/libffi Source0: https://github.com/libffi/libffi/releases/download/v%{version}/libffi-%{version}.tar.gz BuildArch: noarch BuildRequires: make # The win32/win64 clang columns dispatch to the supplement drivers only from # 152-1.9 on. Headers and CRT must be named; the GCC targets get them # through gcc. compiler-rt and libunwind: the drivers always link # -rtlib=compiler-rt -unwindlib=libunwind, and mock installs no weak # dependencies. BuildRequires: mingw32-filesystem >= 152-1.9 BuildRequires: mingw32-binutils BuildRequires: mingw32-clang BuildRequires: mingw32-headers BuildRequires: mingw32-crt BuildRequires: mingw32-compiler-rt >= 22.1.8 BuildRequires: mingw32-libunwind >= 22.1.8 BuildRequires: mingw64-filesystem >= 152-1.9 BuildRequires: mingw64-binutils BuildRequires: mingw64-clang BuildRequires: mingw64-headers BuildRequires: mingw64-crt BuildRequires: mingw64-compiler-rt >= 22.1.8 BuildRequires: mingw64-libunwind >= 22.1.8 # No gcc for this target: the toolchain is clang, lld and the llvm-* tools. # Headers and CRT must be named; the other targets get them through gcc. BuildRequires: ucrtarm64-filesystem >= 152 BuildRequires: ucrtarm64-clang BuildRequires: ucrtarm64-llvm-tools BuildRequires: ucrtarm64-headers BuildRequires: ucrtarm64-crt # The drivers always link -rtlib=compiler-rt (__chkstk lives there) and # -unwindlib=libunwind; libunwind only arrives through ucrtarm64-clang's # Recommends chain, and mock installs no weak dependencies. BuildRequires: ucrtarm64-compiler-rt >= 22.1.8 BuildRequires: ucrtarm64-libunwind >= 22.1.8 %description Foreign function interface library for MinGW. # Win32 %package -n mingw32-libffi Summary: A portable foreign function interface library for MinGW %description -n mingw32-libffi Foreign function interface library for MinGW. # Win32 static %package -n mingw32-libffi-static Summary: A portable foreign function interface static library for MinGW %description -n mingw32-libffi-static Foreign function interface static library for MinGW. # Win64 %package -n mingw64-libffi Summary: A portable foreign function interface library for MinGW %description -n mingw64-libffi Foreign function interface library for MinGW. # Win64 static %package -n mingw64-libffi-static Summary: A portable foreign function interface static library for MinGW %description -n mingw64-libffi-static Foreign function interface static library for MinGW. # Windows on ARM64 %package -n ucrtarm64-libffi Summary: A portable foreign function interface library for MinGW %description -n ucrtarm64-libffi Foreign function interface library for MinGW. # Windows on ARM64 static %package -n ucrtarm64-libffi-static Summary: A portable foreign function interface static library for MinGW %description -n ucrtarm64-libffi-static Foreign function interface static library for MinGW. %{?mingw_debug_package} %prep %autosetup -p1 -n libffi-%{version} %build # --disable-symvers for every lld-linked target: lld's MinGW driver has no # --version-script, and the DLL exports the same API by auto-export. With # the win32/win64 columns on the clang drivers that is now all of them # except ucrt64. MINGW32_CONFIGURE_ARGS="--disable-symvers" MINGW64_CONFIGURE_ARGS="--disable-symvers" UCRTARM64_CONFIGURE_ARGS="--disable-symvers" %mingw_configure --enable-shared %mingw_make %install %mingw_make_install rm -rf %{buildroot}%{mingw32_infodir} rm -rf %{buildroot}%{mingw64_infodir} rm -rf %{buildroot}%{ucrtarm64_infodir} rm -rf %{buildroot}%{mingw32_mandir} rm -rf %{buildroot}%{mingw64_mandir} rm -rf %{buildroot}%{ucrtarm64_mandir} # Drop all .la files find %{buildroot} -name "*.la" -delete %check # Verify the ucrtarm64 output with the llvm-* tools only: GNU nm/ar/objdump # silently mis-read AArch64 PE/COFF. %%check runs after the BRP passes. # 1. configure.host picked the AArch64 Windows port. aarch64*-*-mingw* maps to # TARGET=ARM_WIN64 / TARGETDIR=aarch64, and because clang is not the # "microsoft" compiler vendor the sources are the GAS-syntax ffi.c + sysv.S, # not the armasm-syntax win64_armasm.S which only MSVC's assembler accepts. grep -E '^TARGET = ARM_WIN64$' build_ucrtarm64/Makefile grep -E '^TARGETDIR = aarch64$' build_ucrtarm64/Makefile grep -E '^TARGET_OBJ =' build_ucrtarm64/Makefile grep -E '^TARGET_OBJ =.*[[:space:]]src/aarch64/ffi\.lo([[:space:]]|$)' build_ucrtarm64/Makefile grep -E '^TARGET_OBJ =.*[[:space:]]src/aarch64/sysv\.lo([[:space:]]|$)' build_ucrtarm64/Makefile # ... and neither the armasm variant nor another architecture's port slipped in. ! grep -E '^TARGET_OBJ =.*(win64_armasm|src/(x86|arm|mips|powerpc|s390|sparc|riscv)/)' \ build_ucrtarm64/Makefile ! test -e build_ucrtarm64/src/aarch64/win64_armasm.lo # 2. The objects built from that assembly are AArch64 PE, and carry the entry # points the rest of the library calls into. libtool puts the PIC copy in # .libs and the static copy next to the .lo; check whichever exists. for b in ffi sysv ; do o=build_ucrtarm64/src/aarch64/.libs/$b.o test -f "$o" || o=build_ucrtarm64/src/aarch64/$b.o %{ucrtarm64_objdump} -f "$o" %{ucrtarm64_objdump} -f "$o" | grep -q 'file format coff-arm64' %{ucrtarm64_objdump} -f "$o" | grep -q 'architecture: aarch64' # The assembly half must define the call entry point. if [ "$b" = sysv ]; then %{ucrtarm64_nm} --defined-only "$o" | grep 'ffi_call_SYSV' fi done # 3. The DLL really is a Windows ARM64 PE, stripped, with its debuginfo split # out; if %%mingw_debug_package went missing it would ship unstripped. %{ucrtarm64_objdump} -f %{buildroot}%{ucrtarm64_bindir}/libffi-8.dll %{ucrtarm64_objdump} -f %{buildroot}%{ucrtarm64_bindir}/libffi-8.dll \ | grep -q 'file format coff-arm64' %{ucrtarm64_objdump} -h %{buildroot}%{ucrtarm64_bindir}/libffi-8.dll \ | grep -q '\.gnu_debuglink' test -f %{buildroot}%{_prefix}/lib/debug%{ucrtarm64_bindir}/libffi-8.dll.debug # 4. Every shipped archive still carries its ar symbol index. for a in %{buildroot}%{ucrtarm64_libdir}/libffi.a \ %{buildroot}%{ucrtarm64_libdir}/libffi.dll.a ; do magic=$(od -A n -t x1 -N 10 "$a" | tr -d ' \n') echo "archive $a: header $magic" test "$magic" = "213c617263683e0a2f20" %{ucrtarm64_nm} --print-armap "$a" \ | awk '$1 == "ffi_call" && $2 == "in" { found = 1 } END { exit !found }' done # 5. Link test: a real libffi consumer has to compile and link against what is # about to be packaged, both against the import library and statically. # The executables cannot be run here (x86_64 host, ARM64 PE), so only the # link and the resulting file format/imports are checked. armcheck=%{_builddir}/ucrtarm64-libffi-check rm -rf $armcheck mkdir -p $armcheck cat > $armcheck/t.c <<'EOF' #include #include static int add (int a, int b) { return a + b; } int main (void) { ffi_cif cif; ffi_type *args[2]; void *values[2]; int a = 40, b = 2; ffi_arg rc = 0; args[0] = &ffi_type_sint; args[1] = &ffi_type_sint; values[0] = &a; values[1] = &b; if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, args) != FFI_OK) return 1; ffi_call (&cif, FFI_FN (add), &rc, values); printf ("%%d\n", (int) rc); return (int) rc == 42 ? 0 : 1; } EOF # Shared: -lffi resolves to libffi.dll.a -> libffi-8.dll. %{ucrtarm64_cc} -I%{buildroot}%{ucrtarm64_includedir} $armcheck/t.c \ -L%{buildroot}%{ucrtarm64_libdir} -lffi -o $armcheck/t.exe %{ucrtarm64_objdump} -f $armcheck/t.exe %{ucrtarm64_objdump} -f $armcheck/t.exe | grep -q 'file format coff-arm64' %{ucrtarm64_objdump} -p $armcheck/t.exe | grep -i 'libffi-8.dll' # Static: the same program against ucrtarm64-libffi-static, which must not # end up importing the DLL. Capture the imports first: under "!" a crashed # objdump would count as "pattern absent" and pass. %{ucrtarm64_cc} -I%{buildroot}%{ucrtarm64_includedir} $armcheck/t.c \ -L%{buildroot}%{ucrtarm64_libdir} -Wl,-Bstatic -lffi -Wl,-Bdynamic \ -o $armcheck/t-static.exe %{ucrtarm64_objdump} -f $armcheck/t-static.exe %{ucrtarm64_objdump} -f $armcheck/t-static.exe | grep -q 'file format coff-arm64' imports=$(%{ucrtarm64_objdump} -p $armcheck/t-static.exe) if echo "$imports" | grep -qi 'libffi-8.dll'; then echo "ERROR: the static link imports libffi-8.dll" >&2 exit 1 fi # 5b. The win32/win64 DLLs are now linked with the clang supplement drivers, # and the qemu-ga MSI ships them from sysroots where the GNU runtime DLLs # do not exist: no libgcc, libssp or libunwind import may appear. The # same consumer links through the same drivers. for t in i686-w64-mingw32 x86_64-w64-mingw32 ; do case $t in i686-*) wbin_rel=%{mingw32_bindir} wlibdir=%{buildroot}%{mingw32_libdir} wincdir=%{buildroot}%{mingw32_includedir} peformat=pei-i386 ;; x86_64-*) wbin_rel=%{mingw64_bindir} wlibdir=%{buildroot}%{mingw64_libdir} wincdir=%{buildroot}%{mingw64_includedir} peformat=pei-x86-64 ;; esac wbindir=%{buildroot}$wbin_rel $t-objdump -f $wbindir/libffi-8.dll | grep -q "file format $peformat" $t-objdump -h $wbindir/libffi-8.dll | grep -q '\.gnu_debuglink' test -f %{buildroot}%{_prefix}/lib/debug$wbin_rel/libffi-8.dll.debug imports=$($t-objdump -p $wbindir/libffi-8.dll | grep 'DLL Name' || :) echo "$t libffi-8.dll imports: $imports" if echo "$imports" | grep -qiE 'libgcc|libssp|libunwind'; then echo "ERROR: $t libffi-8.dll imports a GNU runtime or unwinder DLL" >&2 exit 1 fi $t-clang -I$wincdir $armcheck/t.c -L$wlibdir -lffi -o $armcheck/t-$t.exe $t-objdump -f $armcheck/t-$t.exe | grep -q "file format $peformat" $t-objdump -p $armcheck/t-$t.exe | grep -i 'libffi-8.dll' $t-clang -I$wincdir $armcheck/t.c -L$wlibdir \ -Wl,-Bstatic -lffi -Wl,-Bdynamic -o $armcheck/t-static-$t.exe imports=$($t-objdump -p $armcheck/t-static-$t.exe) if echo "$imports" | grep -qi 'libffi-8.dll'; then echo "ERROR: the $t static link imports libffi-8.dll" >&2 exit 1 fi done rm -rf "$armcheck" # 6. The pkg-config file is what everything downstream finds libffi with. # --modversion short-circuits pkgconf, so --cflags/--libs get their own # invocation; --cflags comes out empty because the personality drops -I # for system include paths. ( PKG_CONFIG_LIBDIR=%{buildroot}%{ucrtarm64_libdir}/pkgconfig:%{buildroot}%{ucrtarm64_datadir}/pkgconfig export PKG_CONFIG_LIBDIR ucrtarm64-pkg-config --exists --print-errors libffi ucrtarm64-pkg-config --modversion libffi ucrtarm64-pkg-config --cflags --libs libffi ucrtarm64-pkg-config --libs libffi | grep -- '-lffi' ) %files -n mingw32-libffi %license LICENSE %{mingw32_bindir}/libffi-8.dll %{mingw32_includedir}/ffi.h %{mingw32_includedir}/ffitarget.h %{mingw32_libdir}/libffi.dll.a %{mingw32_libdir}/pkgconfig/libffi.pc %files -n mingw32-libffi-static %{mingw32_libdir}/libffi.a %files -n mingw64-libffi %license LICENSE %{mingw64_bindir}/libffi-8.dll %{mingw64_includedir}/ffi.h %{mingw64_includedir}/ffitarget.h %{mingw64_libdir}/libffi.dll.a %{mingw64_libdir}/pkgconfig/libffi.pc %files -n mingw64-libffi-static %{mingw64_libdir}/libffi.a %files -n ucrtarm64-libffi %license LICENSE %{ucrtarm64_bindir}/libffi-8.dll %{ucrtarm64_includedir}/ffi.h %{ucrtarm64_includedir}/ffitarget.h %{ucrtarm64_libdir}/libffi.dll.a %{ucrtarm64_libdir}/pkgconfig/libffi.pc %files -n ucrtarm64-libffi-static %{ucrtarm64_libdir}/libffi.a %changelog * Mon Aug 24 2026 Erik Berg - 3.5.2-3.2 - Build the win32 and win64 targets with the clang supplement drivers: the qemu-ga MSI ships libffi-8.dll from clang/compiler-rt toolchain sysroots, where the GNU runtime DLLs do not exist - Symbol versioning is disabled for the lld-linked targets, which is now all of them except ucrt64; new checks assert the x86 DLLs import no libgcc, libssp or libunwind, and link a consumer through the drivers * Thu Aug 06 2026 Erik Berg - 3.5.2-3.1 - Add libffi for the Windows on ARM64 target * Thu Jul 16 2026 Fedora Release Engineering - 3.5.2-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild * Fri Jan 16 2026 Fedora Release Engineering - 3.5.2-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild * Mon Sep 08 2025 Sandro Mani - 3.5.2-1 - Update to 3.5.2 * Thu Jul 24 2025 Fedora Release Engineering - 3.5.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild * Sun Jun 15 2025 Sandro Mani - 3.5.1-1 - Update to 3.5.1 * Tue May 13 2025 Sandro Mani - 3.4.8-1 - Update to 3.4.8 * Wed Mar 05 2025 Sandro Mani - 3.4.7-1 - Update to 3.4.7 * Fri Jan 17 2025 Fedora Release Engineering - 3.4.6-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild * Thu Jul 18 2024 Fedora Release Engineering - 3.4.6-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild * Fri Mar 22 2024 Sandro Mani - 3.4.6-1 - Update to 3.4.6 * Thu Jan 25 2024 Fedora Release Engineering - 3.4.4-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild * Sun Jan 21 2024 Fedora Release Engineering - 3.4.4-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild * Thu Jul 20 2023 Fedora Release Engineering - 3.4.4-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild * Thu Jan 19 2023 Fedora Release Engineering - 3.4.4-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild * Sat Nov 12 2022 Sandro Mani - 3.4.4-1 - Update to 3.4.4 * Thu Jul 21 2022 Fedora Release Engineering - 3.4.2-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild * Fri Mar 25 2022 Sandro Mani - 3.4.2-3 - Rebuild with mingw-gcc-12 * Thu Jan 20 2022 Fedora Release Engineering - 3.4.2-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild * Fri Jul 30 2021 Sandro Mani - 3.4.2-1 - Update to 3.4.2 * Thu Jul 22 2021 Fedora Release Engineering - 3.1-12 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild * Tue Jan 26 2021 Fedora Release Engineering - 3.1-11 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild * Tue Jul 28 2020 Fedora Release Engineering - 3.1-10 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild * Wed Feb 12 2020 Sandro Mani - 3.1-9 - Drop libffi-3.1-fix-include-path.patch, it just breaks the pkgconfig file * Wed Jan 29 2020 Fedora Release Engineering - 3.1-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild * Wed Aug 14 2019 Fabiano FidĂȘncio - 3.1-7 - Add the same patches from its native counter part, rhbz#1740764 * Thu Jul 25 2019 Fedora Release Engineering - 3.1-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild * Fri Feb 01 2019 Fedora Release Engineering - 3.1-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild * Fri Jul 13 2018 Fedora Release Engineering - 3.1-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild * Thu Feb 08 2018 Fedora Release Engineering - 3.1-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild * Wed Jul 26 2017 Fedora Release Engineering - 3.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild * Tue Jun 20 2017 Kalev Lember - 3.1-1 - Update to 3.1 - Use license macro * Fri Feb 10 2017 Fedora Release Engineering - 3.0.13-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild * Thu Feb 04 2016 Fedora Release Engineering - 3.0.13-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild * Wed Jun 17 2015 Fedora Release Engineering - 3.0.13-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild * Sat Jun 07 2014 Fedora Release Engineering - 3.0.13-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild * Sat Aug 03 2013 Fedora Release Engineering - 3.0.13-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild * Sat Jun 15 2013 Erik van Pienbroek - 3.0.13-3 - Rebuild to resolve InterlockedCompareExchange regression in mingw32 libraries * Fri May 31 2013 Erik van Pienbroek - 3.0.13-2 - Rebuild against latest mingw-filesystem * Sun May 5 2013 Erik van Pienbroek - 3.0.13-1 - Update to 3.0.13 * Thu Feb 14 2013 Fedora Release Engineering - 3.0.11-0.5.rc2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild * Fri Jul 20 2012 Fedora Release Engineering - 3.0.11-0.4.rc2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild * Fri May 11 2012 Eric Smith - 3.0.11-0.3.rc2 - Added static subpackages * Sat Mar 10 2012 Erik van Pienbroek - 3.0.11-0.2.rc2 - Added win64 support * Thu Mar 08 2012 Erik van Pienbroek - 3.0.11-0.1.rc2 - Update to 3.0.11-rc2 - Removed .la file * Tue Mar 06 2012 Kalev Lember - 3.0.9-5 - Renamed the source package to mingw-libffi (#800427) - Spec clean up * Mon Feb 27 2012 Erik van Pienbroek - 3.0.9-4 - Rebuild against the mingw-w64 toolchain * Fri Jan 13 2012 Fedora Release Engineering - 3.0.9-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild * Tue Feb 08 2011 Fedora Release Engineering - 3.0.9-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild * Sat Oct 9 2010 Paolo Bonzini - 3.0.9-1 - Created.