From c6ff338e279a7eb63bddaa38388b4351c3536bc8 Mon Sep 17 00:00:00 2001 From: Sander van der Burg Date: Mon, 7 Jan 2013 18:22:10 +0100 Subject: [PATCH] Added package + build functions for Titanium SDK, a cross-platform mobile development kit --- .../mobile/titaniumenv/build-app.nix | 87 +++++++++++++++++++ .../mobile/titaniumenv/default.nix | 18 ++++ .../mobile/titaniumenv/examples/default.nix | 38 ++++++++ .../examples/emulate-kitchensink/default.nix | 10 +++ .../examples/kitchensink/default.nix | 24 +++++ .../examples/simulate-kitchensink/default.nix | 8 ++ .../mobile/titaniumenv/fixnativelibs.sed | 1 + .../mobile/titaniumenv/fixselfruntimev8.sed | 1 + .../mobile/titaniumenv/fixtiverify.sed | 1 + .../mobile/titaniumenv/titaniumsdk.nix | 57 ++++++++++++ pkgs/top-level/all-packages.nix | 6 +- 11 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 pkgs/development/mobile/titaniumenv/build-app.nix create mode 100644 pkgs/development/mobile/titaniumenv/default.nix create mode 100644 pkgs/development/mobile/titaniumenv/examples/default.nix create mode 100644 pkgs/development/mobile/titaniumenv/examples/emulate-kitchensink/default.nix create mode 100644 pkgs/development/mobile/titaniumenv/examples/kitchensink/default.nix create mode 100644 pkgs/development/mobile/titaniumenv/examples/simulate-kitchensink/default.nix create mode 100644 pkgs/development/mobile/titaniumenv/fixnativelibs.sed create mode 100644 pkgs/development/mobile/titaniumenv/fixselfruntimev8.sed create mode 100644 pkgs/development/mobile/titaniumenv/fixtiverify.sed create mode 100644 pkgs/development/mobile/titaniumenv/titaniumsdk.nix diff --git a/pkgs/development/mobile/titaniumenv/build-app.nix b/pkgs/development/mobile/titaniumenv/build-app.nix new file mode 100644 index 00000000000..0fd4929bda7 --- /dev/null +++ b/pkgs/development/mobile/titaniumenv/build-app.nix @@ -0,0 +1,87 @@ +{stdenv, androidsdk, titaniumsdk, xcodewrapper}: +{ appId, name, src, target, androidPlatformVersions ? [ "8" ] +, release ? false, androidKeyStore ? null, androidKeyAlias ? null, androidKeyStorePassword ? null +, iosKeyFile ? null, iosCertificateName ? null, iosCertificate ? null, iosCertificatePassword ? null +}: + +assert (release && target == "android") -> androidKeyStore != null && androidKeyAlias != null && androidKeyStorePassword != null; +assert (release && target == "iphone") -> iosKeyFile != null && iosCertificateName != null && iosCertificate != null && iosCertificatePassword != null; + +let + androidsdkComposition = androidsdk { + platformVersions = androidPlatformVersions; + useGoogleAPIs = true; + }; +in +stdenv.mkDerivation { + inherit name src; + + buildInputs = [] ++ stdenv.lib.optional (stdenv.system == "x86_64-darwin") xcodewrapper; + + buildPhase = '' + export HOME=$TMPDIR + + mkdir -p $out + + ${if target == "android" then + if release then + "${titaniumsdk}/mobilesdk/*/*/android/builder.py distribute ${name} ${androidsdkComposition}/libexec/android-sdk-* $(pwd) ${appId} ${androidKeyStore} ${androidKeyStorePassword} ${androidKeyAlias} $out" + else + "${titaniumsdk}/mobilesdk/*/*/android/builder.py build ${name} ${androidsdkComposition}/libexec/android-sdk-* $(pwd) ${appId}" + + else if target == "iphone" then + if release then + '' + export HOME=/Users/$(whoami) + export keychainName=$(basename $out) + + # Create a keychain with the component hash name (should always be unique) + security create-keychain -p "" $keychainName + security default-keychain -s $keychainName + security unlock-keychain -p "" $keychainName + security import ${iosCertificate} -k $keychainName -P "${iosCertificatePassword}" -A + + provisioningId=$(grep UUID -A1 -a ${iosKeyFile} | grep -o "[-A-Z0-9]\{36\}") + + # Ensure that the requested provisioning profile can be found + + if [ ! -f "$HOME/Library/MobileDevice/Provisioning Profiles" ] + then + mkdir -p "$HOME/Library/MobileDevice/Provisioning Profiles" + cp ${iosKeyFile} "$HOME/Library/MobileDevice/Provisioning Profiles/$provisioningId.mobileprovision" + fi + + ${titaniumsdk}/mobilesdk/*/*/iphone/builder.py adhoc 6.0 $(pwd) ${appId} ${name} "$provisioningId" "${iosCertificateName}" universal "$HOME/Library/Keychains/$keychainName" + + # Remove our generated keychain + + security delete-keychain $keychainName + '' + else + '' + # Copy all sources to the output store directory. + # Why? Debug application include *.js files, which are symlinked into their + # sources. If they are not copied, we have dangling references to the + # temp folder. + + cp -av * $out + cd $out + ${titaniumsdk}/mobilesdk/*/*/iphone/builder.py build 6.0 $(pwd) ${appId} ${name} + '' + + else throw "Target: ${target} is not supported!"} + ''; + + installPhase = '' + mkdir -p $out + + ${if target == "android" && release then "" + else + if target == "android" then + ''cp $(ls build/android/bin/*.apk | grep -v '\-unsigned.apk') $out'' + else if target == "iphone" && release then + "cp -av build/iphone/build/* $out" + else if target == "iphone" then "" + else throw "Target: ${target} is not supported!"} + ''; +} diff --git a/pkgs/development/mobile/titaniumenv/default.nix b/pkgs/development/mobile/titaniumenv/default.nix new file mode 100644 index 00000000000..8117b452d70 --- /dev/null +++ b/pkgs/development/mobile/titaniumenv/default.nix @@ -0,0 +1,18 @@ +{pkgs, pkgs_i686}: + +rec { + androidenv = pkgs.androidenv; + + xcodeenv = if pkgs.stdenv.system == "x86_64-darwin" then pkgs.xcodeenv else null; + + titaniumsdk = import ./titaniumsdk.nix { + inherit (pkgs) stdenv fetchurl unzip makeWrapper python jdk; + }; + + buildApp = import ./build-app.nix { + inherit (pkgs) stdenv; + inherit (androidenv) androidsdk; + inherit (xcodeenv) xcodewrapper; + inherit titaniumsdk; + }; +} diff --git a/pkgs/development/mobile/titaniumenv/examples/default.nix b/pkgs/development/mobile/titaniumenv/examples/default.nix new file mode 100644 index 00000000000..1526d4c4359 --- /dev/null +++ b/pkgs/development/mobile/titaniumenv/examples/default.nix @@ -0,0 +1,38 @@ +let + pkgs = import {}; + pkgs_i686 = import { system = "i686-linux"; }; +in +rec { + titaniumenv = import ./.. { + inherit pkgs pkgs_i686; + }; + + kitchensink_android = import ./kitchensink { + inherit titaniumenv; + inherit (pkgs) fetchgit; + target = "android"; + }; + + kitchensink_iphone = import ./kitchensink { + inherit titaniumenv; + inherit (pkgs) fetchgit; + target = "iphone"; + }; + + emulate_kitchensink = import ./emulate-kitchensink { + inherit (titaniumenv) androidenv; + kitchensink = kitchensink_android; + }; + + simulate_kitchensink_iphone = import ./simulate-kitchensink { + inherit (titaniumenv) xcodeenv; + kitchensink = kitchensink_iphone; + device = "iPhone"; + }; + + simulate_kitchensink_ipad = import ./simulate-kitchensink { + inherit (titaniumenv) xcodeenv; + kitchensink = kitchensink_iphone; + device = "iPad"; + }; +} diff --git a/pkgs/development/mobile/titaniumenv/examples/emulate-kitchensink/default.nix b/pkgs/development/mobile/titaniumenv/examples/emulate-kitchensink/default.nix new file mode 100644 index 00000000000..817aa5ab37f --- /dev/null +++ b/pkgs/development/mobile/titaniumenv/examples/emulate-kitchensink/default.nix @@ -0,0 +1,10 @@ +{androidenv, kitchensink}: + +androidenv.emulateApp { + name = "kitchensink"; + app = kitchensink; + platformVersion = "8"; + useGoogleAPIs = true; + package = "com.appcelerator.kitchensink"; + activity = "KitchensinkActivity"; +} diff --git a/pkgs/development/mobile/titaniumenv/examples/kitchensink/default.nix b/pkgs/development/mobile/titaniumenv/examples/kitchensink/default.nix new file mode 100644 index 00000000000..8e2b1df264a --- /dev/null +++ b/pkgs/development/mobile/titaniumenv/examples/kitchensink/default.nix @@ -0,0 +1,24 @@ +{titaniumenv, fetchgit, target, androidPlatformVersions ? [ "8" ]}: + +titaniumenv.buildApp { + name = "KitchenSink"; + appId = "com.appcelerator.kitchensink"; + src = fetchgit { + url = https://github.com/appcelerator/KitchenSink.git; + rev = "0f2c0b818034cc4e6867f0aa2afc98bf77dbff02"; + sha256 = "de31496cfb5625d7a193bbbc32a8021e4094ffab20ae13ef2e1583b0394d7c60"; + }; + + inherit target androidPlatformVersions; + + /*release = true; + androidKeyStore = /home/sander/keystore; + androidKeyAlias = "sander"; + androidKeyStorePassword = "foobar";*/ + + /*release = true; + iosKeyFile = /Users/sander/Downloads/profile.mobileprovision; + iosCertificateName = "My Company"; + iosCertificate = /Users/sander/Downloads/c.p12; + iosCertificatePassword = "";*/ +} diff --git a/pkgs/development/mobile/titaniumenv/examples/simulate-kitchensink/default.nix b/pkgs/development/mobile/titaniumenv/examples/simulate-kitchensink/default.nix new file mode 100644 index 00000000000..70ec534f6ae --- /dev/null +++ b/pkgs/development/mobile/titaniumenv/examples/simulate-kitchensink/default.nix @@ -0,0 +1,8 @@ +{xcodeenv, kitchensink, device}: + +xcodeenv.simulateApp { + name = "kitchensink"; + app = kitchensink; + inherit device; + baseDir = "build/iphone/build/Debug-iphonesimulator"; +} diff --git a/pkgs/development/mobile/titaniumenv/fixnativelibs.sed b/pkgs/development/mobile/titaniumenv/fixnativelibs.sed new file mode 100644 index 00000000000..76b330136b6 --- /dev/null +++ b/pkgs/development/mobile/titaniumenv/fixnativelibs.sed @@ -0,0 +1 @@ +s|\t\t\t\t\t\t\t\tapk_zip.write(native_lib, path_in_zip)|\t\t\t\t\t\t\t\tinfo = zipfile.ZipInfo(path_in_zip)\n\t\t\t\t\t\t\t\tinfo.compress_type = zipfile.ZIP_DEFLATED\n\t\t\t\t\t\t\t\tinfo.create_system = 3\n\t\t\t\t\t\t\t\tf = open(native_lib)\n\t\t\t\t\t\t\t\tapk_zip.writestr(info, f.read())\n\t\t\t\t\t\t\t\tf.close()| diff --git a/pkgs/development/mobile/titaniumenv/fixselfruntimev8.sed b/pkgs/development/mobile/titaniumenv/fixselfruntimev8.sed new file mode 100644 index 00000000000..c849aaa611c --- /dev/null +++ b/pkgs/development/mobile/titaniumenv/fixselfruntimev8.sed @@ -0,0 +1 @@ +s|apk_zip.write(os.path.join(lib_source_dir, fname), lib_dest_dir + fname)|info = zipfile.ZipInfo(lib_dest_dir + fname)\n\t\t\t\t\tinfo.compress_type = zipfile.ZIP_DEFLATED\n\t\t\t\t\tinfo.create_system = 3\n\t\t\t\t\tf = open(os.path.join(lib_source_dir, fname))\n\t\t\t\t\tapk_zip.writestr(info, f.read())\n\t\t\t\t\tf.close()| diff --git a/pkgs/development/mobile/titaniumenv/fixtiverify.sed b/pkgs/development/mobile/titaniumenv/fixtiverify.sed new file mode 100644 index 00000000000..8e1114769c8 --- /dev/null +++ b/pkgs/development/mobile/titaniumenv/fixtiverify.sed @@ -0,0 +1 @@ +s|apk_zip.write(os.path.join(lib_source_dir, 'libtiverify.so'), lib_dest_dir + 'libtiverify.so')|info = zipfile.ZipInfo(lib_dest_dir + 'libtiverify.so')\n\t\t\tinfo.compress_type = zipfile.ZIP_DEFLATED\n\t\t\tinfo.create_system = 3\n\t\t\tf = open(os.path.join(lib_source_dir, 'libtiverify.so'))\n\t\t\tapk_zip.writestr(info, f.read())\n\t\t\tf.close()| diff --git a/pkgs/development/mobile/titaniumenv/titaniumsdk.nix b/pkgs/development/mobile/titaniumenv/titaniumsdk.nix new file mode 100644 index 00000000000..5e1943b1bdc --- /dev/null +++ b/pkgs/development/mobile/titaniumenv/titaniumsdk.nix @@ -0,0 +1,57 @@ +{stdenv, fetchurl, unzip, makeWrapper, python, jdk}: + +stdenv.mkDerivation { + name = "titanium-mobilesdk-2.1.5.v20121112144658"; + src = if (stdenv.system == "i686-linux" || stdenv.system == "x86_64-linux") then fetchurl { + url = http://builds.appcelerator.com.s3.amazonaws.com/mobile/2_1_X/mobilesdk-2.1.5.v20121112144658-linux.zip; + sha1 = "79f073d11ee893c508c5aa675a3126501dd385fd"; + } + else if stdenv.system == "x86_64-darwin" then fetchurl { + url = http://builds.appcelerator.com.s3.amazonaws.com/mobile/2_1_X/mobilesdk-2.1.5.v20121112144658-osx.zip; + sha1 = "6a9a726882222d1615de332aa1ca608c15564e1c"; + } + else throw "Platform: ${stdenv.system} not supported!"; + + buildInputs = [ unzip makeWrapper ]; + + buildCommand = '' + mkdir -p $out + cd $out + yes y | unzip $src + + # Fix shebang header for python scripts + + find . -name \*.py | while read i + do + sed -i -e "s|#!/usr/bin/env python|#!${python}/bin/python|" $i + done + + # Zip files do not support timestamps lower than 1980. We have to apply a few work-arounds to cope with that + # Yes, I know it's nasty :-) + + cd mobilesdk/*/*/android + + sed -i -f ${./fixtiverify.sed} builder.py + sed -i -f ${./fixselfruntimev8.sed} builder.py + sed -i -f ${./fixnativelibs.sed} builder.py + + # Patch some executables + + ${if stdenv.system == "i686-linux" then + '' + patchelf --set-interpreter ${stdenv.gcc.libc}/lib/ld-linux.so.2 titanium_prep.linux32 + '' + else if stdenv.system == "x86_64-linux" then + '' + patchelf --set-interpreter ${stdenv.gcc.libc}/lib/ld-linux-x86-64.so.2 titanium_prep.linux64 + '' + else ""} + + # Wrap builder script + + wrapProgram `pwd`/builder.py \ + --prefix PYTHONPATH : ${python.modules.sqlite3}/lib/python*/site-packages \ + --prefix PATH : ${jdk}/bin \ + --prefix JAVA_HOME : ${jdk} + ''; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 458041fe425..cfd51dcf803 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -417,6 +417,11 @@ let }; xcodeenv = callPackage ../development/mobile/xcodeenv { }; + + titaniumenv = import ../development/mobile/titaniumenv { + inherit pkgs; + pkgs_i686 = pkgsi686Linux; + }; inherit (androidenv) androidsdk_4_1; @@ -5702,7 +5707,6 @@ let # `libblkid' fails to build on GNU/Hurd. configureFlags = args.configureFlags + " --disable-libblkid --disable-mount --disable-libmount" - + " --disable-libmount-mount" + " --disable-fsck --enable-static --disable-partx"; doCheck = false; CPPFLAGS = # ugly hack for ugly software!