lol
1{ lib, stdenv, makeWrapper, writeText, writeTextFile, runCommand, callPackage
2, CoreServices, ImageIO, CoreGraphics
3, xcodePlatform ? stdenv.targetPlatform.xcodePlatform or "MacOSX"
4, xcodeVer ? stdenv.targetPlatform.xcodeVer or "9.4.1"
5, sdkVer ? stdenv.targetPlatform.darwinSdkVersion or "10.12" }:
6
7let
8
9 toolchainName = "com.apple.dt.toolchain.XcodeDefault";
10 sdkName = "${xcodePlatform}${sdkVer}";
11 xcrunSdkName = lib.toLower xcodePlatform;
12
13 # TODO: expose MACOSX_DEPLOYMENT_TARGET in nix so we can use it here.
14 sdkBuildVersion = "17E189";
15 xcodeSelectVersion = "2349";
16
17 xcbuild = callPackage ./default.nix {
18 inherit CoreServices ImageIO CoreGraphics stdenv;
19 };
20
21 toolchains = callPackage ./toolchains.nix {
22 inherit toolchainName stdenv;
23 };
24
25 sdks = callPackage ./sdks.nix {
26 inherit toolchainName sdkName xcodePlatform;
27 version = sdkVer;
28 };
29
30 platforms = callPackage ./platforms.nix {
31 inherit sdks xcodePlatform stdenv;
32 };
33
34 xcconfig = writeText "nix.xcconfig" ''
35 SDKROOT=${sdkName}
36 '';
37
38 xcode-select = writeText "xcode-select" ''
39#!${stdenv.shell}
40while [ $# -gt 0 ]; do
41 case "$1" in
42 -h | --help) ;; # noop
43 -s | --switch) shift;; # noop
44 -r | --reset) ;; # noop
45 -v | --version) echo xcode-select version ${xcodeSelectVersion} ;;
46 -p | -print-path | --print-path) echo @DEVELOPER_DIR@ ;;
47 --install) ;; # noop
48 esac
49 shift
50done
51 '';
52
53 xcrun = writeTextFile {
54 name = "xcrun";
55 executable = true;
56 destination = "/bin/xcrun";
57 text = ''
58#!${stdenv.shell}
59args=( "$@" )
60
61# If an SDK was requested, check that it matches.
62for ((i = 0; i < ''${#args[@]}; i++)); do
63 case "''${args[i]}" in
64 --sdk | -sdk)
65 i=$((i + 1))
66 if [[ "''${args[i]}" != '${xcrunSdkName}' ]]; then
67 echo >&2 "xcodebuild: error: SDK \"''${args[i]}\" cannot be located."
68 exit 1
69 fi
70 ;;
71 esac
72done
73
74while [ $# -gt 0 ]; do
75 case "$1" in
76 --sdk | -sdk) shift ;;
77 --toolchain | -toolchain) shift ;;
78 --find | -find | -f)
79 shift
80 command -v $1 ;;
81 --log | -log) ;; # noop
82 --verbose | -verbose) ;; # noop
83 --no-cache | -no-cache) ;; # noop
84 --kill-cache | -kill-cache) ;; # noop
85 --show-sdk-path | -show-sdk-path)
86 echo ${sdks}/${sdkName}.sdk ;;
87 --show-sdk-platform-path | -show-sdk-platform-path)
88 echo ${platforms}/${xcodePlatform}.platform ;;
89 --show-sdk-version | -show-sdk-version)
90 echo ${sdkVer} ;;
91 --show-sdk-build-version | -show-sdk-build-version)
92 echo ${sdkBuildVersion} ;;
93 *) break ;;
94 esac
95 shift
96done
97
98if ! [[ -z "$@" ]]; then
99 exec "$@"
100fi
101 '';
102 checkPhase = ''
103 ${stdenv.shellDryRun} "$target"
104 '';
105 };
106
107in
108
109runCommand "xcodebuild-${xcbuild.version}" {
110 nativeBuildInputs = [ makeWrapper ];
111 inherit (xcbuild) meta;
112
113 # ensure that the toolchain goes in PATH
114 propagatedBuildInputs = [ "${toolchains}/XcodeDefault.xctoolchain" ];
115
116 passthru = {
117 inherit xcbuild xcrun;
118 toolchain = "${toolchains}/XcodeDefault.xctoolchain";
119 sdk = "${sdks}/${sdkName}";
120 platform = "${platforms}/${xcodePlatform}.platform";
121 };
122
123 preferLocalBuild = true;
124} ''
125 mkdir -p $out/bin
126
127 ln -s $out $out/usr
128
129 mkdir -p $out/Library/Xcode
130 ln -s ${xcbuild}/Library/Xcode/Specifications $out/Library/Xcode/Specifications
131
132 ln -s ${platforms} $out/Platforms
133 ln -s ${toolchains} $out/Toolchains
134
135 mkdir -p $out/Applications/Xcode.app/Contents
136 ln -s $out $out/Applications/Xcode.app/Contents/Developer
137
138 # The native xcodebuild command supports an invocation like "xcodebuild -version -sdk" without specifying the specific SDK, so we simulate this by
139 # detecting this case and simulating the output; printing the header and appending the normal output via appending the sdk version to the positional
140 # arguments we pass through to the wrapped xcodebuild.
141 makeWrapper ${xcbuild}/bin/xcodebuild $out/bin/xcodebuild \
142 --add-flags "-xcconfig ${xcconfig}" \
143 --add-flags "DERIVED_DATA_DIR=." \
144 --set DEVELOPER_DIR "$out" \
145 --set SDKROOT ${sdkName} \
146 --run '[ "$#" -eq 2 ] && [ "$1" = "-version" ] && [ "$2" = "-sdk" ] && echo ${sdkName}.sdk - macOS ${sdkVer} \(macosx${sdkVer}\) && set -- "$@" "${sdkName}"' \
147 --run '[ "$1" = "-version" ] && [ "$#" -eq 1 ] && (echo Xcode ${xcodeVer}; echo Build version ${sdkBuildVersion}) && exit 0' \
148 --run '[ "$1" = "-license" ] && exit 0'
149
150 substitute ${xcode-select} $out/bin/xcode-select \
151 --subst-var-by DEVELOPER_DIR $out/Applications/Xcode.app/Contents/Developer
152 chmod +x $out/bin/xcode-select
153
154 cp ${xcrun}/bin/xcrun $out/bin/xcrun
155
156 for bin in PlistBuddy actool builtin-copy builtin-copyPlist \
157 builtin-copyStrings builtin-copyTiff \
158 builtin-embeddedBinaryValidationUtility \
159 builtin-infoPlistUtility builtin-lsRegisterURL \
160 builtin-productPackagingUtility builtin-validationUtility \
161 lsbom plutil; do
162 ln -s ${xcbuild}/bin/$bin $out/bin/$bin
163 done
164
165 fixupPhase
166''