You are here

How to build Android APKs on a FreeBSD server

Not so frequently asked questions and stuff: 

Edit: this article is out of date. A new one was written two years later here.

ImageThe FreeBSD logo

Situation

Your team is creating Android apps. Your CI server is running FreeBSD and you'd like Jenkins or something else to be able to build your apps to have nice nightly builds.

You don't care about having adb and you especially don't want to install anything related to X11.

Example

In this example, we'll be building an app using gradle.

Install the build requirements

Install gradle

cd /usr/ports/devel/gradle && make install clean

Install the linux compatibility layer

kldload linux
cd /usr/ports/emulators/linux_base-f10 && make install distclean

Remember, you might need to use brandelf on some parts of the SDK later if they won't execute.

Install bash and link /bin/bash to /usr/local/bin/bash.

cd /usr/ports/shells/bash && make install clean
ln -s /usr/local/bin/bash /bin/bash

Install your favorite flavour of Java.

cd /usr/ports/java/openjdk7 && make install clean

Download and update the Android SDK

Download and extract the Android SDK for Linux.

fetch 'http://dl.google.com/android/android-sdk_r23-linux.tgz'
tar xzf android-sdk_r23-linux.tgz

Go into the tools folder and list the contents of the SDK repositories.

./android list sdk -u
Refresh Sources:
  Fetching https://dl-ssl.google.com/android/repository/addons_list-2.xml
  Validate XML
  Parse XML
  Fetched Add-ons List successfully
  Refresh Sources
  Fetching URL: https://dl-ssl.google.com/android/repository/repository-10.xml
  Validate XML: https://dl-ssl.google.com/android/repository/repository-10.xml
  Parse XML:    https://dl-ssl.google.com/android/repository/repository-10.xml
  Fetching URL: https://dl-ssl.google.com/android/repository/addon.xml
  Validate XML: https://dl-ssl.google.com/android/repository/addon.xml
  Parse XML:    https://dl-ssl.google.com/android/repository/addon.xml
  Fetching URL: https://dl-ssl.google.com/android/repository/addon-6.xml
  Validate XML: https://dl-ssl.google.com/android/repository/addon-6.xml
  Parse XML:    https://dl-ssl.google.com/android/repository/addon-6.xml
  Fetching URL: https://dl-ssl.google.com/glass/gdk/addon.xml
  Validate XML: https://dl-ssl.google.com/glass/gdk/addon.xml
  Parse XML:    https://dl-ssl.google.com/glass/gdk/addon.xml
  Fetching URL: https://dl-ssl.google.com/android/repository/extras/intel/addon.xml
  Validate XML: https://dl-ssl.google.com/android/repository/extras/intel/addon.xml
  Parse XML:    https://dl-ssl.google.com/android/repository/extras/intel/addon.xml
  Fetching URL: https://dl-ssl.google.com/android/repository/sys-img/android/sys-img.xml
  Validate XML: https://dl-ssl.google.com/android/repository/sys-img/android/sys-img.xml
  Parse XML:    https://dl-ssl.google.com/android/repository/sys-img/android/sys-img.xml
  Fetching URL: https://dl-ssl.google.com/android/repository/sys-img/android-wear/sys-img.xml
  Validate XML: https://dl-ssl.google.com/android/repository/sys-img/android-wear/sys-img.xml
  Parse XML:    https://dl-ssl.google.com/android/repository/sys-img/android-wear/sys-img.xml
  Fetching URL: https://dl-ssl.google.com/android/repository/sys-img/android-tv/sys-img.xml
  Validate XML: https://dl-ssl.google.com/android/repository/sys-img/android-tv/sys-img.xml
  Parse XML:    https://dl-ssl.google.com/android/repository/sys-img/android-tv/sys-img.xml
  Fetching URL: https://dl-ssl.google.com/android/repository/sys-img/x86/addon-x86.xml
  Validate XML: https://dl-ssl.google.com/android/repository/sys-img/x86/addon-x86.xml
  Parse XML:    https://dl-ssl.google.com/android/repository/sys-img/x86/addon-x86.xml
