Deploying Firefox 2 within the Enterprise: Part 5

IMPORTANT! Some of the information in this post is not correct. I will be updating it soon.

Updated: See section on serving the update.xml file

OK, now that we have MAR files, how do we get them to our users?

Setting Up a Firefox Update Server

A Firefox update server is actually not that complex of a setup. Basically a Firefox update server takes a URL that describes a particular Firefox version, and if there is an update available, it returns an XML file that identifies the location of the update. So let's take a look at this URL.

If you are to go into about:config and search for app.update.url, you would see the following:


https://aus2.mozilla.org/update/1/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/update.xml

When Firefox 2.0.0.3 looks for an upgrade (English on Windows), the URL looks like this:


https://aus2.mozilla.org/update/1/Firefox/2.0.0.3/2007030919/WINNT_x86-msvc/en-US/release/update.xml

Most of this URL is self explanatory. The only part we need to explain is BUILD_ID. The build ID of a Firefox is a unique identifer that conveys the exact date down to the hour when a build was created. For the build above, that data is March 9, 2007 at 7:00 PM. You can see the build ID for any Firefox build by type about: in the URL bar. Note that selecting Help->About does not display the complete build ID. If you build a custom version of Firefox, you can see the build ID by looking in the file mozilla/obj/config/nsBuildID.h. If you see a build ID of 0000000000 in this file, it means that you forgot to set MOZILLA_OFFICIAL and BUILD_OFFICIAL before building.

If we look at the URL that is served, it ends in update.xml. So what do these update.xml files look like? Here's the update.xml to upgrade from Firefox 2.0.0.2 to Firefox 2.0.0.3. (https://aus2.mozilla.org/update/1/Firefox/2.0.0.2/2007021917/WINNT_x86-msvc/en-US/release/update.xml)

<?xml version="1.0"?>
<updates>
  <update type="minor"
          version="2.0.0.3"
          extensionVersion="2.0.0.3"
          buildID="2007030919"
          detailsURL="http://en-US.www.mozilla.com/en-US/firefox/2.0.0.3/releasenotes/">
    <patch type="complete"
           URL="http://download.mozilla.org/?product=firefox-2.0.0.3-complete&amp;os=win&amp;lang=en-US"
           hashFunction="SHA1"
           hashValue="bc64376c13867b5524d71e87f7ad98e727f2d3f4"
           size="7617299"/>
    <patch type="partial"
           URL="http://download.mozilla.org/?product=firefox-2.0.0.3-partial-2.0.0.2&amp;os=win&amp;lang=en-US"
           hashFunction="SHA1"
           hashValue="2555dcad94c9bc1c7327cb3699844f633888ea4a"
           size="270514"/>
  </update>
</updates>

Rather then go into a lot of detail here about this file, I'd rather point you to wiki.mozilla.org which has a great explanation of this file. (Incidentally, the wiki you can lots of other great information about the Software Update process) One thing you might be wondering is how to generate the hashValue. Microsoft has a tool available called FCIV that can be used to generate the hashes.

OK, we know the URL and we have the update.xml file, so how do we serve it to the browser?


Update: as Benjamin Smedberg pointed out, I am doing a lot of work for nothing. mod_rewrite can be used to accomplish this task. Create a file called "noupdate.xml" that contains <updates></updates>Then put this in a .htaccess file:

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*) noupdate.xml

What this says is if you find the file, serve it, if you don't, serve the file that represents the empty update.


At first, it looks like we can just setup directories that correspond to the URL, but this won't work since we need to send an XML file that looks like:

<updates>
</updates>

If there are no updates available. So I'm going to use a simple PHP file to function as our update server. We'll need to do some changes to our web server configuration as well. Note I am using Apache.

First go into httpd.conf and make sure that mod_rewrite is available. Then go into your main web directory and add or edit the file .htaccess with this:

RewriteEngine on
RewriteRule ^/?update/(.*) /update.php/$1 [L]

What this rule says is whenever you see a URL that begins with "update" send it to update.php. The actual update.php file looks like this:

