Samstag, 5. Oktober 2013

Build Fennec (Firefox Mobile) - for the first time

My first time compiling Fennec on Windows and first time compiling Fennec at all. I got the Ubuntu virtual machine image from Brad Lassey's blog as described in the MozillaWiki. I did an update to Android SDK, Android NDK, mozila-central sources. I followed the steps to build Fennec like described in the Wiki article. But as always IT never works out without problems.

For the impatient: the real problem was a mismatch of the real Android SDK path and the path in mozconfig. Now the whole story:

First, the PYTHON environment variable just had no effect. The mach python script was loaded by the old 2.6 Python interpreter. The workaround was to invoke mach using Python 2.7 directly:
> python2.7 mach build
This did the job and the script started the configuration step. But it didn't get far. After 10 seconds the build stopped and hung (once CPU core busy). It seemed like an unusual step to hang. The process list revealed a ld.gold process which refused to finish. Looking deeper into this showed, that /usr/bin/ld.gold is a symbolic link to /usr/bin/hardened-ld which itself is a perl script. Analyzing the script revealed that that hardened-ld tries to resolve all symbolic links until the link points to hardened-ld. Then it appends ".real" to the name and checks if the file does exist. If it does, it executes the file. If it does not exist, it executes the last resolved name:
while (-l $tool && ($link = resolve_link($tool)) !~ /$self$/) {
    $tool = $link;
}
if (-x "$tool.real") {
    $tool = "$tool.real";
}
So if there'd be a /usr/bin/my-ld pointing to /usr/bin/ld.gold which itself would point to /usr/bin/hardened-ld and I execute /usr/bin/my-ld, the script would resolve the links until /usr/bin/ld.gold, check for /usr/bin/ld.gold.real and execute it if it exists. If it does not, it executed /usr/bin/ld.gold.
Back to my problem. In my case /usr/bin/ld.gold was executed and /usr/bin/ld.gold.real was missing. So ld.gold just invoked ld.gold in a never ending loop. That's why the build hung. I guess this is a bug in the VM I got from Brad Lassey. After updating the dated Ubuntu /usr/bin/ld.gold.real appeared. However the endless loop problem in hardened-ld still remains. I filed a bug report for this.
This step did not yet lead to a nice working build. Instead it surfaced a new error message:

/usr/bin/ld.gold.real: fatal error: /home/mozilla/android-ndk-r8e/platforms/android-5/arch-arm/usr/lib/crtbegin_so.o: unsupported ELF machine number 40
That's a weird error message. But searching the internet gave me this important hint: "It seams it use a native ld (for x86) to link an ARM object." Looks like the build was using the system default ld instead of the ld from the android-ndk toolchain.
Updating toolchain path in mozconfig gave me an other error: my android-sdk path was wrong. Jesus, how I love useful error messages. When I updated the Android SDK, as recommended by the Wiki article, I just unpacked the tar. This left the SDK in a path named android-sdk-linux. But mozconfig was referencing android-sdk-linux_x86. That did the magic.
So this was my mozconfig in the end:
HOME=`echo $HOME`
# Add the correct paths here:
ac_add_options --with-android-ndk="$HOME/android-ndk-r8e"
ac_add_options --with-android-sdk="$HOME/android-sdk-linux_x86/platforms/android-17"
ac_add_options --with-android-version=17
ac_add_options --with-android-tools="$HOME/android-sdk-linux_x86/tools"
ac_add_options --with-android-toolchain="$HOME/android-ndk-r8e/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86"
ac_add_options --with-android-platform="$HOME/android-ndk-r8e/platforms/android-14/arch-arm"
# android options
ac_add_options --enable-application=mobile/android
ac_add_options --target=arm-linux-androideabi
ac_add_options --with-endian=little
ac_add_options --with-ccache

mk_add_options MOZ_OBJDIR=./objdir-droid
mk_add_options MOZ_MAKE_FLAGS="-j9 -s"

Conclusion: informative and correct error messages are invaluable.