Packages available for installation or update: 63
   1- Android SDK Tools, revision 23.0.1
   2- Android SDK Platform-tools, revision 20
   3- Android SDK Build-tools, revision 20
   4- Documentation for Android 'L' Preview SDK, revision 1
   5- SDK Platform Android 4.4W, API 20, revision 1
   6- SDK Platform Android L Preview, revision 1
   7- SDK Platform Android 4.4.2, API 19, revision 3
   8- SDK Platform Android 4.3, API 18, revision 2
   9- SDK Platform Android 4.2.2, API 17, revision 2
  10- SDK Platform Android 4.1.2, API 16, revision 4
  11- SDK Platform Android 4.0.3, API 15, revision 3
  12- SDK Platform Android 4.0, API 14, revision 3
  13- SDK Platform Android 3.2, API 13, revision 1
  14- SDK Platform Android 3.1, API 12, revision 3
  15- SDK Platform Android 3.0, API 11, revision 2
  16- SDK Platform Android 2.3.3, API 10, revision 2
  17- SDK Platform Android 2.2, API 8, revision 3
  18- SDK Platform Android 2.1, API 7, revision 3
  19- SDK Platform Android 1.6, API 4, revision 3
  20- SDK Platform Android 1.5, API 3, revision 4
  21- Samples for SDK API 20, revision 1
  22- Samples for SDK API L Preview, revision 1
  23- Samples for SDK API 19, revision 5
  24- Samples for SDK API 18, revision 1
  25- Samples for SDK API 17, revision 1
  26- Samples for SDK API 16, revision 1
  27- Samples for SDK API 15, revision 2
  28- Samples for SDK API 14, revision 2
  29- Samples for SDK API 13, revision 1
  30- Samples for SDK API 12, revision 1
  31- Samples for SDK API 11, revision 1
  32- Samples for SDK API 10, revision 1
  33- Samples for SDK API 8, revision 1
  34- Samples for SDK API 7, revision 1
  35- Google APIs (x86 System Image), Android API 19, revision 5
  36- Google APIs (ARM System Image), Android API 19, revision 5
  37- Glass Development Kit Preview, Android API 19, revision 8
  38- Google APIs, Android API 18, revision 3
  39- Google APIs, Android API 17, revision 3
  40- Google APIs, Android API 16, revision 3
  41- Google APIs, Android API 15, revision 2
  42- Google APIs, Android API 14, revision 2
  43- Google APIs, Android API 13, revision 1
  44- Google TV Addon, Android API 13, revision 1
  45- Google APIs, Android API 12, revision 1
  46- Google TV Addon, Android API 12, revision 2
  47- Google APIs, Android API 11, revision 1
  48- Google APIs, Android API 10, revision 2
  49- Google APIs, Android API 8, revision 2
  50- Google APIs, Android API 7, revision 1
  51- Google APIs, Android API 4, revision 2
  52- Google APIs, Android API 3, revision 3
  53- Android Support Repository, revision 6
  54- Android Support Library, revision 20
  55- Google Play services for Froyo, revision 12
  56- Google Play services, revision 17
  57- Google Repository, revision 8
  58- Google Play APK Expansion Library, revision 3
  59- Google Play Billing Library, revision 5
  60- Google Play Licensing Library, revision 2
  61- Google USB Driver, revision 10
  62- Google Web Driver, revision 2
  63- Intel x86 Emulator Accelerator (HAXM installer), revision 4

-u means "no gui".

Install what you need.

./android update sdk --filter 1,2,3,5,6,53,54,56 -u
[license stuff]
Installing Archives:
  Preparing to install archives
  Downloading Android SDK Platform-tools, revision 20
  Installing Android SDK Platform-tools, revision 20
  Stopping ADB server failed (code -1).
    Installed Android SDK Platform-tools, revision 2099%)
  Downloading Android SDK Build-tools, revision 20
  Installing Android SDK Build-tools, revision 20
    Installed Android SDK Build-tools, revision 2099%)
  Downloading SDK Platform Android 4.4W, API 20, revision 1
  Installing SDK Platform Android 4.4W, API 20, revision 1
    Installed SDK Platform Android 4.4W, API 20, revision 197%)
  Downloading SDK Platform Android L Preview, revision 1
  Installing SDK Platform Android L Preview, revision 1
    Installed SDK Platform Android L Preview, revision 197%)
  Downloading Android Support Repository, revision 6
  Installing Android Support Repository, revision 6
    Installed Android Support Repository, revision 699%)
  Downloading Android Support Library, revision 20
  Installing Android Support Library, revision 20
    Installed Android Support Library, revision 2093%)
  Downloading Google Play services, revision 17
  Installing Google Play services, revision 17
    Installed Google Play services, revision 1796%)
  Downloading Android SDK Tools, revision 23.0.1
  Installing Android SDK Tools, revision 23.0.1
    Installed Android SDK Tools, revision 23.0.199%)
  Stopping ADB server failed (code -1).
  Unable to run 'adb': Cannot run program "/root/android-sdk-linux/platform-tools/adb": error=2, No such file or directory.
  Starting ADB server failed (code -1).
null  Done. 8 packages installed.

Build your apps!

