core/pkgs/by-name/xc/xcbuild/wrapper.nix
2024-05-13 11:34:52 -04:00

168 lines
5.1 KiB
Nix

{ lib, stdenv, makeWrapper, writeText, writeTextFile, runCommand, callPackage
, CoreServices, ImageIO, CoreGraphics
, xcodePlatform ? stdenv.targetPlatform.xcodePlatform or "MacOSX"
, xcodeVer ? stdenv.targetPlatform.xcodeVer or "9.4.1"
, sdkVer ? stdenv.targetPlatform.darwinSdkVersion or "10.12"
, productBuildVer ? null
}:
let
toolchainName = "com.apple.dt.toolchain.XcodeDefault";
sdkName = "${xcodePlatform}${sdkVer}";
xcrunSdkName = lib.toLower xcodePlatform;
# TODO: expose MACOSX_DEPLOYMENT_TARGET in nix so we can use it here.
sdkBuildVersion = "17E189";
xcodeSelectVersion = "2349";
xcbuild = callPackage ./default.nix {
inherit CoreServices ImageIO CoreGraphics stdenv;
};
toolchains = callPackage ./toolchains.nix {
inherit toolchainName stdenv;
};
sdks = callPackage ./sdks.nix {
inherit toolchainName sdkName xcodePlatform sdkVer productBuildVer;
};
platforms = callPackage ./platforms.nix {
inherit sdks xcodePlatform stdenv;
};
xcconfig = writeText "nix.xcconfig" ''
SDKROOT=${sdkName}
'';
xcode-select = writeText "xcode-select" ''
#!${stdenv.shell}
while [ $# -gt 0 ]; do
case "$1" in
-h | --help) ;; # noop
-s | --switch) shift;; # noop
-r | --reset) ;; # noop
-v | --version) echo xcode-select version ${xcodeSelectVersion} ;;
-p | -print-path | --print-path) echo @DEVELOPER_DIR@ ;;
--install) ;; # noop
esac
shift
done
'';
xcrun = writeTextFile {
name = "xcrun";
executable = true;
destination = "/bin/xcrun";
text = ''
#!${stdenv.shell}
args=( "$@" )
# If an SDK was requested, check that it matches.
for ((i = 0; i < ''${#args[@]}; i++)); do
case "''${args[i]}" in
--sdk | -sdk)
i=$((i + 1))
if [[ "''${args[i]}" != '${xcrunSdkName}' ]]; then
echo >&2 "xcodebuild: error: SDK \"''${args[i]}\" cannot be located."
exit 1
fi
;;
esac
done
while [ $# -gt 0 ]; do
case "$1" in
--sdk | -sdk) shift ;;
--toolchain | -toolchain) shift ;;
--find | -find | -f)
shift
command -v $1 || exit 1 ;;
--log | -log) ;; # noop
--verbose | -verbose) ;; # noop
--no-cache | -no-cache) ;; # noop
--kill-cache | -kill-cache) ;; # noop
--show-sdk-path | -show-sdk-path)
echo ${sdks}/${sdkName}.sdk ;;
--show-sdk-platform-path | -show-sdk-platform-path)
echo ${platforms}/${xcodePlatform}.platform ;;
--show-sdk-version | -show-sdk-version)
echo ${sdkVer} ;;
--show-sdk-build-version | -show-sdk-build-version)
echo ${sdkBuildVersion} ;;
*) break ;;
esac
shift
done
if ! [[ -z "$@" ]]; then
exec "$@"
fi
'';
checkPhase = ''
${stdenv.shellDryRun} "$target"
'';
};
in
runCommand "xcodebuild-${xcbuild.version}" {
nativeBuildInputs = [ makeWrapper ];
inherit (xcbuild) meta;
# ensure that the toolchain goes in PATH
propagatedBuildInputs = [ "${toolchains}/XcodeDefault.xctoolchain" ];
passthru = {
inherit xcbuild xcrun;
toolchain = "${toolchains}/XcodeDefault.xctoolchain";
sdk = "${sdks}/${sdkName}";
platform = "${platforms}/${xcodePlatform}.platform";
};
preferLocalBuild = true;
} ''
mkdir -p $out/bin
ln -s $out $out/usr
mkdir -p $out/Library/Xcode
ln -s ${xcbuild}/Library/Xcode/Specifications $out/Library/Xcode/Specifications
ln -s ${platforms} $out/Platforms
ln -s ${toolchains} $out/Toolchains
mkdir -p $out/Applications/Xcode.app/Contents
ln -s $out $out/Applications/Xcode.app/Contents/Developer
# The native xcodebuild command supports an invocation like "xcodebuild -version -sdk" without specifying the specific SDK, so we simulate this by
# detecting this case and simulating the output; printing the header and appending the normal output via appending the sdk version to the positional
# arguments we pass through to the wrapped xcodebuild.
makeWrapper ${xcbuild}/bin/xcodebuild $out/bin/xcodebuild \
--add-flags "-xcconfig ${xcconfig}" \
--add-flags "DERIVED_DATA_DIR=." \
--set DEVELOPER_DIR "$out" \
--set SDKROOT ${sdkName} \
--run '[ "$#" -eq 2 ] && [ "$1" = "-version" ] && [ "$2" = "-sdk" ] && echo ${sdkName}.sdk - macOS ${sdkVer} \(macosx${sdkVer}\) && set -- "$@" "${sdkName}"' \
--run '[ "$1" = "-version" ] && [ "$#" -eq 1 ] && (echo Xcode ${xcodeVer}; echo Build version ${sdkBuildVersion}) && exit 0' \
--run '[ "$1" = "-license" ] && exit 0'
substitute ${xcode-select} $out/bin/xcode-select \
--subst-var-by DEVELOPER_DIR $out/Applications/Xcode.app/Contents/Developer
chmod +x $out/bin/xcode-select
cp ${xcrun}/bin/xcrun $out/bin/xcrun
for bin in PlistBuddy actool builtin-copy builtin-copyPlist \
builtin-copyStrings builtin-copyTiff \
builtin-embeddedBinaryValidationUtility \
builtin-infoPlistUtility builtin-lsRegisterURL \
builtin-productPackagingUtility builtin-validationUtility \
lsbom plutil; do
ln -s ${xcbuild}/bin/$bin $out/bin/$bin
done
fixupPhase
''