building mobile apps with the nix package manager

40
Building mobile apps with the Nix package manager Sander van der Burg Conference Compass July 14, 2016 Sander van der Burg Building mobile apps with the Nix package manager

Upload: sander-van-der-burg

Post on 14-Feb-2017

411 views

Category:

Software


0 download

TRANSCRIPT

Building mobile apps with the Nix packagemanager

Sander van der Burg

Conference Compass

July 14, 2016

Sander van der Burg Building mobile apps with the Nix package manager

Apps are popular

Conference Compass provides a service to improve the waypeople experience events

Most visible part of the service: apps for conference attendees

Sander van der Burg Building mobile apps with the Nix package manager

Apps are popular

Some features:Conference programFloormapsAnnouncements

Each customer basically gets “their own” app.We have a product-line to accomplish that

Sander van der Burg Building mobile apps with the Nix package manager

Producing apps is complex: target platforms

Sander van der Burg Building mobile apps with the Nix package manager

Producing apps is complex: platform versions

Android example:Code name Version number Initial release data API level

Nougat 7.0 TBD 24Marshmallow 6.0 October 5, 2015 23Lollipop 5.0 – 5.1 November 12, 2014 21 – 22KitKat 4.4 – 4.4.4 October 31, 2013 19 – 20Jelly Bean 4.1 – 4.3 July 9, 2012 16 – 18...

