Mozilla Platform Development Cheat Sheet
Firefox, XUL, XBL, XPCOM, Javascript, CSS, ...
Repositories
- mozilla-central (Latest for Firefox):
http://hg.mozilla.org/mozilla-central/ - Mozilla Aurora:
http://hg.mozilla.org/releases/mozilla-aurora/ - Mozilla Beta:
http://hg.mozilla.org/releases/mozilla-beta/ - Mozilla Release:
http://hg.mozilla.org/releases/mozilla-release/ - comm-central (Latest for Thunderbird, SeaMonkey, Lightning/Sunbird):
http://hg.mozilla.org/comm-central/ - Mozilla Inbound (Push changes here to get them on mozilla-central):
http://hg.mozilla.org/integration/mozilla-inbound - Mozilla ESR 10:
http://hg.mozilla.org/releases/mozilla-esr10
Extensions
- Firebug
Edit, debug, and monitor JavaScript, CSS, HTML, and external XUL - Chromebug (Requires a matching Firebug version)
Debug Firefox itself's XUL, XBL, Javascript, ... (debug chrome) - Extension Developer
Interactive JavaScript shell, live preview HTML and XUL editors, regular expression and XPath testers, and packaging tool
Plugins
- Copy to: <installDir>\Plugins
- Environment variable MOZ_DEBUG_CHILD_PROCESS=1 can be used to delay 30 seconds when loading plugin-container before the plugin is loaded.
- Plugin development
Debugging
- Use Firebug and Chromebug to debug XUL, XBL, JavaScript
- Debug C++ src in Windows: Open VS2010, select open project, select dist/bin/firefox.exe in your obj dir. Press F5. Change source, do an incremental build, open the source and set breakpoints in VS2010.
- To avoid having debug assertions and to have them show up in the log instead, set this environment variable:
XPCOM_DEBUG_BREAK=warn
Debugging XUL apps
- Preferences should be in a .js file in the directory %appname%/defaults/preferences/.
- /* debugging prefs */
pref("browser.dom.window.dump.enabled", true);
pref("javascript.options.showInConsole", true);
pref("javascript.options.strict", true);
pref("nglayout.debug.disable_xul_cache", true);
pref("nglayout.debug.disable_xul_fastload", true); - To write to the Error Console:
Components.utils.reportError("0"); - To write to the console:
dump("hello world!");
Command Line
- -purgecaches use when changing XUL, XBL, JSM, ...
- -no-remote allows you to run multiple instances of the program with different profiles
- -console starts the application with a debug console
- -ProfileManager starts the application with the profile manager
- -P "profilename" starts the application with the specified profile
- -console starts firefox with an extra console, you can then enable extra logs like app.update.log in about:config
- Other command line options
Crashes
- about:crashes gives you links to your crashes
- Online crash reports and stats
Getting help
- IRC:
irc.mozilla.org
Some channels: #developers, #introduction, #xul, #planning, #jsapi, #gfx
More info on IRC - NNTP Server
- Google group
- Mailing list
Useful links when getting started
- Ability to edit bugs on bugzilla (editbugs privs)
- Getting commit access
- Mozilla source code directory structure
Useful links forever
- Bugzilla
- Mozilla central push log
- Mozilla central Nightly builds
- MXR (Browse source code online)
- DXR (Search source code online)
- Tinderbox (Tool to ensure compiles on various platforms and all automated)
- Modules and module owners (for code reviews and questions)
- Top crash reports
- License Boilerplate
- Tools
- Air Mozilla
- Old Air Mozilla
Useful links if you are an employee
Coding style
- line length: 80 chars or less
- indenting: 2 spaces (no tabs)
- Function definitions, braces on newlines
- Conditionals and loops:
if (condition) {
} - Multiline, align with parentheses:
if (argument1 == paramvalu1 && argument2 == paramvalue2 &&
argument3 == paramvalue3 && argument4 == paramValue4) {
} - Comments, use space after comment indicator
- More info on coding style
Build commands
-
Full build of Firefox: (~ 1h)
make -f client.mk - To rebuild Firefox without pulling the tree: (~25min)
make -f client.mk build_all_depend - To clean: (~2min)
make -f client.mk distclean - Incremental builds (~2min, see below section)
- Full build of Thunderbird or other comm-central
python client.py checkout (which clones a copy of mozilla-central inside a subfolder called mozilla)
make -f client.mk - Make an objdir for partial tree
cd $(objdir)
../build/autoconf/make-makefile component/path
cd $(objdir)/component/path
make - Regenerating a Makefile from a Makefile.in
cd $(objdir)
../build/autoconf/make-makefile dir_path/with/makefile_dot_in - pymake config:
notepad c:\users\bbondy\.profile
alias pymake=/c/project/mozilla/mozilla-central/build/pymake/make.py - Building with pymake:
mkdir objdirpymake
cd objdirpymake
../configure (if fails, run again)
pymake -sj4 (4 is the number of cores) - Or building with pymake:
python build/pymake/make.py -f client.mk - Running tests with pymake:
python -OO ../build/pymake/make.py mochitest-plain - Incremental builds with pymake:
pymake -sC widget/windows
Example .mozconfig files (Gecko 2.0 and up)
-
Firefox Debug .mozconfig contents: (Using mozilla-central)
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-ff-debug
ac_add_options --enable-application=browser
ac_add_options --enable-debug
ac_add_options --disable-optimize
ac_add_options --enable-tests
-
Firefox Release .mozconfig contents: (Using mozilla-central)
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-ff-debug
ac_add_options --enable-application=browser
ac_add_options --enable-optimize
ac_add_options --enable-debug-symbols
-
xulrunner .mozconfig contents: (Using mozilla-central)
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-xulrunner-debug
ac_add_options --enable-application=xulrunner
ac_add_options --enable-debug
ac_add_options --disable-optimize
-
Thunderbird .mozconfig contents: (Using comm-central)
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-tb-debug
ac_add_options --enable-application=mail
ac_add_options --enable-debug
ac_add_options --disable-optimize
#If you also want Lightning
ac_add_options --enable-calendar
-
SeaMonkey .mozconfig contents: (Using comm-central)
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-seamonkey-debug
ac_add_options --enable-application=suite
ac_add_options --enable-debug
ac_add_options --disable-optimize
-
Sunbird .mozconfig contents: (Using comm-central)
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-sunbird-debug
ac_add_options --enable-application=calendar
ac_add_options --enable-debug
ac_add_options --disable-optimize
-
Fennec Win32 .mozconfig
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir
ac_add_options --enable-application=mobile
# For improved compile speeds, all optional.
mk_add_options MOZ_MAKE_FLAGS=-j4
#export CCACHE_HARDLINK=1
#export MOZ_DEBUG_SYMBOLS=1
ac_add_options --enable-debug
ac_add_options --disable-optimize
# Needed on Win32 to fix problem with Windows Vista SDK
ac_add_options --disable-accessibility
-
Windows 8 Metro .mozconfig
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir
ac_add_options --enable-application=mobile
mk_add_options MOZ_MAKE_FLAGS=-j4
ac_add_options --enable-debug
ac_add_options --disable-optimize
ac_add_options --enable-tests
ac_add_options --enable-win8metro
ac_add_options --with-windows-version=602
Incremental builds
- Don't use make in subdirectories from within the source dirs, use the obj dir which is created when you first build (Example: obj-i686-pc-mingw32\widget)
- Example if you have changes to /widget:
cd obj-i686-pc-mingw32
make -C widget
make -C toolkit/library
Logging
-
Logging Javascript with Firebug/Chromebug/web console:
console.log("my output");
console.log("%s is %d years old.", "Bob", 42).
-
Netscape portable runtime logging (PR_LOG):
Environment variables:
NSPR_LOG_FILE = WinDebug and it will output to the debug output window or use NSPR_LOG_FILE=C:\nspr-log.txt to output to a file by that name
NSPR_LOG_MODULES can specify which modules to log with the, example NSPR_LOG_MODULES = nsWindowsWidgets:5 (5 is the log level) You can use NSPR_LOG_MODULES=all:5 to enable all module logging
Finding source of regressions
- Do a binary search on the nightly builds until you narrow down a build that introduced the regression
- Use the push log to review changes in that time span
- Use MozRegression
Submitting a patch for review
- You don't have commit access at first, instead create a patch.
- Setup your author information (your ~/.hgrc or ~/mercurial.ini on Windows):
[ui]
username = Your Name <your@email.com>
- Use the mq extension, add to your ~/.hgrc or ~/mercurial.ini on Windows [extensions]
- When submitting do this
hgext.mq =
Working with hg and patches
- To create a patch:
hg qnew bugXXXXXX.patch
On popup: Bug XXXXXX - Description of your fix - To take a file out of a patch:
hg qrefresh -X re:regexp_pattern_of_files_to_remove - To refresh changes into your patch:
hg qrefresh - To see the status of changes: (after you take out files it should re-appear in the changes)
hg status - Undo application of a patch in your MQ patch queue: (Removes the patch from your commit tree and working directory)
hg qpop (To unapply the last applied patch)
hg qpop -a (To unapply all patches)
hg qpop name.patch (To unapply all patches up to but not including the specified patch) - Apply a patch which is in your MQ patch queue: (Re-adds the patch to your commit tree and working directory, you can apply more than one patch)
hg qpush (To apply the next patch in the series)
hg qpush -a (To apply all patches)
hg qpush name.patch (To apply all patches in the series up to and including the named patch) - List which patches are in your MQ patch queue:
hg qseries - List which patches in your MQ patch queue are applied (pushed):
hg qapplied - List which patches in your MQ patch queue are not yet applied (pushed):
qunapplied - To delete a patch from your MQ patch queue: (Patch must first be unapplied)
hg qdelete - To turn a patch into a permanent changeset: (Patch must first be applied)
hg qfinish - To turn a normal changeset into a patch: (Patch must first be unapplied)
hg qimport -r tip - Convert a patch to a finalized changeset: (Patch must first be applied)
hg qfinish tip
hg qfinish -a (for all of the patches
- To make a backup of your patches directory: (Saves the patches backup to .hg/patches.N)
hg qsave - To import someone else's patch into your MQ patch queue:
hg qimport patchname.patch (You must later also apply it with qpush) - To import someone else' patch with a different patch strip count:
patch -pN (to apply the patch, where N is the strip count of the patch)
qnew (to create a new patch)
hg addremove (to pickup any files added/removed by the patch)
qrefresh (to refresh the patch) - To change the ordering of how patches are applied
Manually edit your .hg/patches/series file, one patch name per line. - To rollup several patches into one
hg diff -r qparent > rollup.patch - See last 50 pushed
hg log -l 50 - Undoing a qfinish or remove last commit into a patch
hg qimport -r tip (Make sure you have no other patches applied) - To backout a revision
hg backout revnumber - Folding a patch in your queue onto another one
hg qgoto base_patch.patch
hg qfold patch_to_fold_in_base_patch.patch - Renaming a patch
hg qrename new_patch_name.patch - Merge all changes from parent repo into your branch
cd yourbranchdir
hg update
hg pull other-repo
hg merge
hg commit
hg push - Clone a repository up until a specific changeset
hg clone -r revisionid http://hg.mozilla.org/mozilla-central/ repo_name - Remove a changeset and all of its decendants
hg strip changesetid - Rebase one repository to another by beheading the old tip
cd repo_you_want_to_change
hg pull repo_to_change_to
hg heads .
hg update -r revisin_to_forget_about
hg commit --close-branch
hg update -r revision_to_use
hg push --force
Documentation
Testing and QA
- Automated testing link1 link2
- Litmus (Manual testing)
- Mochitest for testing via pages (HTML, XHTML, SVG, XUL, XBL) (mochitest-plain, mochitest-chrome, mochitest-browser-chrome, mochitest-a11y or mochitest-ipc)
- Browser chrome mochitest for testing via JS
- Reftests for testing if 2 pages that should render the same actually do
- Compiled code tests
- xpcshell for testing XPCOM components
Automated test run examples
- mochitest-plain:
TEST_PATH=content/html/content/test make -C $(OBJDIR) mochitest-plain - mochitest-chrome: (like a mochitest but with chrome privs)
TEST_PATH=widget/tests/ make -C $(OBJDIR) mochitest-chrome - mochitest-browser-chrome: (Chrome JS tests)
TEST_PATH=widget/tests/ make -C $(OBJDIR) mochitest-browser-chrome - xpcshell test, whole directory:
cd $(OBJDIR)
make -C widget/tests/ xpcshell-tests
- xpcshell single test:
cd $(OBJDIR)
make SOLO_FILE="testname.js" -C widget/tests/ check-one
- reftests:
TEST_PATH=image/test/reftest/reftest.list make -C obj-i686-pc-mingw32 reftest
Troubleshooting build problems
- I built on windows, and had crashes on startup:
The reason ended up being because I was using the same profile as my FF4 and some extensions were causing the crash (Firebug in particular). Simply disabling the extensions fixed the problem. - If you are building on Windows with VC2010, and get the error, install the Win7.0 SDK instead. Alternatively if you really want to use 7.1 you may need to patch your guess-msvc.bat
about:
- Blank page:
about:blank - Addons:
about:addons - To adjust settings:
about:config - To see how your Firefox was built:
about:buildconfig - To see all of your crash reports:
about:crashes - Other
Common about:config prefs
- Allow remote XUL from local computer:
dom.allow_XUL_XBL_for_file: true;
XPCOM objects in JavaScript
- Creating an XPCOM component:
var cid = "@brianbondy.com/componentname;1"
var obj = Components.classes[cid].createInstance();
obj = obj.QueryInterface(Components.interfaces.IMyInterface) - Listing XPCOM components:
for (var c in Components.classes) { print(c); } - Listing XPCOM interfaces:
for (var i in Components.interfaces) { print(i); }
How to push to try
- Need commit access level 1
- Try server info
- TryChooser - try command line generator
- Build bot results
- In .hgrc (or mercurial.ini) add:
[paths]
try = ssh://hg.mozilla.org/try
- To push the applied hg queue patches to the try server:
hg qrefresh --message "try: -b do -p all -u all -t all"
hg push -f try
How to push a changeset from your MQ
- If you want your patch to land on Aurora, or Firefox Beta you need to request it in Bugzilla. only for severe security, stability, or regressions recently introduced. Provide risk/reward in ticket.
- Need commit access level 3
- In .hgrc (or mercurial.ini) add:
[paths]
mozilla-inbound = http://hg.mozilla.org/integration/mozilla-inbound/
- To push:
Move your patch to the top of your queue
hg pull
hg update
hg qpush
hg qrefresh -m "Bug xxx - Blah. Blah. Blah. r=xyz"
hg qfinish -a
hg push mozilla-inbound
- Rules for pushing
Bugzilla keywords
- addon-compat: If your change may affect addon compatibility
- dev-doc-needed: If your change may need documentation
- regression: If your bug is a regression
- checkin-needed: If a checkin is needed for a patch but the author can't do it themselves because of privs or some other reason
- Others
Firefox UI debugging
- Extesion Developer Extension
- Or in any build of Firefox:
- Type about:
- Open the web console
- Type in the following:
- Components.utils.import('resource://gre/modules/Services.jsm');
- this.__proto__ = Services.wm.getMostRecentWindow('navigator:browser');
- Now you can use anything you can in the extensions developer extension
Contributor info and Metrics
Doing Code Reviews
- Code Review Guide
- Quick Points:
- MultiByte vs. Wide character set comm-central defaults to ASCII
- Check if platform API available pre Win2k
- Does it pass try?
- Formatting?
- Comments, typos, spelling
- Did you test in scenario X?
- New import libs in toolkit/library?
- Should it have tests?
- Interface change? Change IID, sr required, addon-compat keyword
- Documentation needed?
- Mark keywords for post-fix work: dev-doc-needed, privacy-review-needed, sec-review-needed, user-doc-needed, addon-compat, release tracking flags, in-testsuite flag
Commit flags
- Append to the end of patches:
- reviewed by: r=nickname
- approved by: a=nickname
- super reviewed by: sr=nickname
Mentoring bugs
- Add to whiteboard [mentor=bbondy]
- More info
Release cycle
- Every 6 weeks:
- Nightly -> Aurora
- Aurora -> Beta
- Beta -> Release
- Release calendar
Personal files on people.mozilla.com
- Add to your C:\Users\bbondy\.ssh\config file:
Host people.mozilla.com
User bbondy
IdentityFile C:\Users\bbondy\.ssh\bbondy.pub
- Your must already have L1 commit access, i.e. your public key is already on the server.
- You can upload files to a URL like: http://people.mozilla.com/~bbondy
Anything under the /home/bbondy/public_html will show up at the http address above. - On Windows connect with putty sftp:
psftp bbondy@people.mozilla.com
Enter your private key password
put filename.ext
Project Branches
- TBPL results: https://tbpl.mozilla.org/?tree=BRANCHNAME
- Self serve build API to create dep, Nightly, or PGO builds: https://build.mozilla.org/buildapi/self-serve/BRANCHNAME