Monday, May 27, 2013

[1st UPDATE: In Android Studio 0.1.1 the project structure of a new project has changed slightly: The name of top level directory is now postfixed with 'Project'. Everything else works as described.2nd UPDATE, 23 June 2013: Fixed the build.gradle file for Android Studio 0.1.63rd UPDATE, 25 June 2013: Added a section to reflect latest changes in the Gradle Plugin and handling of the support library]

Note: While this guide uses ActionBarSherlock as an example the very same procedure will work for many library projects.

Since Android Studio was released as "Early Access Preview" there has been a lot of confusion how to use ActionBarSherlock and other library projects in it. Many people were successful when they imported projects from Eclipse after using ADT's export functionality but there was no how-to for projects created in Studio. I've been struggling with it myself for many hours.
After Xavier Ducrohet posted a little comment on Goolge+ it finally turned out that the problem essentially was caused by a misconception and lack of documentation: Android Studio's UI for managing dependencies is useless for the gradle based build system. And so are all the guides proposing a IntelliJ kind of dependency management.You have to manually edit your dependencies!

So here's a step-by-step guide how to integrate ActionBarSherlock into your Android Studio project:

Create a new project "SherlockTest":

Click "Next" until you're done:

After the wizard has finished you will find a new project with the following structure:

Now you need to put a copy of ActionBarSherlock into your project: Open a terminal, 'cd' into your project, create a 'libraries' directory and clone ActionBarSherlock from github:

After cloning ABS the project structure in Android Studio will show the newly added directories:

Now, you need to tell your build system that those directories exist by editing ~/AndroidStudioProjects/SherlockTest/settings.gradle. Just add the path to your library so that settings.gradle looks like this:

include ':SherlockTest', ':libraries:ActionBarSherlock:actionbarsherlock'

Next, create a build.gradle file in libraries/ActionBarSherlock/actionbarsherlock. Just copy the one from SherlockTest-SherlockTest (you can do this using Ctrl-C and Ctrl-V in Android Studio). You need to edit it a bit. So open the build.gradle file in libraries/ActionBarSherlock/actionbarsherlock change the 'apply-plugin' line to mark this as a library and add a sourceSet section to the android section. The whole build.gradle file should look like this now:

Now you can add the dependency to your main project by editing the build.gradle file located in the SherlockTest-SherlockTest subtree in the project structure. Just add

compile project(':libraries:ActionBarSherlock:actionbarsherlock')

to the dependencies section.
[EDIT: As of Android Studio 0.1.6 you have to remove the dependency on support-v4.jar as well. It is already referenced by ABS.][EDIT 25 June 2013: See additional notes below for the right way to referencing the support library!] So the whole build.gradle file looks like this:

That's it! Now you can use Sherlock* classes in Android Studio and build your project from Studio as well. You might need to restart Android Studio or reload you project to get autocomplete of Sherlock* classes though.

Additional notes

While it all works as described you might want to tweak you build.gradle files a bit more.

Use latest Android Gradle Plugin

First, in order to always use the most recent version of the Android Gradle Plugin you should change all occurences of

dependencies {
classpath 'com.android.tools.build:gradle:0.4'
}

to

dependencies {
classpath 'com.android.tools.build:gradle:0.4.+'
}

Referencing the support library the right way

Second, you should not reference the support library the way it's done above. This only works if there's exactly one librarydepending on it. The right way to do it is by using the Android Support Repository. If you haven't installed it already you should do so using the SDK Manager from Studio. It's located in the "Extras" section.
After you have it installed you can reference the support library by replacing

dependencies {
compile files('libs/android-support-v4.jar')
}

with

dependencies {
compile 'com.android.support:support-v4:13.0.0'
}

You should also add this to the main build.gradle file (not the one in the top level directory) so that it reads:

Monday, May 13, 2013

In part 1 of this small series of blog posts I've shown you how to set up a cross compile environment for building autotools projects for Android. Now let's ut it to the test and build some audio libraries. To follow this tutorial please create a 'src' subdirectory in your toolchains directory and cd into it:

cd $TOOLS/android-toolchains/arm-linux-androideabi-4.8
mkdir src

Ogg - first try

Let's start with ogg. You can find a source tarball on xiph.org. Download and extract it to your just created src folder:

What's wrong?

This is an error you will frequently encounter. Configure is using a script called 'config.sub' and it doesn't know about arm-linux-androideabi. This doesn't come as much of a surprise as the version shipped with the tarball has a timestamp '2009-11-20'. I'm not sure but I don't think there was a compiler with arm-linux-androideabi back then.

Fortunately, 'config.sub' isn't really part of the actual sources but is generated with a script called 'autogen.sh' that is not part of the source tarball but can be found in the git tree.

Ogg - second try

So, let's clean up and try with ogg from git:

rm -rf libogg-*
git clone git://git.xiph.org/mirrors/ogg.git
cd ogg

This directory doesn't contain the 'configure' script, yet. So we have to create it by running 'autogen.sh':

./autogen.sh
android-configure
android-make
android-make install