(Source: https:

//en.wikipedia.org/wiki/Android_version_history)

Sander van der Burg Building mobile apps with the Nix package manager

Producing apps is complex: tedious installations ofdependencies

Sander van der Burg Building mobile apps with the Nix package manager

Producing apps is complex: host system requirements

iOS development requires Xcode which requires Mac OS X:

Sander van der Burg Building mobile apps with the Nix package manager

Producing apps is complex: how to set up continuousbuilds?

Sander van der Burg Building mobile apps with the Nix package manager

Nix package manager

Benefits for mobile app development:

Manages the build-time dependencies of mobile apps

Automates the builds of mobile apps

Reliably manages multiple versions/variants of dependencies

Conveniently reproduces app installations

Nix works on multiple operating systems, e.g. Linux and MacOS X

Integration with Hydra – the Nix-based continuous integrationsolution comes (almost) for free

Sander van der Burg Building mobile apps with the Nix package manager

Nix package manager

Benefits for mobile app development:

Manages the build-time dependencies of mobile apps

Automates the builds of mobile apps

Reliably manages multiple versions/variants of dependencies

Conveniently reproduces app installations

Nix works on multiple operating systems, e.g. Linux and MacOS X

Integration with Hydra – the Nix-based continuous integrationsolution comes (almost) for free

Sander van der Burg Building mobile apps with the Nix package manager

Android packaging in Nixpkgs

Sander van der Burg Building mobile apps with the Nix package manager

Many Android SDK components have been packaged in Nixpkgs

Platform tools

Build tools

Support libraries

Platform SDKs:

API-levels: 2 – 23

System images:

API-levels: 14 – 23Architectures: armeabi-v7a, x86, x86 64, mips

Addons:

Google APIs, API-levels: 3 – 23Google Play Services

Android NDK:

Versions: r8e, r10e

Android packaging process

The majority of the Android SDK components are opensource (Apache Software License, version 2.0), but Googledoes not provide proper source releases

You can fetch sources from Git repositories:https://android.googlesource.com

The Android SDK has its own package distributionmechanism (XML metadata + Zip files over HTTP)

Some packages (core SDK, build tools, platform tools) haveexecutables that must be patched with patchelf

Sander van der Burg Building mobile apps with the Nix package manager

Android packaging process

Most components can be automatically transformed into Nixpackages by applying XSL transformations:

<sdk:platform>

<sdk:revision>1</sdk:revision>

<sdk:description>Android SDK Platform 6.0</sdk:description>

<sdk:version>6.0</sdk:version>

<sdk:api-level>23</sdk:api-level>

...

<sdk:archives>

<sdk:archive>

<sdk:size>70408061</sdk:size>

<sdk:checksum type="sha1">

cbccca8d3127e894845556ce999b28281de541bd

</sdk:checksum>

<sdk:url>android-23_r01.zip</sdk:url>

</sdk:archive>

</sdk:archives>

<sdk:uses-license ref="android-sdk-license"/>

</sdk:platform>

Sander van der Burg Building mobile apps with the Nix package manager

Android packaging process

Most components can be automatically transformed into Nixpackages by applying XSL transformations:

{fetchurl}:

{

...

platform_23 = buildPlatform {

name = "android-platform-6.0";

src = fetchurl {

url = https://dl.google.com/android/repository/android-23_r01.zip;

sha1 = "cbccca8d3127e894845556ce999b28281de541bd";

};

meta = {

description = "Android SDK Platform 6.0";

};

};

}

More details, see:

http://sandervanderburg.blogspot.com/2012/11/building-android-applications-with-nix.html

http://sandervanderburg.blogspot.com/2013/08/some-improvements-to-nix-android-build.html

Sander van der Burg Building mobile apps with the Nix package manager

Installing the Android SDK with Nix

Because the Android SDK is modular, there is no single AndroidSDK package. You have to specify which modules you want:

with import <nixpkgs> {};

androidenv.androidsdk {

platformVersions = [ "23" ]; # Anything between 2 - 23

abiVersions = [ "armeabi-v7a" ]; # Also possible: x86, mips, x86_64

useGoogleAPIs = true;

useExtraSupportLibs = true;

useGooglePlayServices = true;

}

$ nix-env -i $(nix-build myandroidsdk.nix)$ android -h

Sander van der Burg Building mobile apps with the Nix package manager

Installing the Android SDK with Nix

Nixpkgs contains a number of preconfigured compositions forcommon scenarios:

Install an SDK with commonly used modules for Android 6.0:

$ nix-env -f ’<nixpkgs>’ -iA androidenv.androidsdk 6 0

Install an SDK with commonly used modules for Android 5.0:

$ nix-env -f ’<nixpkgs>’ -iA androidenv.androidsdk 5 0

Sander van der Burg Building mobile apps with the Nix package manager

Building Android apps with Nix

with import <nixpkgs> {};

let

repo = fetchFromGitHub {

owner = "svanderburg";

repo = "nix-androidenvtests";

rev = "79775d3facaff28a7a772a9a5a6af1866ec206f0";

sha256 = "0fl9psaxvlpg34xf5g8ci1v41jx0cl2zx9xy1wnnqc7zx4mwhrvj";

};

in

androidenv.buildApp {

name = "MyFirstApp";

src = "${repo}/src/myfirstapp";

platformVersions = [ "16" ];

}

$ nix-build myfirstapp.nix$ ls resultMyFirstApp-debug.apk nix-support

Sander van der Burg Building mobile apps with the Nix package manager

Launching Android emulator instances

with import <nixpkgs> {};

androidenv.emulateApp {

name = "emulate-myfirstapp";

app = import ./myfirstapp.nix; # App built in the previous example

platformVersion = "23"; # We use a newer API-level emulator instance

abiVersion = "x86"; # Also possible: armeabi-v7a, mips, x86_64

package = "com.example.my.first.app";

activity = ".MainActivity";

# API-levels 15 and onwards support GPU acceleration

enableGPU = true;

}

$ nix-build emulatemyfirstapp.nix

The expression produces a script

Sander van der Burg Building mobile apps with the Nix package manager

Launching Android emulator instances

The generated script configures an emulator instance and launchesit. When the boot process has been completed it installs and startsthe app:

$ ./result/bin/run-test-emulator

Sander van der Burg Building mobile apps with the Nix package manager

Launching Android emulator instances

The generated script configures an emulator instance and launchesit. When the boot process has been completed, it installs andstarts the app:

$ ./result/bin/run-test-emulator

Sander van der Burg Building mobile apps with the Nix package manager

Running APKs in emulators

(You can also fetch the Angry Birds APK from your phoneand automatically start it in a generated emulator instance:http://sandervanderburg.blogspot.com/2014/02/

reproducing-android-app-deployments-or.html)

iOS variability

For iOS, there are fewer concerns than Android:

Xcode version

A specific Xcode version includes a specific version of an iOS SDK:Version iOS SDK included

7.3 iOS 9.37.2 iOS 9.27.1 iOS 9.17.0 iOS 9.06.4 iOS 8.4...

iOS simulator version:

Xcode 7.3 supports: iOS 9.1 - 9.0, 8.4 - 8.1

Sander van der Burg Building mobile apps with the Nix package manager

Xcode packaging

Nothing is actually packaged in Nixpkgs :-):

Xcode may not be redistributed

It must be installed from the App store (latest version) or theApple developer portal (older versions)

Sander van der Burg Building mobile apps with the Nix package manager

