docs
Folders and files
Name | Name | Last commit date | ||
---|---|---|---|---|
parent directory.. | ||||
TOC 1. Introduction 2. Installing and setting up the Android environment 3. Getting the source code 4. Installing the required Ubuntu packages 5. How to compile 6. Installing MrMC in an Android system 7. Running and debugging MrMC in an Android system 8. Architecture 9. Useful Commands ----------------------------------------------------------------------------- 1. Introduction ----------------------------------------------------------------------------- We currently recommend Ubuntu "Trusty Tahr" (14.04) 64Bit. This is what our continuous integration system "jenkins" is using. Additionally, building from OSX Snow Leopard or Mavericks (others on your own risk ;) ) is working (see 3.1). NOTE TO NEW USERS: All lines that are prefixed with the '#' character are commands that need to be typed into a terminal window / console (similar to the command prompt for Windows). Note that the '#' character itself should NOT be typed as part of the command. ----------------------------------------------------------------------------- 2. Installing the required Ubuntu packages ----------------------------------------------------------------------------- These are the minimum packages necessary for building MrMC. Non-Ubuntu users will need to get the equivalents. $ sudo apt-get install build-essential default-jdk git curl libcurl4-openssl-dev autoconf \ unzip zip zlib1g-dev gawk gperf cmake If you run a 64bit operating system you will also need to get ia32-libs Ubuntu >= 14.04: $ sudo apt-get install lib32stdc 6 lib32z1 lib32z1-dev Older versions: $ sudo apt-get install ia32-libs The following versions are used on our continuous integration system "jenkins". Other (newer) versions might work as well. JDK: openjdk-6-jdk (java version "1.6.0_27") JRE: openjre-6-jre (java version "1.6.0_27") ----------------------------------------------------------------------------- 3. Installing and setting up the Android environment ----------------------------------------------------------------------------- To develop MrMC for Android the Android SDK and NDK are required. -------------------------------------------------------------------- 3.1. Prerequisites when compiling on Mac OSX -------------------------------------------------------------------- a. When building on Mac OSX you should download the java version from here: http://support.apple.com/kb/DL1572 Or ensure otherwise that you are using java 1.6 (java -version tells you the version). b. The compilation for android needs a case sensitive filesystem. The filesystem used on normal OSX installations is case insensitive. So you need to generate a writeable hdd image and format it with hfs (case sensitive). The size should be 20GB. c. Generate a writable dmg with the following command: $ hdiutil create -type UDIF -fs 'Case-sensitive Journaled HFS ' -size 20g -volname android-dev ~/android-dev.dmg d. Whenever you want to compile/develop you need to mount it: $ open ~/android-dev.dmg e. Your workspace can be accessed in /Volumes/android-dev/ then f. Once you have your hdd image with case sensitive hfs file system do all steps below inside of this filesystem. In the end you need to adapt all paths in this document so that they match your local environment. As an example here is a configure line from step 5.1 which demonstrates possible paths. In this example the hdd image is mounted on /Volumes/android-dev. ./configure --with-tarballs=/Users/Shared/mrmc-depends/tarballs --host=arm-linux-androideabi \ --with-sdk-path=/Volumes/android-dev/android/android-sdk-macosx \ --with-ndk=/Volumes/android-dev/android/android-ndk-r10d \ --with-toolchain=/Volumes/android-dev/android/android-toolchain-arm/android-17 \ --prefix=/Volumes/android-dev/android/mrmc-depends -------------------------------------------------------------------- 3.2. Getting the Android SDK and NDK -------------------------------------------------------------------- To get the Android SDK, go to http://developer.android.com/sdk and download the latest version for your operating system. The NDK can be downloaded from http://developer.android.com/tools/sdk/ndk/ [NOTICE] Compiling MrMC for Android requires Android NDK Revision at least 10d. For the SDK just use the latest available. It will work. After downloading the SDK and NDK extract the files contained in the archives to your harddisk. For our example we are extracting in the following directories (this matches the example from tools/depends/README as well): NDK (referenced as <android-ndk> from now on): /opt/android-ndk-r19c SDK (referenced as <android-sdk> from now on): /opt/android-sdk-linux Make sure you have a recent JRE and JDK installed otherwise the Android SDK will not work. (see point 2.) -------------------------------------------------------------------- 3.3. Installing Android SDK packages -------------------------------------------------------------------- After having extracted the Android SDK to <android-sdk> you need to install some android packages using the Android SDK Manager: $ cd <android-sdk>/tools $ ./android update sdk -u -t platform,platform-tool $ ./android update sdk --all -u -t build-tools-25.0.3 As of newest SDKs the android tool is deprecated. Use sdkmanager instead: $ cd <android-sdk>/tools/bin $ ./sdkmanager platform-tools $ ./sdkmanager "platforms;android-26" $ ./sdkmanager "build-tools;27.0.3" $ ./sdkmanager "cmake;3.6.4111459" -------------------------------------------------------------------- 3.4. Setup the Android toolchain (deprecated) -------------------------------------------------------------------- -------------------------------------------------------------------- 3.5. Create a (new) debug key to sign debug APKs -------------------------------------------------------------------- All packages must be signed. The following command will generate a self-signed debug key. If the result is a cryptic error, it probably just means a debug key already existed, no cause for alarm. $ keytool -genkey -keystore ~/.android/debug.keystore -v -alias \ androiddebugkey -dname "CN=Android Debug,O=Android,C=US" -keypass \ android -storepass android -keyalg RSA -keysize 2048 -validity 10000 ----------------------------------------------------------------------------- 4. Getting the source code ----------------------------------------------------------------------------- $ cd $HOME $ git clone git://github.com/mrmc/mrmc.git mrmc-android $ cd mrmc-android $ git submodule update --init addons/skin.re-touched ----------------------------------------------------------------------------- 5. How to compile ----------------------------------------------------------------------------- Compiling MrMC for Android consists of compiling the libraries MrMC depends on with the Android toolchain and creating an Android Application Package (APK) which can be installed in an Android system. -------------------------------------------------------------------- 5.1. Building dependencies -------------------------------------------------------------------- $ cd $HOME/mrmc-android/tools/depends $ ./bootstrap $ ./configure --help Run configure with the correct settings for you local configuration. See tools/depends/README for examples. Anyone working on the dependencies themselves will want to set the environment variables specified in ~/.bashrc or similar, to avoid having to input these with each configure. $ make -j <jobs> $ make -j <jobs> -C target/binary-addons NOTE: if you only want to build specific addons you can specify like this: $ make -C target/binary-addons ADDONS="pvr.hts pvr.dvblink" This build was designed to be massively parallel. Don't be afraid to give it a 'make -j20' or so. Verify that all dependencies are built correctly (it will tell you so) before continuing to avoid errors. If in doubt run another 'make' (single threaded) until the message "Dependencies built successfully." appears. If the single make fails, keep cleaning the specific library by issuing: $ make -C target/<name_of_failed_lib> distclean Then try make again. Rinse and repeat until you are really done and all libs are built. -------------------------------------------------------------------- 5.2. Building MrMC -------------------------------------------------------------------- $ cd $HOME/mrmc-android $ make -C tools/depends/target/xbmc $ make $ make apk After the first build (assuming bootstrap and configure are successful), subsequent builds can be run with a simple 'make' and 'make apk'. ----------------------------------------------------------------------------- 6. Installing MrMC in an Android system ----------------------------------------------------------------------------- To install MrMC through the previously built APK in an Android system you can either install it on a real device (smartphone/tablet/...) running Android >= 2.3.x. -------------------------------------------------------------------- 6.1. Installing MrMC on the Android device -------------------------------------------------------------------- Make sure your Android device is connected to your computer through USB. Furthermore you have to enable the following option in your device's Android settings: - Applications [X] Unknown sources $ cd $HOME/mrmc-android/tools/android/packaging $ adb devices $ adb -s <device-id> install -r images/xbmcapp-debug.apk The <device-id> can be retrieved from the list returned by the "adb devices" command and is the first value in the row representing your device. ----------------------------------------------------------------------------- 7. Running and debugging MrMC in an Android system ----------------------------------------------------------------------------- After installing MrMC's APK in an Android system you can start it using its Launcher icon in Android's Application Launcher. -------------------------------------------------------------------- 7.1. Debugging MrMC -------------------------------------------------------------------- To be able to see what is happening while running MrMC you first need to enable USB debugging in your Android settings (this is already done when using the emulator): - Applications [X] Unknown sources - Development [X] USB debugging To access the log output of your Android system run (the -s parameter and the <device-id> may not be needed when using the Android emulator) $ adb -s <device-id> logcat -------------------------------------------------------------------- 7.2. GDB -------------------------------------------------------------------- GDB can be used to debug, though the support is rather primitive. Rather than using gdb directly, you will need to use ndk-gdb which wraps it. Do NOT trust the -p/--project switches, as they do not work. Instead you will need to cd to tools/android/packaging/mrmc and execute it from there. $ ndk-gdb --start --delay=0 This will open the installed version of MrMC and break. The warnings can be ignored as we have setup the appropriate paths already. -------------------------------------------------------------------- 8. Architecture -------------------------------------------------------------------- During the early days of the android port, MrMC was launched via a stub lib that then dlopen'd libMrMC. This was done to get around bionic's poor handling of shared libs. We now compile everything into libMrMC itself so that it has no runtime dependencies beyond system libs. Done this way, we're able to launch into libMrMC directly. But we still hit Bionic's loader's deficiencies when we dlopen a lib. There are two main issues to overcome for loading: 1. Bionic imports all symbols for a lib as soon as it is loaded, and it will refuse to open a lib if it has a single unresolved symbol 2. It does not search recursively during the resolve. So if liba depends on libb, dlopen'ing liba will _not_ pull in missing symbols from libb. This is particularly nasty considering #1. To work-around these problems we use our own recursive loader in place of dlopen. This loader mimics expected behavior. Using the example above, loading libb before liba will mean that everything will resolve correctly. Additionally, Android does not use versioned solibs. libfoo.so.1 which is typical on linux would not be found by the loader. This means that we must strip the SONAME and NEEDED values out of the libs as well as changing the filenames themselves. The cleaner solution would be to patch libtool/cmake/etc to not add versioning in the first place. For now, we use the brute-force approach of modifying the binary and blanking out the versions. See here for more info: http://www.bernawebdesign.ch/byteblog/2011/11/23/creating-non-versioned-shared-libraries-for-android/ As a final gotcha, all libs must be in the form of ^lib.*so$ with no exceptions (they won't even install otherwise), and the soname must match. So we have to do some renaming to get some of our self-built libs loaded. Development: Typical android native activities are built with ndk-build which is a wrapper around Make. It would be a nightmare to port our entire buildsystem over, so instead we build as usual then package ourselves. It may be beneficial to use ndk-build to do the actual packaging, but for now its behavior is emulated. ABI: Presently we are targeting armv7a neon for arm, and i686 for x86. -------------------------------------------------------------------- 9. Useful Commands -------------------------------------------------------------------- Below are a few helpful commands when building/debugging. These assume that pwd is 'tools/android/packaging' and that the proper sdk/ndk paths are set. -Install a new build over the existing one $ adb -e install -r images/xbmcapp-debug.apk -Launch MrMC on the emulator without the GUI $ adb shell am start -a android.intent.action.MAIN -n org.mrmc.mrmc/android.app.NativeActivity -Kill a misbehaving MrMC $ adb shell ps | grep org.mrmc | awk '{print $2}' | xargs adb shell kill -Filter logcat messages by a specific tag (e.g. "mrmc") $ adb logcat -s mrmc:V -Enable CheckJNI (BEFORE starting the application) $ adb shell setprop debug.checkjni 1