<?php
header("Content-type: text/xml");

$url_array=explode("/",$_SERVER["REQUEST_URI"]);
$noidea=$url_array[2];
$product=$url_array[3];
$version=$url_array[4];
$build_id=$url_array[5];
$build_target=$url_array[6];
$locale=$url_array[7];
$channel=$url_array[8];
$filename=$url_array[9];

$updatefile = "$noidea/$product/$version/$build_id/$build_target/$locale/$channel/$filename";
//echo "$updatefile";

if (file_exists($updatefile)) {
  $handle = fopen($updatefile, "r");
  $contents = fread($handle, filesize($updatefile));
  echo "$contents";
  fclose($handle);
} else {
  echo '';
  echo '';
}
?>

This PHP simply looks for the presence of an update.xml directory structure specified by the URL and if it is available, it returns it, otherwise it returns <updates></updates>

So how do we publish updates then? We simply create an update.xml file and place it in the appropriate subdirectory.

The last step is updating the browser to point to our new update URL. Your first thought might have been to simple update app.update.url in about:config, but that will not work. When app.update.url is queried by Firefox, it always looks for the "default preference" which means that even if a user changes the preference, it won't be used. For testing purposes, you can add a new preference called "app.update.url.override" that will work, but when you go to deploy your updates, you should set app.update.url in an extension like the CCK. That will cause it to become a "default preference."

One more installment to go. I'll try to address some general deployment issues, and if you have questions (any questions), PLEASE let me know.

Operator and DOM Mutation Events

This is working so well, I have to tell the world.

I just added support for DOM Mutation events to Operator. So now when DOM nodes are added and removed from the document, Operator will update appropriately.

But that's not the coolest part...

I added support for the DOMAttrModified event. So combined with Firebug, you can actually interactively modify your HTML to add/remove/modify a microformat and Operator will update live based on the changes you make. It's REALLY sweet.

New version coming soon....

Deploying Firefox 2 within the Enterprise: Part 4

My original topic was Setting up your own update server to deploy Firefox patches. I think what I am going to do is split things up into two sections - Creating Firefox Update files and setting up a Firefox Update Server. So...

Creating Firefox Update Files (MARs)

Firefox 2.0.0.3 and 1.5.0.11 were released yesterday (March 21, 2007), and at some point in the next few days, if you use Firefox, you'll receive a message telling you that an update is available. Alternatively, you can go to Help->Check for Updates... and Firefox will connect to an update server to check to see if there is an update available. If you deploy Firefox in a large corporation, you might want to either prevent your users from getting Firefox updates until you have certified them, or you might want to push your own updates to Firefox that include additional function. Today we're going to talk a little about how the update process works and how you can create your own update files. In the next installment we'll talk more about how the update process works and how to push updates to your users.

In the distant past, whenever there was an update to Firefox, users had to download a new installer and basically reinstall Firefox. To solve this problem, a new update system for Firefox was created. This system uses a file format called MAR which is short for Mozilla Archive. The MAR file contains the binary diffs for files that have changed in the update, or if the bzipped diffs are larger than the file they are patching, it contains the entire file. Whenever a new version of Firefox is released, two MAR files are created as can be seen with Firefox 2.0.0.3. The partial MAR is used to upgrade users directly from Firefox 2.0.0.2 to Firefox 2.0.0.3. The complete MAR is used if the partial upgrade could not be applied correctly or if you are on a version of Firefox that is more than one version behind.

To provide an update server within your enterprise, you'll have to create your own MAR files based on your custom Firefox builds. Today we're going to talk about creating those files.

Before we get started, we need to make a few fixes to our build tree. Basically the problem is that the update packaging scripts weren't working with the MozillaBuild tools in Firefox 2.0.0.2. First we need to patch the update files. Download the patch from bug 373121 and place it in the mozilla/tools/update-packaging directory. Then type:

patch < bugmsysupdate-packaging-1.8.patch