Edit local.properties and set your SDK location. Alternatively, you can set the environment variable ANDROID_HOME.

sdk.dir=/some/where/android-sdk-linux

Start gradle and see if it complains.

gradle
[some stuff]
Welcome to Gradle 1.12.

To run a build, run gradle  ...

To see a list of available tasks, run gradle tasks

To see a list of command-line options, run gradle --help

BUILD SUCCESSFUL

Total time: 14.139 secs

If not, build!

gradle assembleRelease
[many things]
14:25:54.743 [LIFECYCLE] [org.gradle.BuildResultLogger]
14:25:54.744 [LIFECYCLE] [org.gradle.BuildResultLogger] BUILD SUCCESSFUL
14:25:54.746 [LIFECYCLE] [org.gradle.BuildResultLogger]
14:25:54.748 [LIFECYCLE] [org.gradle.BuildResultLogger] Total time: 1 mins 56.878 secs
ll Truc/build/outputs/apk/
-rw-r--r--  1 root  wheel  1064222 Jul  1 14:25 Truc-release-unaligned.apk
-rw-r--r--  1 root  wheel  1064495 Jul  1 14:25 Truc-release.apk

You can also use the SDK Manager Plugin for gradle, so that your SDK is updated automatically when you build your project.

Problems I met

gradle won't start

gradle

FAILURE: Build failed with an exception.

* What went wrong:
net.rubygrapefruit.platform.internal.jni.PosixFileFunctions.symlink(Ljava/lang/String;Ljava/lang/String;Lnet/rubygrapefruit/platform/internal/FunctionResult;)V

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

libstdc++.so.6 is missing. Install gcc.

cd /usr/ports/lang/gcc && make install clean

Ambiguous method overloading for method java.io.File

> Ambiguous method overloading for method java.io.File#.
  Cannot resolve which method to invoke for [null, class java.lang.String] due to overlapping prototypes between:
        [class java.lang.String, class java.lang.String]
        [class java.io.File, class java.lang.String]

gradle couldn't find the SDK. Did you set sdk.dir in local.properties?


The SDK downloads packages for Windows instead of Linux

The SDK doesn't recognize FreeBSD, so it downloads packages for Windows. It needs to be patched.

Download the sdk source.

git clone https://android.googlesource.com/platform/tools/base

Apply the following patch to the source:

diff -Naur A/common/src/main/java/com/android/SdkConstants.java B/common/src/main/java/com/android/SdkConstants.java
--- A/common/src/main/java/com/android/SdkConstants.java        2014-07-01 16:44:55.000000000 +0200
+++ B/common/src/main/java/com/android/SdkConstants.java        2014-07-01 19:57:58.000000000 +0200
@@ -596,6 +596,8 @@
             return PLATFORM_WINDOWS;
         } else if (os.startsWith("Linux")) {                //$NON-NLS-1$
             return PLATFORM_LINUX;
+        } else if (os.startsWith("FreeBSD")) {              //$NON-NLS-1$
+            return PLATFORM_LINUX;
         }

         return PLATFORM_UNKNOWN;
diff -Naur A/sdklib/src/main/java/com/android/sdklib/internal/repository/archives/ArchFilter.java B/sdklib/src/main/java/com/android/sdklib/internal/repository/archives/ArchFilter.java
--- A/sdklib/src/main/java/com/android/sdklib/internal/repository/archives/ArchFilter.java      2014-07-01 19:57:30.000000000 +0200
+++ B/sdklib/src/main/java/com/android/sdklib/internal/repository/archives/ArchFilter.java      2014-07-01 19:55:33.000000000 +0200
@@ -210,6 +210,8 @@
             hostOS = HostOs.WINDOWS;
         } else if (os.startsWith("Linux")) {                //$NON-NLS-1$
             hostOS = HostOs.LINUX;
+        } else if (os.startsWith("FreeBSD")) {              //$NON-NLS-1$
+            hostOS = HostOs.LINUX;
         }

         BitSize jvmBits;

Rebuild the patched files.

javac sdklib/src/main/java/com/android/sdklib/internal/repository/archives/ArchFilter.java -cp "sdklib/src/main/java:common/src/main/java"
javac common/src/main/java/com/android/SdkConstants.java

Replace the files inside the jar.

cd sdklib/src/main/java/ && jar uf /some/where/android-sdk-linux/tools/lib/sdklib.jar com/android/sdklib/internal/repository/archives/ArchFilter.class
cd common/src/main/java && jar uf /some/where/android-sdk-linux/tools/lib/common.jar com/android/SdkConstants.class

See this patch on the Android website: https://android-review.googlesource.com/#/c/100271/.

Profit!