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