These commands should run without problems. If you run into issues though you are probably missing some development tools in your Linux installation. Install them using apt-get, yum or whatever your distribution is using.

Now, let's verify our installation:

ls $TOOLS/android-toolchains/arm-linux-androideabi-4.8/lib | grep ogg

Should yield output similar to this:

libogg.a
libogg.la
libogg.so
libogg.so.0
libogg.so.0.8.0

Great, the first native library has been built!

Vorbis

If everything went successfully with ogg building vorbis is straight forward:

FLAC

UPDATE: Currently FLAC from git won't build. Please, checkout the last working version d35b21e7b92a46fb64307f7b43f173f5efa35192 before building.Update: I'm currently getting an error on the first run of android-make related to 'docbook-to-man'. The second run of android-make runs fine.

Done! You now have a complete set of libsndfile, libogg, libvorbis, libflac build for Android!But there have been lots of warnings in the build process of libsndfile. So we should probably perform some tests before using it in an Android project. So the next part will show how to use those libraries and how to run the libsndfile test suite.

Preface

In my science shows I'm using many sound cues - like playing an intro when the show starts, setting some sound accents to help the audience focus on those little gems and surely some dramatic music when it helps to build up the suspense.
I've been using my own cue playback software for this for many years and it has served me well. Right now I'm in the process of porting parts of this software to Android. In this blog I will publish some of the findings I make during this ongoing project - as a note to myself and as a help for others. I'll start with a small series on building native libraries for Android.

Android NDK

The Android NDK offers the tools to use native C/C++ code in Android projects. However, the documentation is not too verbose on how to use the NDK for building existing open source projects. While many projects need their own tweaks and patches a lot of libraries I am using in my audio programs (e.g. libsndfile, flac, libogg, libvorbis and mpg123) are astonishingly easy to build once you properly set up your cross compile environment.
But beware of tiny little problems (read: compiler warnings): As you will see, e.g. libsndfile builds fine with a couple of minor tweaks - but that doesn't mean it will work as expected.

Preparing the tools

First, you need the Andoid SDK. If you don't already have it installed get it from http://developer.android.com/sdk/index.html. As there are different versions available, please follow the installation instructions for your copy.
Next, you need the latest version of the NDK for your operating system. Get it from http://developer.android.com/tools/sdk/ndk/index.html. At the time of this writing the lastest version is r8e. As I'm using a 64-bit Linux the file to get is android-ndk-r9-linux-x86_64.tar.bz2. For historical reasons I like to have my external tools all in $HOME/tools and export a corresponding environment variable:

export TOOLS=$HOME/tools

You don't need to follow this habit but the instructions are written this way. Now, extract your NDK tarball to $TOOLS:

You'll find a new directory android-ndk-r8e in your $TOOLS directory. For convenience, I like to keep a symbolic link pointing to the latest NDK and set yet another environment variable:

ln -s android-ndk-r9 android-ndk
export NDK=$TOOLS/android-ndk

Setting up the toolchain

Working with software projects using autotools is much simpler if you set up a standalone toolchain. This is explained in $NDK/docs/STANDALONE-TOOLCHAIN.html. Here's the command to put the arm-linux-androideabi-4.8 toolchain in $TOOLS/android-toolchains/arm-linux-androideabi-4.8:

I'm using --toolchain=arm-linux-androideabi-4.8 since I need some C++11 features that are not available in previous versions of gcc. Again, read $NDK/docs/STANDALONE-TOOLCHAIN.html for the other options.

Preparing the environment

For convenience you should setup a couple of convenience wrapper scripts and environment variables for handling autotools projects. First, create a directory for executables in your home directory:

mkdir $HOME/bin

Then modify your .bashrc or .bash_profile depending on your distribution or own preferences by adding the following lines:

These wrappers just set the CXX and CC environment variables before calling './configure' or 'make', respectively.

Some projects use pkg-config to figure out compiler flags etc. So we create another wrapper:

#!/bin/bash
#
# This file: $HOME/bin/arm-linux-androideabi-pkg-config
# This file has no copyright assigned and is placed in the Public Domain.
# No warranty is given.
# Original version and further reading:
# http://www.mega-nerd.com/erikd/Blog/CodeHacking/MinGWCross/pkg-config.html
# When using cross compiler tools, the native Linux
# pkg-config executable works fine as long as the default PKG_CONFIG_LIBDIR
# is overridden.
export PKG_CONFIG_LIBDIR=$TOOLS/android-toolchains/arm-linux-androideabi-4.8/lib/pkgconfig
# Also want to override the standard user defined PKG_CONFIG_PATH
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH_ARM_ANDROID_EABI
# Now just execute pkg-config with the given command line args.
pkg-config $@

How to use it in a perfect world

Whenever you come across an autotools project, i.e. a project that is build using the triplet './configure', 'make', 'make install' all you should need to do is use 'android-configure' instead of './configure' and 'android-make' instead of 'make'.

...and in the real world

In reality though there are lots of issues that may arise since Android is quite different from any usual Linux distribution. I'll discuss some of them in the forthcoming part 2.