Once this change has been made, we need to make a small change to our build tools. Go to the mozilla-build/msys/bin directory and copy the file sh.exe to bash.exe. (Future versions of MozillaBuild will have bash.exe.) Alternatively, you can just grab the latest version of MozillaBuild (1.1).

OK, now we're ready to get started. First we need to build the diff utility we need. Go to the mozilla/obj/other-licenses/bsdiff directory and type make. Next we're going to build the full MAR file. This is the easy part. Go to the mozilla/obj/tools/update-packaging directory and type make. Once this process completes, if you look in the mozilla/obj/dist/update directory, you'll see the file firefox-2.0.0.2.en-US.win32.complete.mar. This is the complete MAR file we talked about earlier.

Creating the partial MAR file requires a little more work. Since a partial MAR is a diff between two versions of Firefox, we'll need to have the two versions of Firefox we want to diff against in separate directories so that we can create the partial MAR. If you want to create a partial MAR against your own custom Firefox 2.0.0.3, you'll need to create a new build tree and build Firefox 2.0.0.3 using the instructions in the first post. (Change FIREFOX_2_0_0_2_RELEASE to FIREFOX_2_0_0_3_RELEASE) We're going to take a shortcut and use the files that were created as part of the official Firefox 2.0.0.3 release.

The partial MARs are created by diffing the contents of two complete MAR files. So what we'll need to do is create two directories and unpack the complete MAR files into those directories. Let's make two directories. For convenience, we'll put them under the mozilla/tools/update-packaging directory. One we'll call ff2002 and the other we'll call ff2003. Copy the complete MAR that you created above into ff2002 and download the complete MAR for Firefox 2.0.0.3 and put it into ff2003.

In order to unpack the MAR files, there are tools in the mozilla/tools/update-packaging directory. There is a PERL script called unwrap_full_update.pl and a shell script called unwrap_full_update.sh. Either one can be used. The tools assume that mar.exe is in the path or pointed to by an environment variable. Let's go ahead and put it in the path by copying mar.exe from mozilla/obj/dist/host/bin to mozilla-build/moztools-180compat/bin. (Ugly I know, but convenient). Now we need to go to the ff2002 directory where we put the MAR file and unpack it. The unwrap scripts work in the current directory, so running them will look something like this:

perl ../unwrap_full_update.pl firefox-2.0.0.2.en-US.win32.complete.mar

or

sh ../unwrap_full_update.sh firefox-2.0.0.2.en-US.win32.complete.mar

Once you have unpacked the MAR file, delete the original MAR file or move it out of the way so that we don't diff it. Then do the same process for the 2.0.0.3 MAR file.

Creating the partial MAR is actually done using make, so once we've unpacked the MAR files, we'll need to go back to the mozilla/obj/tools/update-packaging directory. There are a few environment variables we need to set in order to tell the partial MAR packaging what to do.

SRC_BUILD_ID and DST_BUILD_ID
These names aren't totally accurate. They are actually the version numbers of the two builds. They will be used to name the output MAR file. For our builds, they are 2.0.0.2 and 2.0.0.3
SRC_BUILD and DST_BUILD
These actually point to the locations of the files we just unpackaged.

So:

SRC_BUILD_ID=2.0.0.2; export SRC_BUILD_ID;
DST_BUILD_ID=2.0.0.3; export DST_BUILD_ID;
SRC_BUILD=../../../tools/update-packaging/ff2002; export SRC_BUILD;
DST_BUILD=../../../tools/update-packaging/ff2003; export DST_BUILD;

Then type make partial-patch.

And that's it! In the mozilla/obj/dist/update directory, you'll see the file firefox-2.0.0.2.en-US.win32.partial.2.0.0.2-2.0.0.3.mar. Which is the partial MAR between Firefox 2.0.0.2 and Firefox 2.0.0.3.

Obviously in this post I chose to place files in certain locations that made it easier to describe the process. With the information I have presented, you might find a way to simplify this process. If you have better ideas on how to do this stuff, please let me know. I'm going to look at making changes to the build process to try to simplify this.

Next time we'll talk about how to get those files to our users.

Deploying Firefox 2 within the Enterprise: Part 3