Xcode packaging

{stdenv, version, xcodeBaseDir ? "/Applications/Xcode.app"}:

stdenv.mkDerivation {

name = "xcode-wrapper-"+version;

buildCommand = ’’

mkdir -p $out/bin

cd $out/bin

ln -s /usr/bin/xcode-select

ln -s /usr/bin/security

ln -s /usr/bin/codesign

ln -s "${xcodeBaseDir}/Contents/Developer/usr/bin/xcodebuild"

ln -s "${xcodeBaseDir}/Contents/Developer/usr/bin/xcrun"

ln -s "${xcodeBaseDir}/Contents/Developer/Applications/Simulator.app/Contents/MacOS/Simulator"

cd ..

ln -s "${xcodeBaseDir}/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs"

# Check if we have the xcodebuild version that we want

if [ -z "$($out/bin/xcodebuild -version | grep -x ’Xcode ${version}’)" ]

then

echo "We require xcodebuild version: ${version}"

exit 1

fi

’’;

}

Sander van der Burg Building mobile apps with the Nix package manager

Xcode packaging

We create a proxy package for Xcode:

We lose the ability to use Nix to manage a build’sdependencies

But we can still automatically build apps, integrate withHydra etc.

Nix store paths still reflect the properties we care about, e.g.Xcode version

More details, see:

http://sandervanderburg.blogspot.com/2012/12/deploying-ios-applications-with-nix.html

http://sandervanderburg.blogspot.com/2013/08/improving-testability-of-nix-ios-build.html

http://sandervanderburg.blogspot.com/2014/10/deploying-ios-applications-with-nix.html

Sander van der Burg Building mobile apps with the Nix package manager

Building an app for the iOS simulator

with import <nixpkgs> { system = "x86_64-darwin"; };

let

repo = fetchFromGitHub {

owner = "svanderburg";

repo = "nix-xcodeenvtests";

rev = "482c8a5fd50bd415309f46a12b72a2f07298a134";

sha256 = "1mmb805g9c8kjkkh61imjgilw0iig5a9g7i3ra91jxpy2mwagb6r";

};

in

xcodeenv.buildApp {

name = "HelloWorld";

src = "${repo}/src/HelloWorld";

scheme = "HelloWorld";

sdkVersion = "9.2";

release = false; # Indicates that we want a simulator build

}

$ nix-build firstapp.nix$ ls resultHelloWorld.app HelloWorld.app.dSYM

Sander van der Burg Building mobile apps with the Nix package manager

Launching iOS simulator instances

with import <nixpkgs> { system = "x86_64-darwin"; };

xcodeenv.simulateApp {

name = "simulate-helloworld";

app = import ./firstapp.nix; # App build shown previously

bundleId = "MyCompany.HelloWorld";

}

$ nix-build simulatefirstapp.nix

The expression produces a script

Sander van der Burg Building mobile apps with the Nix package manager

Launching iOS simulator instances

Starting the script without parameters, shows an overview of theavailable simulators, and asks you to pick an instance by its UDID:

$ ./result/bin/run-test-simulator

== Devices ==

-- iOS 9.0 --

iPhone 4s (1632E4A6-8D62-4EF7-BBBC-B95C7AD872A5) (Shutdown)

iPad 2 (65D35EC1-F62A-42C3-AC4C-7027963DA01B) (Shutdown)

...

-- iOS 9.2 --

iPhone 4s (2F8EB097-892D-484F-96A2-D68AE3D31694) (Shutdown)

iPhone 5 (9423B552-075C-4D25-A950-5B56CD069C97) (Shutdown)

iPhone 5s (2B71AD4D-6396-4C83-B73F-EB275CAB0C93) (Shutdown)

...

Please provide a UDID of a simulator:

2F8EB097-892D-484F-96A2-D68AE3D31694

Sander van der Burg Building mobile apps with the Nix package manager

Launching iOS simulator instances

After picking a UDID, the simulator instance gets launched:

Sander van der Burg Building mobile apps with the Nix package manager

Launching iOS simulator instances

After pressing enter, the app gets installed and launched:

Sander van der Burg Building mobile apps with the Nix package manager

Building an app for ad-hoc purposes or store releases

with import <nixpkgs> { system = "x86_64-darwin"; };

let

repo = fetchFromGitHub {

owner = "svanderburg";

repo = "nix-xcodeenvtests";

rev = "482c8a5fd50bd415309f46a12b72a2f07298a134";

sha256 = "1mmb805g9c8kjkkh61imjgilw0iig5a9g7i3ra91jxpy2mwagb6r";

};

