nixpkgs/pkgs/os-specific/darwin/apple-sdk-11.0/apple_sdk.nix
netfox 815d6c0d3e
apple-framework-System: fix System.tbd dangling symbolic link
Contrarily to the other frameworks, System framework's TBD file
is a symlink pointing to `${MacOSX-SDK}/usr/lib/libSystem.B.tbd`.

This produces an error when using the framework, as:

  1. The original file is not copied into the output directory
  2. Even if it was copied, the relative path wouldn't match

Resulting in the symlink being broken and the linker failing when
trying to link `-framework System`.

The fix applied consists in replacing the symbolic link with the
actual file, as this is easier than fixing the link and doesn't
seem to produce any side effects.
2023-04-12 14:37:48 +02:00

269 lines
10 KiB
Nix

{ lib, stdenvNoCC, buildPackages, fetchurl, xar, cpio, pkgs, python3, pbzx, MacOSX-SDK }:
# TODO: reorganize to make this just frameworks, and move libs to default.nix
let
stdenv = stdenvNoCC;
standardFrameworkPath = name: private:
"/System/Library/${lib.optionalString private "Private"}Frameworks/${name}.framework";
mkDepsRewrites = deps:
let
mergeRewrites = x: y: {
prefix = lib.mergeAttrs (x.prefix or {}) (y.prefix or {});
const = lib.mergeAttrs (x.const or {}) (y.const or {});
};
rewriteArgs = { prefix ? {}, const ? {} }: lib.concatLists (
(lib.mapAttrsToList (from: to: [ "-p" "${from}:${to}" ]) prefix) ++
(lib.mapAttrsToList (from: to: [ "-c" "${from}:${to}" ]) const)
);
rewrites = depList: lib.fold mergeRewrites {}
(map (dep: dep.tbdRewrites)
(lib.filter (dep: dep ? tbdRewrites) depList));
in
lib.escapeShellArgs (rewriteArgs (rewrites (builtins.attrValues deps)));
mkFramework = { name, deps, private ? false }:
let self = stdenv.mkDerivation {
pname = "apple-${lib.optionalString private "private-"}framework-${name}";
version = MacOSX-SDK.version;
dontUnpack = true;
# because we copy files from the system
preferLocalBuild = true;
disallowedRequisites = [ MacOSX-SDK ];
nativeBuildInputs = [ buildPackages.darwin.rewrite-tbd ];
installPhase = ''
mkdir -p $out/Library/Frameworks
cp -r ${MacOSX-SDK}${standardFrameworkPath name private} $out/Library/Frameworks
if [[ -d ${MacOSX-SDK}/usr/lib/swift/${name}.swiftmodule ]]; then
mkdir -p $out/lib/swift
cp -r -t $out/lib/swift \
${MacOSX-SDK}/usr/lib/swift/${name}.swiftmodule \
${MacOSX-SDK}/usr/lib/swift/libswift${name}.tbd
fi
# Fix and check tbd re-export references
chmod u+w -R $out
find $out -name '*.tbd' -type f | while read tbd; do
echo "Fixing re-exports in $tbd"
rewrite-tbd \
-p ${standardFrameworkPath name private}/:$out/Library/Frameworks/${name}.framework/ \
-p /usr/lib/swift/:$out/lib/swift/ \
${mkDepsRewrites deps} \
-r ${builtins.storeDir} \
"$tbd"
done
'';
propagatedBuildInputs = builtins.attrValues deps;
passthru = {
tbdRewrites = {
prefix."${standardFrameworkPath name private}/" = "${self}/Library/Frameworks/${name}.framework/";
};
};
meta = with lib; {
description = "Apple SDK framework ${name}";
maintainers = with maintainers; [ copumpkin ];
platforms = platforms.darwin;
};
};
in self;
framework = name: deps: mkFramework { inherit name deps; private = false; };
privateFramework = name: deps: mkFramework { inherit name deps; private = true; };
in rec {
libs = {
xpc = stdenv.mkDerivation {
name = "apple-lib-xpc";
dontUnpack = true;
installPhase = ''
mkdir -p $out/include
pushd $out/include >/dev/null
cp -r "${MacOSX-SDK}/usr/include/xpc" $out/include/xpc
cp "${MacOSX-SDK}/usr/include/launch.h" $out/include/launch.h
popd >/dev/null
'';
};
Xplugin = stdenv.mkDerivation {
name = "apple-lib-Xplugin";
dontUnpack = true;
propagatedBuildInputs = with frameworks; [
OpenGL ApplicationServices Carbon IOKit CoreGraphics CoreServices CoreText
];
installPhase = ''
mkdir -p $out/include $out/lib
ln -s "${MacOSX-SDK}/include/Xplugin.h" $out/include/Xplugin.h
cp ${MacOSX-SDK}/usr/lib/libXplugin.1.tbd $out/lib
ln -s libXplugin.1.tbd $out/lib/libXplugin.tbd
'';
};
utmp = stdenv.mkDerivation {
name = "apple-lib-utmp";
dontUnpack = true;
installPhase = ''
mkdir -p $out/include
pushd $out/include >/dev/null
ln -s "${MacOSX-SDK}/include/utmp.h"
ln -s "${MacOSX-SDK}/include/utmpx.h"
popd >/dev/null
'';
};
sandbox = stdenv.mkDerivation {
name = "apple-lib-sandbox";
dontUnpack = true;
dontBuild = true;
installPhase = ''
mkdir -p $out/include $out/lib
ln -s "${MacOSX-SDK}/usr/include/sandbox.h" $out/include/sandbox.h
cp "${MacOSX-SDK}/usr/lib/libsandbox.1.tbd" $out/lib
ln -s libsandbox.1.tbd $out/lib/libsandbox.tbd
'';
};
libDER = stdenv.mkDerivation {
name = "apple-lib-libDER";
dontUnpack = true;
installPhase = ''
mkdir -p $out/include
cp -r ${MacOSX-SDK}/usr/include/libDER $out/include
'';
};
simd = stdenv.mkDerivation {
name = "apple-lib-simd";
dontUnpack = true;
installPhase = ''
mkdir -p $out/include
cp -r ${MacOSX-SDK}/usr/include/simd $out/include
'';
};
};
frameworks = let
# Dependency map created by gen-frameworks.py.
generatedDeps = import ./frameworks.nix {
inherit frameworks libs;
};
# Additional dependencies that are not picked up by gen-frameworks.py.
# Some of these are simply private frameworks the generator does not see.
extraDeps = with libs; with frameworks; let
inherit (pkgs.darwin.apple_sdk_11_0) libnetwork;
libobjc = pkgs.darwin.apple_sdk_11_0.objc4;
in {
# Below this comment are entries migrated from before the generator was
# added. If, for a given framework, you are able to reverify the extra
# deps are really necessary on top of the generator deps, move it above
# this comment (and maybe document your findings).
AVFoundation = { inherit ApplicationServices AVFCapture AVFCore; };
Accelerate = { inherit CoreWLAN IOBluetooth; };
AddressBook = { inherit AddressBookCore ContactsPersistence libobjc; };
AppKit = { inherit AudioToolbox AudioUnit UIFoundation; };
AudioToolbox = { inherit AudioToolboxCore; };
AudioUnit = { inherit Carbon CoreAudio; };
Carbon = { inherit IOKit QuartzCore libobjc; };
CoreAudio = { inherit IOKit; };
CoreFoundation = { inherit libobjc; };
CoreGraphics = { inherit SystemConfiguration; };
CoreMIDIServer = { inherit CoreMIDI; };
CoreMedia = { inherit ApplicationServices AudioToolbox AudioUnit; };
CoreServices = { inherit CoreAudio NetFS ServiceManagement; };
CoreWLAN = { inherit SecurityFoundation; };
DiscRecording = { inherit IOKit libobjc; };
Foundation = { inherit SystemConfiguration libobjc; };
GameKit = { inherit GameCenterFoundation GameCenterUI GameCenterUICore ReplayKit; };
ICADevices = { inherit Carbon libobjc; };
IOBluetooth = { inherit CoreBluetooth; };
JavaScriptCore = { inherit libobjc; };
Kernel = { inherit IOKit; };
LinkPresentation = { inherit URLFormatting; };
MediaToolbox = { inherit AudioUnit; };
MetricKit = { inherit SignpostMetrics; };
Network = { inherit libnetwork; };
PCSC = { inherit CoreData; };
PassKit = { inherit PassKitCore; };
QTKit = { inherit CoreMedia CoreMediaIO MediaToolbox VideoToolbox; };
Quartz = { inherit QTKit; };
QuartzCore = { inherit ApplicationServices CoreImage CoreVideo Metal OpenCL libobjc; };
Security = { inherit IOKit libDER; };
TWAIN = { inherit Carbon; };
VideoDecodeAcceleration = { inherit CoreVideo; };
WebKit = { inherit ApplicationServices Carbon libobjc; };
};
# Overrides for framework derivations.
overrides = super: {
CoreFoundation = lib.overrideDerivation super.CoreFoundation (drv: {
setupHook = ./cf-setup-hook.sh;
});
# This framework doesn't exist in newer SDKs (somewhere around 10.13), but
# there are references to it in nixpkgs.
QuickTime = throw "QuickTime framework not available";
# Seems to be appropriate given https://developer.apple.com/forums/thread/666686
JavaVM = super.JavaNativeFoundation;
CoreVideo = lib.overrideDerivation super.CoreVideo (drv: {
installPhase = drv.installPhase + ''
# When used as a module, complains about a missing import for
# Darwin.C.stdint. Apparently fixed in later SDKs.
awk -i inplace '/CFBase.h/ { print "#include <stdint.h>" } { print }' \
$out/Library/Frameworks/CoreVideo.framework/Headers/CVBase.h
'';
});
System = lib.overrideDerivation super.System (drv: {
installPhase = drv.installPhase + ''
# Contrarily to the other frameworks, System framework's TBD file
# is a symlink pointing to ${MacOSX-SDK}/usr/lib/libSystem.B.tbd.
# This produces an error when installing the framework as:
# 1. The original file is not copied into the output directory
# 2. Even if it was copied, the relative path wouldn't match
# Thus, it is easier to replace the file than to fix the symlink.
cp --remove-destination ${MacOSX-SDK}/usr/lib/libSystem.B.tbd \
$out/Library/Frameworks/System.framework/Versions/B/System.tbd
'';
});
};
# Merge extraDeps into generatedDeps.
deps = generatedDeps // (
lib.mapAttrs
(name: deps: generatedDeps.${name} // deps)
extraDeps
);
# Create derivations, and add private frameworks.
bareFrameworks = (lib.mapAttrs framework deps) // (
lib.mapAttrs privateFramework (import ./private-frameworks.nix {
inherit frameworks;
libobjc = pkgs.darwin.apple_sdk_11_0.objc4;
})
);
in
# Apply derivation overrides.
bareFrameworks // overrides bareFrameworks;
}