Creating a Firefox installer

Continuing where we left off...

Now that we have built Firefox, our next step is to build the installer. Before we do that, however, we need to place our custom extensions in our build so that they get packaged with Firefox.

There are three ways that extensions can be installed in Firefox: user extensions, application extensions, and registry-install extensions. When a user installs an extension from a web page, it is installed in their profile directory and is called a user extension. If the user switches profiles, that extension is no longer available to them. Alternatively, extensions can be installed in the extensions directory where the firefox executable is located. If extensions are installed here, they are called application extensions. These extensions essentially become a part of the application install, so they are available to any profile that is created. (Note that when an application extension is upgraded, the upgrade is done as a user extension, so if you switch to another profile, the extension needs to be upgraded again.)

We want to package our extensions as application extensions, so we need to place them in the extensions directory under the executable so that the installer packages them as a part of Firefox. In our build, this directory is located at mozilla/obj/dist/bin/extensions, so let's go there and install our extensions.

If you look in the extensions directory, you'll see one or more directories. Each of these directories represents an extension. The names of the extension directories are determined by the ID of the extension. These IDs can either be UUIDs like {972ce4c6-7e08-4474-a285-3208198ce6fd} or they can be an email format like name@extensions.domainname.tld. When we first place the extensions we want to install into this directory, we won't know the ID of the extension, so we'll have to create a temporary directory in which to unzip the extension. Once we've unzipped the extension, we'll be able to find out the ID of the extension and then we can rename the directory appropriately.

To install an extension, create a temporary directory under the extensions directory and unzip the XPI that corresponds to the extension into the temporary directory. Once you have unzipped the XPI file, you should see a file called install.rdf in the temporary directory. If you edit this file, you will see a line that looks like this:

name@extensions.domainname.tld

or this

{972ce4c6-7e08-4474-a285-3208198ce6fd}

The value in the middle is the extension ID. We will need to rename the temporary directory to match this ID. Note that when you rename the directory, you might need to enclose the ID in quotation marks.

You should follow the above process for all extensions you want to preinstall, including the CCK you created in Step 2.

There's one other small change we might want to make before we build the installer. This step is needed if there are files we want to remove as part of our install. For instance, when we deployed Firefox originally inside of IBM, we used a version of the CCK that wasn't as self contained as the current version. We can use this method to cleanup any files that might be left behind. The file that we want to change is removed-files.in in the mozilla/browser/installer directory. The format of this file is very simple. Just add any files you want to remove during installation to the list. Make sure you use forward slashes. Also note that the top level directory for anything referenced in this file is the directory where the firefox executable is located.

The build system maintains a list of all files that should be a part of the Firefox package. Because our files aren't in that list, we're going to have to make a small change to the build system before we build the installer. First go to the directory mozilla/toolkit/mozapps/installer. Then download the patch file. Save it in the directory mozilla/toolkit/mozapps/installer. Now go to a command line and type patch < packager.mk.patch. What this change does is cause the build process to copy all the files we just placed in the extensions directory before it builds the installer.

Now we are ready to actually build our installer. Go to the mozilla/obj/browser/installer directory and type:

make installer

After this process completes, your installer executable will be in:

mozilla/obj/dist/install/sea

If you need to do an unattended install you can invoke the executable with the parameter /S. You can get more information on customizing the installer from the Mozilla Wiki.

Next time we'll talk about creating an update server and producing update files for Firefox.

Deploying Firefox 2 within the Enterprise: Answering Some Questions

Some questions have already come up about the posts I've written, and rather than answering in comments or in a post at the end, I'd like to address some of them now. Note that I'm paraphrasing most of the questions.

Why would you need to build your own custom version of Firefox? Couldn't you just customize the build that Mozilla produces?

There are a couple answers to this question.

Answer: Custom Fixes

There might be cases where a fix is needed for your enterprise that either will not make it into the source code fast enough, or will not be accepted at all.

