This article explains how Gaia's build system works, including the makefile, the build process, environment variables, and potential customizations.
Most of the meaningful work for the build steps are performed by the scripts that live inside the build/
subdirectory of Gaia, which are executed using make, node.js and XPCShell (also known as JS Shell), a runtime environment from XULRunner. The Gaia build system contains many helper tools to help install, test, localization, and package webapps onto a real device. It also allows developers to customize Gaia by for example changing default wallpaper, ringtones, apps and settings.
Note: XPCShell is similar to node.js but with the added capability to run some Mozilla-flavored javascript. It allows Gaia build scripts to run inside a Firefox extension.
The Makefile
The Makefile consists of a bunch of goals. This section explains the most useful ones.
install-gaia
This goal will push all the apps for Gaia to your device. If you want to only push a specific app, you can use the APP
flag as follows:
APP=calendar make install-gaia
This directory must exist inside one of the Gaia apps directories (e.g., apps
).
reset-gaia
This works the same as install-gaia
but starts by purging and then sets up permission defaults after installing all of the apps. The apps will be in /data/local
like in the engineering builds. This will also push test and debugging applications.
Be careful: Using the APP
environment variable with reset-gaia
appears to work, but it will put your phone in an unusable state (which is recoverable by running this goal again without the APP
variable). So don't do that.
production
Same as reset-gaia
but source code will be optimized. This goal basically allows you to emulate user builds. This will also push the same set of apps that are installed in user builds.
Be careful: Using the APP
environment variable with production
appears to work, but it will put your phone in an unusable state (which is recoverable by running this goal again without the APP
variable). So don't do that.
reference workloads
These goals push variously sized workloads to the device, helping us with debugging and fixing the performance and scalability issues we might have. These goals accept the APP environment variable, or an APPS environment variable that should contain the app names separated by a space, e.g.,
APP=sms make reference-workload-light APPS="sms communications/contacts" make reference-workload-heavy
Note: For more information, read Hacking Gaia: Reference workloads.
Environment variables
Some environment variables let you control some aspects of the build and installation on the device, for example:
P=1
This enables parallel build in order to take advantage of multicore CPU and speed up building time. Default value is 0.
Be careful: Parallel build is an experimental feature that can be unstable.
GAIA_OPTIMIZE=1
This triggers an optimization pass on the JavaScript files. This is automatically set when running make production
. This can be used for install-gaia
or reset-gaia
too.
PRODUCTION=1
This is basically an alias for make production
.
DEBUG=1
This lets you generate a debug profile to use with Gaia unit tests or when developing your Firefox OS app in Firefox. You must delete the existing profile directory before trying to generate a new one.
DEVICE_DEBUG=1
This disables screen lock on the device.
GAIA_DEVICE_TYPE=phone
This variable lets you build specific device from different 'app.list'. All 'app.list' files are located under /build/config/$(GAIA_DEVICE_TYPE)/ folders.
GAIA_DEVICE_TYPE default value is phone.
Note: for more details and more options, consult our Hacking Gaia make options guide.
Build process
Here is a sequence diagram for building gaia:
pre-app.js, app.js & post-app.js will be executed by Makefile and mostly build tasks have been done in xpcshell scripts, Makefile is used for detecting OS and downloading b2g-desktop and we plan to migrate more tasks from Makefile to xpcshell scripts.
you may have question for why we have pre-app, app and post-app, that just because we are moving dependencies from Makefile to xpcshell script, so we created pre-app.js and post-app.js on bug 1021051 for moving mostly dependencies to xpcshell scripts, and at the end, app.js, pre-app.js and post-app.js will be merged on bug 1053703.
we have three kinds of directory for gaia build system:
- source directories: apps, dev_apps, shared directories
- stage directory: build_stage
- profile directories: profile, profile-debug or profile-test directories
our goal is never generate files to source directories, unfortunately we still have some modules to generate files into source directories, but we plan to fix these issues. here is a table to show which modules generate files to source, stage or profile directories.
Here is the build process when make
is executed in the gaia directory, rules will be executed in order:
- b2g_sdk: b2g-desktop is used to run the xpcshell scripts in
GAIA_DIR/build/
. - svoperapps: Download apps and generate configuration files for apps installation per provider of mobile telephony and country
- webapp-manifests: Generate webapps metadata for build process
- keyboard-layouts: Generate the default keyboard layout config
- settings.json (settings.js): This JavaScript generates the default settings for Firefox OS, which are read by Gaia.
- webapp-shared: Pick files which are used in each app from shared directory to build_stage directory.
- preferences: Generates default preferences for Firefox OS; it will generate the
user.js
file and put it onto the device, where it is read by Gecko. Note that the values might be changed with different environment variables such asDEBUG=1
. - app.js: Makefiles in the
app
directory: These are executed if they exist. For each app, if there is no app Makefile the Gaia Makefile will copy the app directory to thebuild_stage
, and execute[app-directory]/build/build.js
if it exists. See Build script for apps for more details. - test-agent-bootstrap & test-agent-config: setup test-agent includes two make rules,
test-agent-config
&test-agent-bootstrap-apps
, which are used to setup test environments for each app. - webapp-optimize: This script contains various optimization procedures including JavaScript minification, concatenation of localization resource files into to JSON files, and generation of HTML files for the default language if necessary.
- webapp-zip: This compresses each app to a separate zip file and puts them into the
profile/
directory. - optimize-clean:
optimize-clean
cleans the HTML files for the default language. - contacts: Copies the preloaded contact file to your profile, if it exists in
GAIA_DISTRIBUTION_DIR
. - extensions: Copies the extensions in
GAIA_DIR/tools/extensions
to your profile directory; different configuration setups allow you to specify copying different extensions. - installed-extensions.json (additional-extensions.js): Finally, this script downloads certain additional extensions to your profile directory.
Build Script for apps
By default, app build script [app directory]/build/build.js will be executed by app.js if it exists. if $APP/build/build.js does not exist, app.js will copy app into build_stage.
files in app directory should be copied into build_stage directory by app build script becuase app.js will not copy them if app build script exists. for example, calendar app has build/build.js and utils.copyToStage() should be called in build.js for calendar app.
Note: For sources outside of your application (like in shared/), you need to put them in a comment node inside the <head> of your index.html, so that it get copied from shared/ into your app.
build script for apps can require all build modules in $GAIA_DIR/build especially utils module which is a very useful module for building apps, you can use require('utils') to get the module.
Customizing the preferences
If you find that you have a set of custom preferences you need to set each time you flash your device, you can create a file called custom-prefs.js
inside the build/config
directory and store them in there. This keeps them from being overwritten and out of source control.
Here are some useful preferences:
// this enables marionette which lets you run performance tests // see https://developer.mozilla.org/en-US/docs/Mozilla/Firefox_OS/Platform/Testing/Gaia_performance_tests user_pref("marionette.defaultPrefs.enabled", true); // this sets the port for remote debugging your application on the device user_pref("devtools.debugger.remote-port", 60000); // this enables the remote debugger user_pref("devtools.debugger.remote-enabled", true); // this outputs debug information about the Radio Interface Layer in logcat user_pref("ril.debugging.enabled", true);
This file is read each time you generate a profile. The safest way to be sure that everything is generated is to delete your profile first:
rm -rf profile && make profile
Then you can safely use the install-gaia
goal.
FAQ
The device remains black after a flash
This can sometimes happen if you flash the device while it is idle. To remedy this just restart B2G by using the following command from the command line:
adb shell stop b2g && adb shell start b2g