2013-01-07 16:52:42 +01:00
{ stdenv , xcodewrapper }:
{ name
, src
2018-01-05 11:40:34 +01:00
, sdkVersion ? " 1 1 . 2 "
2013-01-07 16:52:42 +01:00
, target ? null
, configuration ? null
, scheme ? null
, sdk ? null
, xcodeFlags ? " "
, release ? false
, codeSignIdentity ? null
, certificateFile ? null
, certificatePassword ? null
, provisioningProfile ? null
2018-03-22 14:33:15 +01:00
, signMethod ? null
2013-01-07 16:52:42 +01:00
, generateIPA ? false
, generateXCArchive ? false
2014-08-01 18:34:18 +02:00
, enableWirelessDistribution ? false
, installURL ? null
, bundleId ? null
, version ? null
, title ? null
2013-01-07 16:52:42 +01:00
} :
2018-03-22 14:33:15 +01:00
assert release -> codeSignIdentity != null && certificateFile != null && certificatePassword != null && provisioningProfile != null && signMethod != null ;
2014-08-01 18:34:18 +02:00
assert enableWirelessDistribution -> installURL != null && bundleId != null && version != null && title != null ;
2013-01-07 16:52:42 +01:00
let
# Set some default values here
_target = if target == null then name else target ;
_configuration = if configuration == null
then
if release then " R e l e a s e " else " D e b u g "
else configuration ;
_sdk = if sdk == null
then
2013-03-13 13:02:19 +01:00
if release then " i p h o n e o s " + sdkVersion else " i p h o n e s i m u l a t o r " + sdkVersion
2013-01-07 16:52:42 +01:00
else sdk ;
# The following is to prevent repetition
2014-10-27 17:24:35 +01:00
deleteKeychain = ''
security default-keychain - s login . keychain
security delete-keychain $ keychainName
'' ;
2013-01-07 16:52:42 +01:00
in
stdenv . mkDerivation {
2013-03-21 14:11:58 +01:00
name = stdenv . lib . replaceChars [ " " ] [ " " ] name ;
inherit src ;
2013-01-07 16:52:42 +01:00
buildInputs = [ xcodewrapper ] ;
buildPhase = ''
$ { stdenv . lib . optionalString release ''
export HOME = /Users / $ ( whoami )
keychainName = " $ ( b a s e n a m e $ o u t ) "
# Create a keychain
security create-keychain - p " " $ keychainName
security default-keychain - s $ keychainName
security unlock-keychain - p " " $ keychainName
# Import the certificate into the keychain
security import $ { certificateFile } - k $ keychainName - P " ${ certificatePassword } " - A
2017-01-27 10:50:36 +01:00
# Grant the codesign utility permissions to read from the keychain
security set-key-partition-list - S apple-tool:,apple: - s - k " " $ keychainName
2013-01-07 16:52:42 +01:00
# Determine provisioning ID
2014-07-18 16:40:15 +02:00
PROVISIONING_PROFILE = $ ( grep UUID - A1 - a $ { provisioningProfile } | grep - o " [ - A - Z a - z 0 - 9 ] \{ 3 6 \} " )
2013-01-07 16:52:42 +01:00
if [ ! - f " $ H O M E / L i b r a r y / M o b i l e D e v i c e / P r o v i s i o n i n g P r o f i l e s / $ P R O V I S I O N I N G _ P R O F I L E . m o b i l e p r o v i s i o n " ]
then
# Copy provisioning profile into the home directory
mkdir - p " $ H O M E / L i b r a r y / M o b i l e D e v i c e / P r o v i s i o n i n g P r o f i l e s "
cp $ { provisioningProfile } " $ H O M E / L i b r a r y / M o b i l e D e v i c e / P r o v i s i o n i n g P r o f i l e s / $ P R O V I S I O N I N G _ P R O F I L E . m o b i l e p r o v i s i o n "
fi
# Check whether the identity can be found
security find-identity - p codesigning $ keychainName
'' }
# Do the building
2018-01-05 11:40:34 +01:00
export LD = clang # To avoid problem with -isysroot parameter that is unrecognized by the stock ld. Comparison with an impure build shows that it uses clang instead. Ugly, but it works
2018-03-22 14:33:15 +01:00
xcodebuild - target $ { _target } - configuration $ { _configuration } $ { stdenv . lib . optionalString ( scheme != null ) " - s c h e m e ${ scheme } " } - sdk $ { _sdk } TARGETED_DEVICE_FAMILY = " 1 , 2 " ONLY_ACTIVE_ARCH = NO CONFIGURATION_TEMP_DIR = $ TMPDIR CONFIGURATION_BUILD_DIR = $ out $ { if generateIPA || generateXCArchive then " - a r c h i v e P a t h \" ${ name } . x c a r c h i v e \" a r c h i v e " else " " } $ { if release then '' P R O V I S I O N I N G _ P R O F I L E = $P R O V I S I O N I N G _ P R O F I L E O T H E R _ C O D E _ S I G N _ F L A G S = " - - k e y c h a i n $H O M E / L i b r a r y / K e y c h a i n s / $k e y c h a i n N a m e - d b " '' else " " } $ { xcodeFlags }
2018-01-05 11:40:34 +01:00
2013-01-07 16:52:42 +01:00
$ { stdenv . lib . optionalString release ''
$ { stdenv . lib . optionalString generateIPA ''
2018-03-22 14:33:15 +01:00
# Create export plist file
cat > " ${ name } . p l i s t " < < EOF
< ? xml version = " 1 . 0 " encoding = " U T F - 8 " ? >
< ! DOCTYPE plist PUBLIC " - / / A p p l e / / D T D P L I S T 1 . 0 / / E N " " h t t p : / / w w w . a p p l e . c o m / D T D s / P r o p e r t y L i s t - 1 . 0 . d t d " >
< plist version = " 1 . 0 " >
<dict>
<key> provisioningProfiles < /key >
<dict>
<key> $ { bundleId } < /key >
<string> $ PROVISIONING_PROFILE < /string >
< /dict >
<key> method < /key >
<string> $ { signMethod } < /string >
$ { stdenv . lib . optionalString ( signMethod == " e n t e r p r i s e " || signMethod == " a d - h o c " ) ''
<key> compileBitcode < /key >
< false / >
'' }
< /dict >
< /plist >
EOF
2013-01-07 16:52:42 +01:00
# Produce an IPA file
2018-03-22 14:33:15 +01:00
xcodebuild - exportArchive - archivePath " ${ name } . x c a r c h i v e " - exportOptionsPlist " ${ name } . p l i s t " - exportPath $ out
2013-03-15 16:18:45 +01:00
# Add IPA to Hydra build products
mkdir - p $ out/nix-support
2013-03-21 14:11:58 +01:00
echo " f i l e b i n a r y - d i s t \" $ ( e c h o $ o u t / * . i p a ) \" " > $ out/nix-support/hydra-build-products
2014-08-01 18:34:18 +02:00
$ { stdenv . lib . optionalString enableWirelessDistribution ''
appname = $ ( basename $ out /* . i p a . i p a )
sed - e " s | @ I N S T A L L _ U R L @ | ${ installURL } ? b u n d l e I d = ${ bundleId } \& a m p ; v e r s i o n = ${ version } \& a m p ; t i t l e = $ a p p n a m e | " $ { ./install.html.template } > $ out / $ appname . html
2014-08-04 11:23:25 +02:00
echo " d o c i n s t a l l \" $ o u t / $ a p p n a m e . h t m l \" " > > $ out/nix-support/hydra-build-products
2014-08-01 18:34:18 +02:00
'' }
2013-01-07 16:52:42 +01:00
'' }
# Delete our temp keychain
$ { deleteKeychain }
'' }
'' ;
failureHook = stdenv . lib . optionalString release deleteKeychain ;
installPhase = " t r u e " ;
}