Last year we had a problem with a buggy IBM printer driver that caused Firefox to crash printing certain web pages. The most problematic pages seemed to be IBM internal pages. Unfortunately, this particular driver was in use for just about every printer inside IBM. The fix for this problem was unfortunate: it involved putting some exception handling in Firefox to catch the printer driver crash. We weren't sure it was going to make it into the source code fast enough to meet our needs, so we actually prepared to build a custom Firefox. Luckily we were able to get the fix in and we deployed the next Firefox 1.5 update quickly. But this could have certainly turned into a case where we needed to ship a custom version of Firefox.

You might run into similar cases where you might need a feature or fix that is not available in the version of Firefox you have deployed.

Answer: You Might Need to Extend Support Beyond what Mozilla Offers

A lot of people might not realize this, but the Mozilla Corporation policy is that they will only provide security fixes for software for six months after the release of the next major version. So for instance, Firefox 2 was released on October 24, 2006 so support for Firefox 1.5 will be discontinued on April 24, 2007.

For consumers, this might not be an issue, but for enterprises and educational institutions this can be a problem. Let's start with educational institutions.

Check out this excellent comment from UK Web Focus. The problem is that educational institutions tend to deploy new software during the summer break. So Firefox 1.5 will be out of support before the spring semester is over. Things would have been even worse if Firefox 1.5 had been released in August or September.

But educational institutions are only part of the story. Let's talk about the enterprise. I've worked with a number of companies deploying applications so what I'm going to talk about here are real world scenarios.

Scenario 1: Piloting and Testing takes six months or more

For a large enterprise to deploy a new web browser, there is a process that must be followed to ensure that the browser works with their internal infrastructure. Usually this involves the IT folk installing the browser locally and doing some initial testing, piloting the browser with some small group of people, and then eventually deploying the new web browser to the rest of their organization. In addition, if there are major changes to the browser (as there was with Firefox 2), there are other organizations that must be involved like the help desk or web application teams. The help desk will need to do things like rewrite support scripts or other training material. The web application teams will need to test the new browser with their applications. If either of these teams run into problems, this would delay the release of the new web browser to the entire organization.

As we mentioned before, Firefox 2 was released on October 24, 2006. If you are in a large organization like mine, you are aware that very little happens at the end of the year whether due to vacation or lack of funding. So if an enterprise were to start the process of deploying Firefox 2, it would not start until probably mid January. So essentially an enterprise has about three months to complete the process that I have detailed above. In my experience this process can take six months to a year.

Scenario 2: Deployment windows

In some large enterprises, there are "deployment windows." That is to say specific times of the year when new software can be deployed. These deployment windows can be any time during the year, but experience has shown they they are typically in the fall and they are usually once a year or even once every two years.

Right away, you can see a problem. With a once a year deployment window, you will have at least six months where the browser is unsupported.

What can I do?

In theory, you could cherry pick security fixes from Firefox 2 security releases and backport them to Firefox to 1.5. This is clearly not an optimum solution.

Is there a good solution?

The fact is that life cycle for enterprise software needs to be one year at the minimum, two years preferred. If this is something that is important to you, you should at least let Mozilla Corporation know. This also might be a great business opportunity for some enterprising folk...

Why is the CCK a wizard? Why isn't the information provided in your post a part of the CCK?

The Firefox CCK was designed to look and work exactly like the Netscape CCK. If you were to install the Netscape CCK, you would see that a lot of the text is even the same. The CCK is not a tool that is designed to be used every day. Most organizations would probably only use it once or twice a year. For that reason, it was designed to be minimalist. The CCK was a one man project (me) so I would certainly appreciate any help anyone wanted to provide in helping to maintain the CCK. The source code is available here.

Can I set preferences for extensions within the CCK?

I believe that if you set the preferences and then locked them in the CCK, they would not be overridden when the extension is installed. The problem has to do with load order. If you just set them in the CCK, when the extension is loaded, it overrides the preferences that were set by the CCK.

Bonus Question: What if I just want to rename the browser or change the branding? Do I have to build it?

