nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 autoreconfHook,
4 dejagnu,
5 mkAppleDerivation,
6 stdenv,
7 testers,
8 texinfo,
9
10 # test suite depends on dejagnu which cannot be used during bootstrapping
11 # dejagnu also requires tcl which can't be built statically at the moment
12 doCheck ? !(stdenv.hostPlatform.isStatic),
13}:
14
15mkAppleDerivation (finalAttrs: {
16 releaseName = "libffi";
17
18 outputs = [
19 "out"
20 "dev"
21 "man"
22 "info"
23 ];
24
25 patches = [
26 # Clang 18 requires that no non-private symbols by defined after cfi_startproc. Apply the upstream libffi fix.
27 ./patches/llvm-18-compatibility.patch
28 # Fix a memory leak when using the trampoline dylib. See https://github.com/libffi/libffi/pull/621#discussion_r955298301.
29 ./patches/fix-tramponline-memory-leak.patch
30 ];
31
32 # Make sure libffi is using the trampolines dylib in this package not the system one.
33 postPatch = ''
34 substituteInPlace src/closures.c --replace-fail /usr/lib "$out/lib"
35 '';
36
37 enableParallelBuilding = true;
38
39 nativeBuildInputs = [
40 autoreconfHook
41 texinfo
42 ];
43
44 configurePlatforms = [
45 "build"
46 "host"
47 ];
48
49 configureFlags = [
50 "--with-gcc-arch=generic" # no detection of -march= or -mtune=
51 "--enable-builddir=build"
52 ];
53
54 postConfigure = ''
55 # Use Apple’s configuration instead of the one generated by the `configure` script.
56 cp darwin/include/fficonfig_${stdenv.hostPlatform.darwinArch}.h build/fficonfig.h
57 cp darwin/include/ffitarget_${
58 if stdenv.hostPlatform.isAarch64 then "arm64" else "x86"
59 }.h build/include/ffitarget.h
60 # Use `macCatalyst` instead of `iosmac` to avoid errors due to invalid availability annotations.
61 substitute darwin/include/ffi.h build/include/ffi.h \
62 --replace-fail iosmac macCatalyst
63 '';
64
65 postBuild = lib.optionalString stdenv.hostPlatform.isAarch64 ''
66 $CC -Os -Wl,-allowable_client,! -Wl,-not_for_dyld_shared_cache -Wl,-no_compact_unwind \
67 src/aarch64/trampoline.S -dynamiclib -o libffi-trampolines.dylib \
68 -Iinclude -Ibuild -Ibuild/include \
69 -install_name "$out/lib/libffi-trampoline.dylib" -Wl,-compatibility_version,1 -Wl,-current_version,1
70 '';
71
72 postInstall =
73 # The Darwin SDK puts the headers in `include/ffi`. Add a symlink for compatibility.
74 ''
75 ln -s "$dev/include" "$dev/include/ffi"
76 ''
77 # Install the trampoline dylib since it is build manually.
78 + lib.optionalString stdenv.hostPlatform.isAarch64 ''
79 cp libffi-trampolines.dylib "$out/lib/libffi-trampolines.dylib"
80 '';
81
82 preCheck = ''
83 # The tests use -O0 which is not compatible with -D_FORTIFY_SOURCE.
84 NIX_HARDENING_ENABLE=''${NIX_HARDENING_ENABLE/fortify3/}
85 NIX_HARDENING_ENABLE=''${NIX_HARDENING_ENABLE/fortify/}
86 '';
87
88 dontStrip = stdenv.hostPlatform != stdenv.buildPlatform; # Don't run the native `strip' when cross-compiling.
89
90 inherit doCheck;
91
92 nativeCheckInputs = [ dejagnu ];
93
94 passthru = {
95 tests = {
96 pkg-config = testers.hasPkgConfigModules {
97 package = finalAttrs.finalPackage;
98 };
99 };
100 };
101
102 meta = {
103 description = "Foreign function call interface library";
104 longDescription = ''
105 The libffi library provides a portable, high level programming
106 interface to various calling conventions. This allows a
107 programmer to call any function specified by a call interface
108 description at run-time.
109
110 FFI stands for Foreign Function Interface. A foreign function
111 interface is the popular name for the interface that allows code
112 written in one language to call code written in another
113 language. The libffi library really only provides the lowest,
114 machine dependent layer of a fully featured foreign function
115 interface. A layer must exist above libffi that handles type
116 conversions for values passed between the two languages.
117 '';
118 homepage = "https://github.com/apple-oss-distributions/libffi/";
119 license = lib.licenses.mit;
120 pkgConfigModules = [ "libffi" ];
121 };
122})