Advanced Package Processing System [APPS] MTAC – August 2004.
Building mobile apps with the Nix package manager
-
Upload
sander-van-der-burg -
Category
Software
-
view
411 -
download
0
Transcript of Building mobile apps with the Nix package manager
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