I needed an excuse to plug my other extension, so here it is. If you ever need to rename Firefox for some reason (like for instance, to call it Iceweasel), I have creating an extension that specifically facilitates changing all the branding in the browser including the product name, the images in the about screen, and the icons. That extension is called Rebrand.

Our next installment is tomorrow, and we'll talk about building the Firefox installer with our custom extensions.

Deploying Firefox 2 within the Enterprise: Part 2

Adding Enterprise specific customizations to Firefox

In this installment, we're going to talk about customizing Firefox for deployment in your enterprise/organization.

Use the CCK Wizard.

Wow, that was easy. OK, maybe a little too easy. Let's go into some detail about what the CCK is, where it came from, and what it does now. (Note that this history is simplified quite a bit.)

In the 4.x days, there were two tools from Netscape for customizing the browser, one called Mission Control Desktop and one called the Client Customization Kit. The Mission Control Desktop was intended for enterprise customization and deployment of Netscape Navigator/Communicator, while the Client Customization Kit was more intended for ISPs and OEMs to customize Netscape Navigator/Communicator for their customers. Both of these tools were written in Java and actually produced full installers when they were finished. (For more information about the differences between Mission Control Desktop and the Client Customization Kit, you can checkout the Netscape Everywhere Custom Browser Distribution Program Frequently Asked Questions.)

When Netscape 6 was released, Netscape again provided a Client Customization Kit. This CCK was more focused on a customized install rather than enterprise features. This customized install included things like customizing the home page, help menu, bundling XPIs into the install, etc. It produced a full install package and could also produce a CD installer. Note that Netscape 7 also used a similar CCK.

While the source code for the Netscape 6/7 CCK is in the Mozilla source tree, it is Windows only and tailored towards a suite type distribution, so I decided to write a new CCK from scratch that produced an extension that could be installed into Firefox to provide the necessary customizations. And so the CCK Wizard was born.

The CCK Wizard is an extension for Firefox that walks you through a set of page to customize Firefox and then generates an extension that can be installed into Firefox to enable your customizations. Let's take a tour of the CCK Wizard.

Deploying Firefox 2 within the Enterprise: Part 1

I'm actually going to take a break from Operator for a few days to talk about deploying Firefox 2 within the Enterprise. Note that when you deploy Firefox within an enterprise or organization, you can customize Firefox without worrying about Mozilla trademark policies. Just be sure your customized Firefox is not deployed outside of your enterprise or organization.

We're going to cover:

  1. Building a custom version of Firefox
  2. Adding Enterprise specific customizations to Firefox
  3. Creating a Firefox installer
  4. Setting up your own update server to deploy Firefox patches