in

xcodeenv.buildApp {

name = "HelloWorld";

src = "${repo}/src/HelloWorld";

scheme = "HelloWorld";

sdkVersion = "9.2";

release = true; # Indicates that we want a real build

generateIPA = true; # Indicates that we want an IPA bundle

certificateFile = ./mycertificate.p12;

certificatePassword = "secret";

codeSignIdentity = "iPhone Distribution: My Company";

provisioningProfile = ./my.mobileprovision;

}

Sander van der Burg Building mobile apps with the Nix package manager

Building an app for ad-hoc purposes or store releases

$ nix-build firstapp.nix$ ls resultHelloWorld.app HelloWorld.app.dSYM HelloWorld.ipa nix-support

Sander van der Burg Building mobile apps with the Nix package manager

Building Titanium apps

Previously shown Nix funcions are relevant for native appdevelopmentWe use a cross-platform development framework: TitaniumUses JavaScript as an implementation languageCross-platform API for UI components that integrate with theunderlying host systemSupports multiple targets: iOS, Android, Tizen, WindowsPhone, Blackberry, Mobile web applicationsNot write once run everywhere: 60% – 90% of code can bereused among platforms

More details,

see:http://sandervanderburg.blogspot.com/2014/01/building-appcelerator-titanium-apps.html

Sander van der Burg Building mobile apps with the Nix package manager

Building Titanium apps

We can also build them with Nix! The Titanium infrastructurereuses Android and iOS functionality from Nixpkgs!

Sander van der Burg Building mobile apps with the Nix package manager

Building a Titanium app for Android

with import <nixpkgs> {};

titaniumenv.buildApp {

name = "KitchenSink";

src = fetchgit {

url = https://github.com/appcelerator/KitchenSink.git;

rev = "f923be78ef415436d0e36450fbdbb3bf90028f6c";

sha256 = "1hz3605s180i3kf2m3wn0ppk1kmm96s8328my5kp6hjsq6ygld5s";

};

tiVersion = "5.1.2.GA";

target = "android"; # Build for Android

androidPlatformVersions = [ "23" ];

release = false;

}

$ nix-build kitchensink-android.nix$ ls resultKitchenSink.apk nix-support

Sander van der Burg Building mobile apps with the Nix package manager

Building a Titanium app for the iOS simulator

with import <nixpkgs> { system = "x86_64-darwin"; };

titaniumenv.buildApp {

name = "KitchenSink";

src = fetchgit {

url = https://github.com/appcelerator/KitchenSink.git;

rev = "f923be78ef415436d0e36450fbdbb3bf90028f6c";

sha256 = "1hz3605s180i3kf2m3wn0ppk1kmm96s8328my5kp6hjsq6ygld5s";

};

tiVersion = "5.1.2.GA";

target = "iphone"; # Build for iOS

release = false;

}

$ nix-build kitchensink-iphone.nix

Sander van der Burg Building mobile apps with the Nix package manager

Distributing Android APKs with Hydra

Use your browser on your Android device to install APKs byvisiting a build result page:

Sander van der Burg Building mobile apps with the Nix package manager

Distributing iOS IPAs with Hydra

Use your browser on your iOS device to install IPAs by clicking onthe ’install’ build product:

(Requires installing a script that composes a itms-services:// link. See:

http://sandervanderburg.blogspot.com/2014/08/wireless-ad-hoc-distributions-of-ios.html)

Sander van der Burg Building mobile apps with the Nix package manager

Some facts

First version of Android build functionality: November 2012

First version of iOS build functionality: December 2012

Hydra integration: March 2013

We have built ±100 different kinds of Titanium-basedAndroid and iOS apps using Nix and Hydra in 2015

Sander van der Burg Building mobile apps with the Nix package manager

References

androidenv, xcodeenv, titaniumenv are part of Nixpkgs(https://github.com/nixos/nixpkgs)

Simple Android test case: https:

//github.com/svanderburg/nix-androidenvtests

Simple iOS test case:https://github.com/svanderburg/nix-xcodeenvtests

Simple Titanium test case:pkgs/development/mobile/titaniumenv/examples

subfolder in Nixpkgs(https://github.com/nixos/nixpkgs)

Sander van der Burg Building mobile apps with the Nix package manager

Questions

Sander van der Burg Building mobile apps with the Nix package manager