1{stdenv, xcodewrapper}:
2{ name
3, src
4, sdkVersion ? "10.2"
5, target ? null
6, configuration ? null
7, scheme ? null
8, sdk ? null
9, xcodeFlags ? ""
10, release ? false
11, codeSignIdentity ? null
12, certificateFile ? null
13, certificatePassword ? null
14, provisioningProfile ? null
15, generateIPA ? false
16, generateXCArchive ? false
17, enableWirelessDistribution ? false
18, installURL ? null
19, bundleId ? null
20, version ? null
21, title ? null
22}:
23
24assert release -> codeSignIdentity != null && certificateFile != null && certificatePassword != null && provisioningProfile != null;
25assert enableWirelessDistribution -> installURL != null && bundleId != null && version != null && title != null;
26
27let
28 # Set some default values here
29
30 _target = if target == null then name else target;
31
32 _configuration = if configuration == null
33 then
34 if release then "Release" else "Debug"
35 else configuration;
36
37 _sdk = if sdk == null
38 then
39 if release then "iphoneos" + sdkVersion else "iphonesimulator" + sdkVersion
40 else sdk;
41
42 # The following is to prevent repetition
43 deleteKeychain = ''
44 security default-keychain -s login.keychain
45 security delete-keychain $keychainName
46 '';
47in
48stdenv.mkDerivation {
49 name = stdenv.lib.replaceChars [" "] [""] name;
50 inherit src;
51 buildInputs = [ xcodewrapper ];
52 buildPhase = ''
53 ${stdenv.lib.optionalString release ''
54 export HOME=/Users/$(whoami)
55 keychainName="$(basename $out)"
56
57 # Create a keychain
58 security create-keychain -p "" $keychainName
59 security default-keychain -s $keychainName
60 security unlock-keychain -p "" $keychainName
61
62 # Import the certificate into the keychain
63 security import ${certificateFile} -k $keychainName -P "${certificatePassword}" -A
64
65 # Grant the codesign utility permissions to read from the keychain
66 security set-key-partition-list -S apple-tool:,apple: -s -k "" $keychainName
67
68 # Determine provisioning ID
69 PROVISIONING_PROFILE=$(grep UUID -A1 -a ${provisioningProfile} | grep -o "[-A-Za-z0-9]\{36\}")
70
71 if [ ! -f "$HOME/Library/MobileDevice/Provisioning Profiles/$PROVISIONING_PROFILE.mobileprovision" ]
72 then
73 # Copy provisioning profile into the home directory
74 mkdir -p "$HOME/Library/MobileDevice/Provisioning Profiles"
75 cp ${provisioningProfile} "$HOME/Library/MobileDevice/Provisioning Profiles/$PROVISIONING_PROFILE.mobileprovision"
76 fi
77
78 # Check whether the identity can be found
79 security find-identity -p codesigning $keychainName
80 ''}
81
82 # Do the building
83 xcodebuild -target ${_target} -configuration ${_configuration} ${stdenv.lib.optionalString (scheme != null) "-scheme ${scheme}"} -sdk ${_sdk} TARGETED_DEVICE_FAMILY="1, 2" ONLY_ACTIVE_ARCH=NO CONFIGURATION_TEMP_DIR=$TMPDIR CONFIGURATION_BUILD_DIR=$out ${if generateXCArchive then "archive" else ""} ${xcodeFlags} ${if release then ''"CODE_SIGN_IDENTITY=${codeSignIdentity}" PROVISIONING_PROFILE=$PROVISIONING_PROFILE OTHER_CODE_SIGN_FLAGS="--keychain $HOME/Library/Keychains/$keychainName-db"'' else ""}
84
85 ${stdenv.lib.optionalString release ''
86 ${stdenv.lib.optionalString generateIPA ''
87 # Produce an IPA file
88 xcrun -sdk iphoneos PackageApplication -v $out/*.app -o "$out/${name}.ipa"
89
90 # Add IPA to Hydra build products
91 mkdir -p $out/nix-support
92 echo "file binary-dist \"$(echo $out/*.ipa)\"" > $out/nix-support/hydra-build-products
93
94 ${stdenv.lib.optionalString enableWirelessDistribution ''
95 appname=$(basename $out/*.ipa .ipa)
96 sed -e "s|@INSTALL_URL@|${installURL}?bundleId=${bundleId}\&version=${version}\&title=$appname|" ${./install.html.template} > $out/$appname.html
97 echo "doc install \"$out/$appname.html\"" >> $out/nix-support/hydra-build-products
98 ''}
99 ''}
100
101 # Delete our temp keychain
102 ${deleteKeychain}
103 ''}
104 '';
105
106 failureHook = stdenv.lib.optionalString release deleteKeychain;
107
108 installPhase = "true";
109}