My assumptions are going to be that you actually need to build Firefox for your own purposes, not that you can simply use a prepackaged build from Mozilla. Also, I'm going to focus on Windows. If you don't need to actually build Firefox, you can use the CCK Wizard to customize Firefox (we'll talk more about that in part 2) and the Firefox Release Repackager to repackage it. The Firefox Release Repackager is Mac only right now, but I've sent Ben a patch to make it work on Windows as well.

Setting up a Firefox build environment

The Windows Build Prequisites page at MDC has the information on setting up a build. In order to recreate an official build, you'll need to have Microsoft Visual C++ version 6. Unfortunately, this is not available anymore, so you might have to get it from eBay. I can't say enough about the MozillaBuild package that bsmedberg put together. It makes setting up a build really easy.

Building Firefox

Once you have setup the build environment, it's time to get the code and build Firefox. Create a directory in which to check out your code and then change to that directory:

mkdir firefox
cd firefox
Checking Out the Code

Now we need to check out the code. We're going to checkout Firefox 2.0.0.2.

cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -r FIREFOX_2_0_0_2_RELEASE mozilla/client.mk
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -r FIREFOX_2_0_0_2_RELEASE mozilla/browser/config
.mozconfig file

Now we're going to go into the mozilla directory and create a .mozconfig file. This file specifies the configuration options for the build. Here's what ours looks like:

. $topsrcdir/browser/config/mozconfig

mk_add_options MOZ_CO_TAG=FIREFOX_2_0_0_2_RELEASE
mk_add_options MOZ_CO_MODULE=mozilla/other-licenses/bsdiff,mozilla/tools/update-packaging

mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj

ac_add_options --enable-update-channel=release
ac_add_options --enable-official-branding
ac_add_options --enable-optimize
ac_add_options --disable-debug
ac_add_options --disable-tests
ac_add_options --enable-static
ac_add_options --disable-shared
ac_add_options --enable-svg
ac_add_options --enable-canvas
ac_add_options --enable-update-packaging
ac_add_options --enable-extensions=default,-inspector

Most of this file you don't have to worry about, but let me explain a few pieces:

mk_add_options MOZ_CO_TAG=FIREFOX_2_0_0_2_RELEASE

This sets the tag we will be checking out from (not really needed since we checked out a makefile that had the corresponding tag, but we'll put it there just in case)

mk_add_options MOZ_CO_MODULE=mozilla/other-licenses/bsdiff,mozilla/tools/update-packaging

This specifies additional code we need to check out in addition to the base Firefox code. These two directories will be needed when we do update packaging.

mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj

This specifies that we want to build our code in an "obj" directory. This means that the output code is separate from the source code, so if we want to easily remove the output code, we can just remove the obj directory.

ac_add_options --enable-extensions=default,-inspector

This specified that we do not want to include the DOM Inspector in our build. This is going to be our "customization" for this build, although if this is really all we wanted to do, there are easier ways.

Incidentally, the way we knew most of these options, was by typing about:buildconfig in a Firefox 2 build. This gives us the official list of build config options.

Building a Localized Firefox

There's a possibility you might want to build a version in another language. For instance, if you wanted to build the French version of Firefox, you could add the following to your .mozconfig file:

mk_add_options MOZ_CO_LOCALES=fr
mk_add_options LOCALES_CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/l10n
ac_add_options --enable-ui-locale=fr

Final Steps

In order to build "official" builds, you must set two environment variables in your build environment:

MOZILLA_OFFICIAL=1; export MOZILLA_OFFICIAL;
BUILD_OFFICIAL=1; export BUILD_OFFICIAL;

If you don't set these, your builds will have a build ID of 00000000.

Now we're ready to build. Go to the mozilla directory and type:

make -f client.mk

And wait patiently until the source code is pulled and the build is finished.

If you need to apply patches, you'll need to pull and build the code separately:

make -f client.mk pull_all

Now you can any apply patches or changes that you want in your custom version of Firefox. This might be a bugzilla patch that is not included in the default Firefox, or other changes. Then:

make -f client.mk build_all

In our next installment, we'll go over customizing and packaging an installer.

SXSW Wrapup

I'm back to work after an action packed few days.

SXSW Interactive started Friday night and when I got there, the line was outrageous, so I thought I was going to miss the first panel I wanted to attend. After waiting a little bit, I mentioned to a volunteer I was a panelist and he said "What are you waiting in this line for?" and sent me to the panelist check-in. Membership has its privileges :). After getting my badge, I went to How to Rawk SXSW. This gave me a chance to meet Tantek in person which was cool. Then I grabbed some free food at a party and headed home.

Saturday I skipped SXSW and instead headed with my wife and a couple friends to San Antonio to volunteer at the Dave Ramsey Live Event. Awesome time. It's actually the fifth time we've volunteered. I can't recommend this event enough (or Dave Ramsey in general) if you are looking to get control of your finances.

Sunday morning I got up a little late and rolled in to SXSW. I missed the 10:00 round, but caught Non-Developers to Open Source Acolytes: Tell Me Why I Care at 11:30 which was a really good session. After a quick lunch, I headed into the show floor to check out the booths, including the Firefox booth. Mary Colvig was there, as well as Rhian and Alex Polvi.

To start the afternoon, I went to Perspectives on Designing for Global Audiences which wasn't what I expected, but at least I ran into Jonas Sicking. After that session, I went to AJAX or Flash: What's Right for You? which was a great session about when Flash or Ajax is appropriate. Slides for that session are available at slideshare.net. That was followed up with The Future of JavaScript which convinced me to actually look forward to the sunsetting of Firefox 1.5 so I can use some new JavaScript features in Operator. At 5:00, I attended People-Powered Products where I learned about lulu.com which is a great site where you can publish your own stuff.

Sunday night, I went to the Microsoft party to get some free stuff, didn't win the XBox 360, then headed over to the web awards for more free food. Then I decided to call it an early night.

Monday I got in a little later, but saw an interesting presentation by Timothy Ferriss on The 4-Hour Workweek. While I don't agree with his stance on debt and credit, the presentation was very interesting and gave me some interesting things to think about, in particular the concept of selective ignorance. Looking forward to the book. At 11:30, I went to American Cancer Society: Applying Disruptive Technology for the Nonprofit Sector which was an excellent presentation about what the American Cancer Society is doing to embrace new technology. The coolest thing they showed was the Second Life Relay For Life. After the session, I got to talk with a couple guys about developing church websites and maybe got some leads on help for updating our church website.

After that session, It was almost go time for the microformats panel. I went back to the show floor and lost track of time, so I was a little late to the green room, but no one else was there yet, so I was OK. Once everyone showed up, we chatted a little about the order of things and then Tantek put on his T-shirts and we headed over. The room was full, depsite being up against Dan Rather. I thought the panel went great. You can check out some photos or blog posts including Wired. Lots of people came up afterwards with good things to say about Operator, including some folks from Yahoo!, Apple and emurse. Also got a chance to meet Eric Meyer. He made a nice comment about Operator moving forward the semantic web. I also met a guy from developerWorks who wants to put microformats on their website. After the session, I helped a guy from opensoul.org debug a problem in Operator which I fixed, as well as a problem with his site which he fixed.

After the session, I caught the tail end of Warren Spector on The Future of Storytelling and then went to the WaSP Annual Meeting: Takin' it to the Street.

After the sessions, I was looking forward to the Mozilla Democracy Party, so I headed over. They had some good BBQ but I realized my place was at home with my family, so after eating, I headed out. Here's some pics of the party.

Tuesday I wanted to be there at ten to catch Browser Wars Retrospective: Past, Present and Future Battlefields. Two very cool things during this panel - first, Arun plugged Operator in one of the questions, and second I realized that I knew Arun from a way previous life when I worked on the OS/2 version of Netscape Navigator out at Netscape. The session as a whole was very interesting. Also very cool is that I ran into Steve Ganz before the session, who I know only because I use his resume for testing hResume :).

