Changes

Jump to: navigation, search

Mobile/Fennec/Android/AdvancedTopics

7,740 bytes added, 01:13, 11 September 2015
Created page with "== Advanced Topics == === Testing === See Mobile/Fennec/Android/Testing. === Building === ==== ccache ==== You can optionally install [https://developer.mozilla.org/en-..."
== Advanced Topics ==

=== Testing ===
See [[Mobile/Fennec/Android/Testing]].

=== Building ===
==== ccache ====

You can optionally install [https://developer.mozilla.org/en-US/docs/Ccache ccache], which can make rebuilding Firefox faster after you have built it once and don't change (much) of the C++ source code. In general, ccache is not a performance improvement if you use only one object directory, or edit only Java and/or JavaScript source code.

If you want to use ccache, add a line the following to your mozconfig:

ac_add_options --with-ccache[=/optional/path/to/ccache]

The default cache size of 1GB is not large enough for a Fennec build. To fully utilize ccache (generally meaning you can expect full builds to complete in <5 minutes from a populated cache), you'll need to change the cache size to at least 4GB. Do so by running:

ccache --max-size 4G

On Mac OS X, install ccache like:

brew install ccache

On Debian-like Linuxes, install ccache using:

sudo apt-get install mercurial ccache

=== Multilocale builds ===

* Create a directory, clone mozharness, copy the config file for easy editing/usage:

mkdir multilocale
cd multilocale
hg clone http://hg.mozilla.org/build/mozharness
cp mozharness/configs/multi_locale/standalone_mozilla-central.py myconfig.py

* Edit myconfig.py
** currently will check out m-c into a directory named 'mozilla-central' in this directory
** currently assumes your mozconfig is in this directory and named 'mozconfig'
** currently assumes your mozconfig sets your objdir name to 'objdir-droid'

* pull mozilla-central

mozharness/scripts/multil10n.py --cfg myconfig.py --pull-build-source
# Alternately, you can hg clone http://hg.mozilla.org/mozilla-central

* Run the script, which will create a multilocale apk

mozharness/scripts/multil10n.py --cfg myconfig.py

And you're done.

* If you want to recompile or re-run the script, restore your objdir to en-US first!

mozharness/scripts/multil10n.py --cfg myconfig.py --restore-objdir

Also see [http://escapewindow.dreamwidth.org/234671.html this blog post] for more information.

=== Single-locale language repacks ===

There is a script in mozharness for this (scripts/mobile_l10n.py) but it relies on buildbot information so it's not suitable for local repacks.

This assumes that $(AB_CD) is the locale you want to repack with; I tested with "ar" and "en-GB".

* clone l10n-central/$(AB_CD) so that it is a sibling of your mozilla-central directory
* I assume your object directory is "objdir-droid" and that you have built and packaged already
make -f client.mk && make -C objdir-droid package
* copy your .mozconfig to .mozconfig.l10n and add the following lines
# L10n
ac_add_options --with-l10n-base=../../l10n-central

# Global options
ac_add_options --disable-tests

mk_add_options MOZ_OBJDIR=./objdir-l10n
* cd to mozilla-central
* configure and prepare objdir-l10n
MOZCONFIG=.mozconfig.l10n make -f client.mk configure
make -C objdir-l10n/config
* copy your built package into objdir-l10n
cp ./objdir-droid/dist/fennec-*en-US*.apk ./objdir-l10n/dist
* unpack. This files objdir-l10n/dist with the bits of the APK, ready for re-assembling.
make -C objdir-l10n/mobile/android/locales unpack
* compare locales (you may need to install the compare-locales tool first). This writes locale differences into objdir-l10n/merged.
compare-locales -m objdir-l10n/merged mobile/android/locales/l10n.ini ../l10n-central $(AB_CD)
* finally, re-assemble with the locale differences
LOCALE_MERGEDIR=objdir-l10n/merged make -C objdir-l10n/mobile/android/locales installers-$(AB_CD)

You should find an APK at "objdir-l10n/dist/fennec-*$(AB_CD)*.apk".

==== Enabling C++ debugging ====

If you want to create a build suitable for debugging the C++ code, add:

ac_add_options --enable-debug-symbols

==== Building for the x86 architecture ====

If you want to build for x86, substitute:

ac_add_options --target=i386-linux-android

for the target specified above. Note: you cannot use <tt>ac_add_options --disable-optimize</tt> when building for x86. See {{bug|965870}}.

==== Building for the ARMv6 architecture ====

'''ARMv6 is no longer a supported target as of Firefox 33.'''

If you want to build for ARMv6 instead of ARMv7 (only required for very old, very low end phones), add:

ac_add_options --with-arch=armv6

==== Unsupported build flags ====

Do '''not''' specify these flags because the resulting build will cause out-of-memory crashes:

ac_add_options --disable-install-strip # Do not use!

==== Updating the builders` SDK ====
i.e. Nightly builds & treeherder. See [[Mobile/Fennec/Android/Updating_SDK_on_builders]].

=== Troubleshooting ===

===== Don't set CC / CXX environmental variables =====

If you've set the environmental variables CC and CXX (e.g. via .bash_aliases or via your mozconfig), then you probably need to unset them before building for Android, or else your build may fail with something like:

checking whether the C compiler (gcc -mandroid -fno-short-enums (etc etc)) works... no

followed by errors about "C compiler cannot create executables", "Relocations in generic ELF (EM: 40)", and "crtbegin_dynamic.o: error adding symbols: File in wrong format". This is a sign that you're compiling with your platform's native compiler (due to having CC / CXX set), instead of the android-specific GCC version that ships with the NDK. See {{bug|977817}} for more details; as noted there, the build system may trust your custom CC & CXX variables, when you probably don't want it to.

=== Coding Gotchas ===
==== Closing resources ====
When handling resources (like Cursors), a try/finally block should be used to ensure these are closed properly. For example:

final Cursor c = getCursor();
try {
useCursorWhichMightThrowException(c);
} catch (SomeSpecificException sse) {
log(sse);
} finally {
c.close();
}

Once the try block is entered, the finally block will *always* get executed upon exit of the try block. The one exception is if there is a System.exit call inside the try block, which immediately exits the program and makes everything moot anyway. The finally block will get executed on caught and uncaught exceptions, as well as normal returns.

If you are casting the resource to something, make sure that you do the cast inside the try block, like so:

// GOOD!
InputStream is = getInputStream();
try {
FileInputStream fis = (FileInputStream) is;
...
} finally {
...
}

rather than doing this:

// BAD!
FileInputStream fis = (FileInputStream) getInputStream();
try {
...
} finally {
...
}

This is so that in case of ClassCastExceptions you don't get a dangling open resource left behind.

==== Caveats for Timing ====

TLDR: Google recommends using SystemClock.uptimeMillis() for general purpose interval timing of user interface events or performance measurements. If you're adding stuff for timing, use SystemClock.uptimeMillis(), rather than something like new Date().getTime().

Normally in Java the default time-getter is System.currentTimeMillis() since it avoids the overhead of creating a new Date object. This is also what new Date() does under the hood. However, currentTimeMillis() and the Date object are both subject to change in unexpected ways if the user changes the time on their device, or if daylight savings comes into effect, or there's a network time update, or whatever. So Android has generously provided android.os.SystemClock which has various functions that you can use to get a better timestamp. Refer to the class javadoc and pick whichever function is most suitable for what you're trying to measure.

http://developer.android.com/reference/android/os/SystemClock.html
Confirm
400
edits

Navigation menu