The last session I attended at SXSW was After Bust 2.0: Ten Years Later, Where Will We Be? which was an entertaining session, although not terribly informative. After the session I grabbed a quick lunch at P.F. Chang's and then realized that the weather was getting bad. I decided to head home early so I didn't get caught in the rain.

All in all, a great conference although I desperately wish IBM had been there demoing more of our stuff. In particular, we have two products that would have been great to see here, the AJAX Toolkit Framework for developing AJAX applications and our enterprise social software, Lotus Connections.

Incidentally, here's some cool pictures of the river behind our house before and during the rain (we're 90 feet up, so we don't have to worry about it). Unfortunately, we didn't get a picture when the water was really high, completely covering the area on the left.

Before the rain:

Before The Rain

During the rain:

During The Rain

Operator Source Code is Finally Available

Update:ufJS and ufJSParser have ended up being integrated into Microformats.js. This will also be the core microformats code in Firefox 3. The API is documented here.

My apologies for taking so long, but the Operator source code is finally on svn.mozilla.org

For now, this includes ufJS and the ufJSParser. I am working on creating a separate project elsewhere to specifically cover the ufJS work, but for now it will be hosted with Mozilla labs.

The code is available under the trilicense.

Obviously I will accept contributions, but there is the potential that the ufJS work will be available under a different license such as the CPL, so contributors need to be aware of that.

The code in SVN corresponds to 0.7a plus hAtom support as well as fixes for the McAfee SiteAdvisor problems.

Enjoy.