Blog

  • FSOSS 2010 – Terrific!

    This past week was Open Source week in Toronto, the last two days of which held Seneca College’s 9th annual Free Software and Open Source Symposium. Always being bogged down with projects around reading week, this was my first in three years that I’d attended. Coming out of it I wish I had gone every year I could. Next year I won’t get the student discount πŸ™

    Wednesday I hoped to attend the Level Up Game Jam, a day-long workshop on using WebGL, HTML5 Audio and JavaScript, but alas couldn’t attend. Though Thursday…

    Thursday 9-12: Game Development using Processing.js

    I attended a workshop by Game Jam speaker Andor Salga on Processing.js. Originally written using Java syntax as an MIT project in 2003, Processing was ported to JavaScript by jQuery inventor and web guru John Resig. Seneca has since been heavily involved with its development. An amazing platform, I found I picked it up incredibly easily and was able to whip up a game in 30 minutes, a game which would be later dubbed “Negative Pong”.

    Single-player and mouse-driven, the object of the game is to keep the ball bouncing as long as possible without letting it go by your paddle. As there is no way to “win” your score counts down from 0 every time time you “drop the ball”. There was no time for audio, multi-player or keyboard controls, but this little tech demo was a great intro to the language. Inspired, I may have a new project (Processing, not Negative Pong) to spend some of my contribution time on. Then Friday hit.

    Friday 11-12: Web Audio

    This was one I was highly looking forward to. Having just learning some Processing (and thanks to discussions with Dave during class), I was eager to learn the other half of the coin. It’s unbelievable how far web audio has come in the last short bit. Intense visualizations, pure JavaScript text to speech, and a demo of Mozilla’s Flight of the Navigator js experience, tuned for FSOSS pictures and Twitter stream. While most of my work this last bit has been with <video>, Dave’ latest challenge has me exploring making my own visualizations. I’m working now on fine-tuning pitch-determined colours. Dave’s presentation can be found here.

    Friday 1-2: WebGL Game Jam Results

    The WebGL Game Jam Results. This was the followup to Wednesday’s day-long missed workshop. The results were great with quite a few innovative 2D and 3D games. Some, like mine, were little more than proof of concept games but others had had more time put into them and came out as great fully-functional WebGL-driven 3D games. Was great fun, and midway on a forum seemed to develop as the audience got involved. Watch the presentation here and watch out for 5:09 πŸ™‚

    Friday 2-3: Federating the Social Web

    Being involved with Mozilla, I wanted to attend at least one presentation from another standpoint. James Walker came from microblog producer Status.net to speak about OStatus, an open protocol developed to try and cull a few of the issues they’ve identified with microblogging and cross-site communication. Not having so much as a Twitter account, I felt the most out of my element going into this presentation, and fittingly learned the most coming out. Always an engaging speaker, you can watch “walkah” speak here.

    Friday 3-4: Mozilla Drumbeat: open innovation for everyone

    Mozilla Drumbeat: the project to make the web awesome. This was a great presentation as well. Matt Thompson came from Mozilla to discuss Drumbeat, they’re mission and what they’re doing to make things better. In true Open Source and Community fashion, the floor was then turned midway through into a Q&A and feedback session, generating discussion that I felt said more about the initiative, its strengths and its challenges than could have possibly been covered in a strict presenter-to-audience setting. Everyone in the room was an equal, with the audience answering each other’s questions, with Matt posing and answering his own into the mix. In a word I found it: collaborative. Watch it here.

    Aftermath

    The reception was great, I enjoyed every minute of it, and even had fun volunteering to take apart the demo room and bring computers back to CDOT. At the end of the day it didn’t matter who had spoken and who had heard, who was presenting or who had learned. It seemed we were all just there to share and broaden ourselves and have a great time with Open Source.

  • How PHP Process Control went wrong

    Well, with the occurrence of reading week I’ve been a bit behind on my blogging. When I last wrote about PHP Process Control, all seemed fine and dandy. A simple call or two, maybe a foreach loop after to process lines of output, nothing majorly wrong. All the theory worked. After experimenting with it though, I found a few issues.

    Firstly, processing control is handled very differently on different operating systems. Windows is fairly do-it-itself without much worry of permissions, groups, ownership or pathing. When getting things to work in a *NIX environment however, a bit of debugging was involved.

    Actually, a lot was and all I had to go off of was an OS return code and a great many googlings.

    Lesson 1: Pathing and the 127 Return Code

    What is the 127 return code above? That’s the first of many issues I ran across: inability to find the process.

    There is that trap every Windows-centric developer falls into at one point or another when working on Linux: forgetting that searching for an executable on Linux will not check the current directory by default. What does this mean in the case of PHP Process control? Specify an absolute directory for the executable. This is easy in PHP though if it’s in the directory the script is running in (or any sub directory):

    • __DIR__ is a magic constant that identifies the directory of the current script (only in PHP 5.3)
    • dirname(__FILE__) extracts the absolute directory from the absolutely-qualified location of the current script (like above, but supported back to PHP 4.0.2)

    There are other reasons for requiring a full path, but I didn’t realize those until learning lesson 3.

    Lesson 2: Permissions and 126 return code

    Ah yes, file permissions. Any of many permission-related issues may come up (I’m still not sure if I accounted for everything but the implementer of my work says all is well) but all these issues fall under the umbrella return code of 126. This is where things got real mucky. Apache executes under a user account (‘www’ on some machines, ‘apache’ on others, ‘httpd’ or ‘nobody’ on still others) for performing any interactions with the OS. In systems where permissions are exclusive rather than inclusive (any *NIX environment) this becomes an issue if not dealt with. So be sure to:

    1. Determine the user that Apache runs under (place ‘passthru(“whois”);’ in a PHP script)
    2. Give that user rights to execute the shell script
    3. Run normally

    Note that this may not be enough. The executable must be in a directory accessible by the apache user account (so keep your files away from /root/). Normally though, these permission issues seemed to arise as a result of running in a web context through a web server. In other words, the script will still likely work if run from the command line like so:

    php myScript.php

    Lesson 3: Apache Environment and the 127 return code

    So our script has passed the above two checkpoints and is guaranteed to run, right? WRONG! These never came up with my own simple implementation of calling a shell script which just catted data around, but shell scripts which call other user-defined shell scripts or executables may still be in for an issue. This is because the Apache user may run in an environment with only a partial path (/bin, /sbin or /usr/bin may not be included by default).

    This is an extension of Lesson 1: Set up the environment at the top of the shell script to be sure everything will work.

    So, a retrospect on my first foray into PHP Process Control: 30 minutes to research, 30 minutes to code, 4 hours to debug. Did the age-old programming wisdom of “expect things to take twice as long as you’d expect” hold? Most definitely. Did I learn a lot and enjoy every minute? Most definitely.

  • Git ate my code: Remoting and the “Gotchas”

    Git isΒ  a powerful tool. You can commit saved work never to be lost again, branch and merge with ease, and manage source code changes without a care in the world. And all this from your local machine without so much as a 14.4k modem. But what if you want to share your work or build off of some else’s? This is where remoting comes in.

    Remoting involves the management of remote repositories and syncing of code to be in line with your own. Remoting is not about directly working with code in a remote repository however. Rather, it is usually involves the movement of code to your local machine where it is then managed and pushed back to a publicly-accessible repository.

    The first step is retrieving code from the public repository. If you’re just creating your project this is done by using the clone command:

    git clone remoteUri localRepo

    This command will pull all commits from the repository remoteUri and recreate them in a repository named localRepo on your local machine. What it also does is store that remoteUri under an alias (origin by default) so that you can put code back in the remote repository later. You can register other remote repositories for your repo by using the add flag for the remote command:

    git remote add alias remoteUri

    Here, alias is the short name for the uri (origin, remote-master, it can be anything!) and remoteUri is once again the location of the remote repo. These aliases will be used when moving code to and from the repository. You can verify that the repository was entered by specifying the -v flag on the remote command:

    git remote -v

    Ah yes, moving code around. You can bring code to your machine by using the pull or fetch commands. Both are similar, though pull will perform an automatic merge while fetch will not. The following command sets are equivalent:

    git pull origin branchName

    git fetch origin
    git merge origin/branchName

    Either of the above will bring code into your current working copy and merge the contents with your work. After putting your two cents in and fixing bugs or adding (undocumented) features it’s time to put the code back into the public repository using the push command:

    git push origin

    There we go, simple simple. Why bring the code to the local machine though, why not just work off the remote repo directly? A few days ago I tried this:

    git checkout origin/master

    I though “I’ll just work off a remote branch, fix a bug and commit my changes without having to push/pull”. Here’s where I learned the true nature of a branch. A branch is simply a pointer to a commit (with a commit being an accumulation of the changes, or a diff, since the last commit). A commit also contains a record to the commit before it, building a chain of changes that allow for the determination of a file’s contents. The thing about pointers is… they’re only local! By checking out a remote branch I began working in what git warned me was a detached HEAD state, which meant that my changes were effectively being written off somewhere in space with no knowledge of what commit on your local machine to use as the basis for the next commit (somewhere on a remote machine was anyone’s guess).

    Now git is great and user friendly but if you ignore the 10-line warning message like I did you may put in lots of time, commit your work, change branches and then wonder where your work went. Even though the changes won’t be reflected in any of your named branches, git never eats commited code. Every commit results in a hash code key to act as the identifier for that commit. All you have to do is use the hash code as the branch name (“git checkout 123ea4123a3aef8bd87ae”).

    But who wants to type in THAT each time. Since branches are just pointers to these commits, you can create a branch on that commit and then can reference it much easier:

    git checkout 123ea4123a3aef8bd87ae
    git branch rescuedBranch

    From here we can either continue to work on it like a normal branch or merge it back to another branch on your local machine. How to get this hash code though? Simple, we go through git’s logs. If you are still on the detached branch, simply call the reflog command to retrieve a list of recent commits and their hashes:

    git reflog

    If you committed and then switched to another branch it will take a little bit more work. The log command outputs a history of commits made and if you specify the –all option you can see everything. For some extra flair, the –graph option outputs a graph showing the various branches and merges that occurred as well:

    git log --all --graph

    Like any good Linux-inspired tool, git work great with other utilities such as grep if you know a bit more information about the commit like the Date, commit messages or Author. For an explanation of that though, I’ll defer to a git professional.

  • BBB.js 0.1 Release

    Releasing early and often, time for 0.1 of the HTML5 Open Video Player!

    Kevin and I have been busy working on enhancing functionality for the <video> element, allowing a user to break a video into bookmarks (a.k.a. chapters) and to create a sequential playlist. Each chapter will have a start time and end time, along with the designation of a title and description. Chapters can be specified from one or more videos and can be played individually or in sequence. A working demo can be seen on Kevin’s or my sites.

    Behind the scenes, there is also an implementation of JSON serialization and deserialization for chaptering data, which may have applications for storage either locally or remotely. My efforts this phase were focused on video timing, DOM Manipulation and JSON.

    Looking forward to our 0.2 Release (projected for November 16), I will be working on ironing out the few remaining integration/timing bugs and implementing TTXT subtitling. We also hope to allow for a configuration file to make its way into this upcoming release as well. Our project page and blogs will show regular updates and code can be found on our github repos.

    The final vision is to modularize this project to allow for integration into existing video players like Video.js, frameworks like Popcorn.js and client-server applications when possible. We currently are working on using Video.js as our implementation player in our demo.

  • Sequentially-playing HTML5 Videos

    In attempting to make a custom playlist for our video player, Kevin and I have been working on two key features: ability to take a subsection of a video and treat it as a “chapter”, and the ability to link multiple chapters together to create a playlist (or “book” if you prefer the literary analogy).

    Either way, we’re close to getting everything working. Jumping around in a video works great, as does getting one video to jump to the next. The issue is getting the two to work together with events and timing being synchronized properly (see below):

    Sequentially playing videos from one <video> tagOn slow network connections, events are being fired at inappropriate times, leaving videos to progress onto the next before the first has finished buffering. Perhaps we’ll have to move away from the timeout method of video advancement to get this to work, but either way our 0.1 release is shaping up for shipping out. With a few tweaks of course πŸ™‚

  • OOP JavaScript, JSON, and DOM Manipulation

    In continuing to develop some more tools for the HTML5 Open Video Player, I’m now working on cookie management and a structure of storage to display video bookmarks. Brave new world.

    I began by going back to my OOP Experiments and figuring out what was wrong. Turns out that by only defining properties inside the constructor and not as a prototype, they are only accessible from the scope of that object but not the prototype. So when it came time to reference them inside a prototyped function… BOOM. Well that’s a big hurdle down.

    With an object now able to contain functions I began looking into cookie storage. Not difficult, with the document.cookie property and some clever string manipulation storage and retrieval of strings was easy:

    // Cookie of key "name" and value "val"
    document.cookie = "name=val";
    // Split cookie string into array of name-value strings
    var cookieArray = document.cookie.split(";");

    With cookie storage figured out, it was time to get my JS object into a string. At first there was a simple comma-separated value string but given that we’re shooting for JSON for other parts of our project why stop there? JSON is used like XML for object descriptions but as it’s also syntactically valid JS one can simply push it to the JS’s eval function and it’s ready for instantiation. Of course, this opens a whole load of security holes and so even the official JSON spec recommends at least regular expression validation prior to eval’ing but noting the preference of a parser.

    Seems there is some browser support for native JSON (which eerily has some versions coinciding with browser support for html5 video), but I have difficulty verifying this list on anything but Firefox. Seems the latest versions of Chrome and Safari both give “Unexpected End” errors while IE8 complains that “JSON is undefined” and Opera just plain stops. So the easiest solution isn’t possible but what’s development without a little wheel re-invention?

    JSON parsers have already been written in many languages, and after investigating them there seemed to be 2 leaders: json2.js and json_sans_eval.js. Both are fast, with json2 focusing on validation while json_sans_eval focusing on security. Both are open source and in the public domain but since the Bookmark object is simple (see below) I opted for the latter with manual validation performed afterward. Experimentation showed malformed JSON simply yielded some expected properties as undefined.

    // Bookmark object, minimal validation
    function Bookmark(src, title, startTime, endTime) {
    this.title = title;
    this.src = src;


    if (startTime < endTime) {
    this.startTime = startTime;
    this.endTime = endTime;
    } else {
    this.endTime = startTime;
    this.startTime = endTime;
    }
    }


    Bookmark.prototype.title = "";
    Bookmark.prototype.src = "";
    Bookmark.prototype.startTime = 0;
    Bookmark.prototype.endTime = 0;
    Bookmark.prototype.toString = function() {
    return "Source: "+this.src+"\nTitle: "+this.title+"\nStart Time: "+this.startTime+"\nEnd Time: "+this.endTime;
    }

    With all this together, it was time for DOM manipulation and dynamic tables. At first I thought this would be easy, with nothing but a call to createElement() to make the row followed by setting the innerHTML like so:

    var tr = document.createElement('tr');
    tr.innerHTML = // Row content HTML goes here
    tbl.appendChild(tr);

    In theory this approach would be quicker since its one call to manipulate the main DOM structure (tbl.appendChild) but IE 8 seems to balk when creating the element. So it’s back to basics and DOM Level 1:

    // Add bookmark to table of contents and global array
    function addElem() {
    var tbl = document.getElementById('tblOfContents');
    var bkmrk = new Bookmark(document.getElementById('bkmrkSrc').value,
    document.getElementById('bkmrkTitle').value,
    document.getElementById('bkmrkStart').value,
    document.getElementById('bkmrkEnd').value);


    var tr = tbl.insertRow(1);
    var srcElem = document.createElement('a');


    srcElem.href = 'javascript:playChapter('+chapters.length+');';
    srcElem.innerHTML = bkmrk.src;
    tr.insertCell(0).appendChild(srcElem);


    tr.insertCell(1).appendChild(document.createTextNode(bkmrk.title));
    tr.insertCell(2).appendChild(document.createTextNode(bkmrk.startTime));
    tr.insertCell(3).appendChild(document.createTextNode(bkmrk.endTime));


    // Add bookmark to a global array of objects as well as have data in table
    chapters.push(bkmrk);
    }

    And so there we have it: a high-level overview of OOP JS, JSON and DOM Manipulation. There is plenty of room for improvements (tests at Quirksmode.org show that a few years ago, using innerHTML was magnitudes quicker than table function calls) but a working implementation is a working implementation, and soon the iterative process will take care of optimizations. For now: application of this code to create chapters within a video!

  • Advanced Git: Branching

    In continuing exploration into Git, Dave has explained a bit more about the architecture of it. It seems quite different from the SVN I’m used to, but luckily he pointed out a great e-resource. Beyond simple commiting, Git (like any good source control tool) has the ability to branch. All changes are logged incrementally, with a branch representing a pointer to the change log. There is always a branch in Git, even master is a branch. Each branch may have many commits to it, with the latest commit for the current working branch being designated as HEAD. Multiple commits to a branch form a chain of changes dating back not to the beginning of the branch but the beginning of the repo. This is because the beginning of the branch can be thought of as the accumulation of all changes on the trunk up until that point.

    Each commit points to one before (backward looking list, results in “tree” when viewed graphically. Commit typically have one parent but in the case of a merge they will have n parents (with n being the number of branches merged in that change set). As a result, a graph of commits in a repo form a web of pointers across many change sets. Here’s a relatively mild visualization (courtesy of progit):

    A web of commit pointers charting changesets
    Commit Pointer Web

    It’s easy to get the hang of so long as one remembers the commands. Here are a few commonly used ones:

    // Create branch, stay on working copy (be sure to be on copy you wish to branch from)
    git branch branchName

    // Merge from branchName into current branch
    git merge branchName

    // View all branches
    git branch

    // Switch to other branch (failure to commit changes from last branch will cause error.
    // Failure to stage changes from last branch before switching may accidentally affect moved-to branch)
    git checkout branchName

    // Create and checkout new branch
    git checkout -b branchName

    // Shows current branch as well as status of modified/staged/committed
    git status

    This is great, almost there (the last piece of the puzzle being remoting). That’s coming up soon!

  • Gettin’ into Git and PHP Process Control

    After my last foray with Mercurial, I’m now beginning to work with the distributed source control tool Git. And I like it. Like Hg, it seems it’s used for many projects including the Canvas 3D JS Library C3DL. Like SVN it provides source control, but unlike SVN it is great for its decentralized attitude and being able to run entirely locally if necessary. The learning curve is great too (almost linear) thanks to documentation like kernel.org’s 20 Everyday Git Commands.

    Of course Git isn’t enough to get any development done. I’ve been delving into PHP and how to issue commands to OS shells and receive output. Seems there are a lot of different options depending on what you want to do. The basic operations can be used via the system or exec functions, each of which return data back to the calling PHP script for further work. These two differ in two ways:

    • system() allows an array to be filled with all lines of the script output
    • exec() returns the entire output as a string rather than just the first line of output

    In situations where the above isn’t enough or when dealing with binary output, the passthru function does the job nicely. This function seems to be the best of the lot: piping the script output directly back to the request stream rather than into PHP (which then goes to the stream) saves a ton of overhead if no additional formatting is required before displaying script output to the user.

    As great as these functions are, the entire branch of PHP dealing with process control and program execution require PHP safe mode to be turned off. So it’s easy to use, just some configuration required.

  • Experiments with OOP Javascript and Timed Subtitles

    In continuing prototyping, I’ve been introducing myself to Object Oriented JavaScript. My exercise? To develop a system of changing text displayed on the screen through use of objects and closures. I’ve been reading up on theory since September but this was a real feet-wetting: my first advanced JavaScript and not all of it worked.

    I decided to go with 2 classes: TimedText and TimedTextManager. For those familiar with patterns, they’re in a composition relationship. For those who aren’t: TimedTextManager is responsible for containing and handling all interactions with TimedText. TimedText represents some text to display after a certain delay.

    This test code was really quick and messy, but it got things done. I ran into some issues and as a result it’s no where near as elegant as I’d hoped. The biggest issue is resolving scope within the TimedTextManager.play function. Whether the prototype function declaration was placed inside the TimedTextManager constructor or after it, Firefox’s JS compiler issues errors about being unable to resolve class-level variables. As a result, variables were duplicated to being local within the TimedTextManager.play function rather than the original declarations within the constructor itself (Commented out code shows the original declarations).

    The changes outlined above have produced a working but not workable solution. Perhaps a closure within a function of an object prototype results in unforeseen scope resolution? I wonder if anyone can shed any light on this.

  • Building Mozilla Firefox on Windows 7

    I’d always thought it would be scary building a large application like Mozilla Firefox completely from source, but a few weeks ago I did some initial looking into it. With a recent nudge from a professor, I went ahead and successfully retrieved the source and compiled Firefox. Here’s how I did it.

    Step 0: I read the documentation.

    Not just a little either, but everything you can to build Firefox on Windows. Mozilla Developer Central has an extensive series of wiki entries dedicated solely to multi-platform building. The build system is complex and issues may come up. If you’re like me you want to get your hands dirty and you’ll ignore the “Impatient” route they suggest.

    Step 1: Review Build Preqrequisites.

    An extensive system has extensive prerequisites for various versions. Feeling ambitious, I decided to try building the most-recent code for the upcoming Firefox 4. Going off a checklist, I worked my way down:

    Hardware Requirements

    Mozilla requires a “development-class system” to compile. With the following hardware, I was above their recommended specs:

    • AMD Phenom X3 8450
    • 3 GB RAM
    • 100+ GB HDD space
    • Windows 7 Professional 32-bit

    Software Requirements

    These are the tools required by the Mozilla build system. I already had a Visual C++ Compiler and Windows SDK, but still to be downloaded was the MozillaBuild System (found here). Given my target product of Firefox 4, my compiler version needed to supported. Firefox 4 is compatible with Visual Studio 2005, 2008 and 2010. My configuration for compiling is below:

    • Visual Studio Ultimate 2010
    • Windows SDK 6.0A, 7.0A, and 7.1
    • MozillaBuild 1.5.1

    MozillaBuild was installed by default to “C:\mozilla-build” (you can change this, just don’t include spaces in the path name!) and with it came a bevy of tools. Windows versions of VIM and python are there, along with the software source control program used by Mozilla (Mercurial, found in “C:\mozilla-build\hg”). With hardware and software dependencies taken care of, it was time to get the source code!

    Step 2: Grabbing the Source Code

    Mozilla uses Mercurial to manage source control and versioning. Mercurial is an application which, if you’re following along to the T should have been installed along with MozillaBuild in Step 1. If not, you can find installation instructions here. Once downloading it though, it came time to configure Mercurial. Mercurial uses an ini file to store settings, which must be created from scratch after installation. Here’s how to do it:

    1. Open Notepad (or another text editor)
    2. Save the empty file to Mercurial’s install directory (“C:\mozilla-build\hg”)

    This file will drive the source retrieval process. Mozilla has a few recommended settings listed on their wiki, copied into my own Mercurial.ini and shown below:

    [ui]
    username = Your Real Name <user@example.com>
    merge = your-merge-program (or internal:merge)


    git = 1
    showfunc = 1
    unified = 8

    [defaults]
    commit = -v

    Name is easy enough to fill in, but the merge tool entry may be one of many things. A few of the wiki editors on MDC prefer tools such as kdiff, but having already had TortoiseSVN and TortoiseMerge installed, I decided to use TortoiseMerge by setting the value to the absolute path of the program (“C:\Program Files\TortoiseSVN\bin\TortoiseMerge.exe”). Merge tools come in many flavours though, with a comprehensive listing here.

    Actually Grabbing the Code

    With the configuration all set, I just had to choose a location to store the source code and then to retrieve it. The location should have no spaces (I chose D:\FFsrc\src20). Then simply call “hg clone http://hg.mozilla.org/mozilla-central/ D:\FFsrc\src20″ from the command line with the parameter after clone being the location to clone from and the last argument being the location to close to. Mozilla Central is the trunk, which at this point will become Firefox 4.

    Mercurial at Work
    Mercurial at Work

    By default, the MozillaBuild installation does not modify the PATH variable on your computer and Windows won’t know what program hg is unless you are in the Mercurial root directory (C:\mozilla-build\hg). You can fix this like so:

    1. Right click on My Computer
    2. Choose Properties
    3. Choose “Advanced” (may show as “Advanced Settings”)
    4. Click “Environment Variables”
    5. Scroll down the list of System variables until you find PATH
    6. Double-click the entry
    7. Move to the end of the string and enter “;C:\mozilla-build\hg” without quotes
    8. Click OK
    9. Click OK
    10. Click OK

    At this point the command to pull code from Mozilla’s source repository should work when run from anywhere. Restarting the system may be required for any changes made to the PATH variable to take effect. Pulling the files will take a while: the complete source as of today’s date weighs in at a hefty 670 MB.

    Step 3: Configuring the Build

    Firefox uses a file (.mozconfig) to specify build options, which are then passed to the make file. This is an ordinary text file with options specified one-per-line, located at the root of the source tree (in my case, D:\FFsrc\src20). There are an extensive number of options which may enable the creation of one of any of the Mozilla products all outlined in their documentation. At the bottom of that page is a listing of several recommended configurations for builds such as Release Firefox, Firefox Debug, Thunderbird Debug and SeaMonkey Optimized (not statically linked). I went with the Firefox release configuration, shown below:

    . $topsrcdir/browser/config/mozconfig
    mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/ff-opt
    ac_add_options --disable-tests

    After creating a .mozconfig file (much the same way you create the Mercurial.ini file) enter the above in your .mozconfig and save it to the root for your source (D:\FFsrc\src20). While this doesn’t seem like many commands, a great many which are not specified have default values, and often defaults result in the best overall performance. A dissection of the options shows a variable, topsrcdir,with relative paths specified for object generation (MOZ_OBJDIR). This will be the location all compilation output (including our final Firefox executables) will reside within.

    With everything in place, it’s time to cross our fingers and build Firefox.

    Step 4: Building Firefox

    Here is where all the diligent work above pays off. The build takes a long time (50 minutes using the hardware, software and build configurations listed above) and may easily take more depending on your build options.

    Compilation is performed through a unix-style shell included in the MozillaBuild install from Step 1. This is run in the form of one of many batch scripts (located at the root install directory for MozillaBuild), each with customizations for whether the compiler used will be Visual Studio 2003, 2005, 2008 or 2010. Using Visual Studio 2010, the appropriate file for me is start-msvc10.bat. While I am on a 32-bit OS and their are 64-bit versions of the scripts, developers on the wiki caution against using the experimental 64-bit versions.

    Whichever shell is right for you, the final steps to building are:

    1. Run the appropriate build file
    2. Make the source root your current directory (cd “D:\FFSrc\src20”)
    3. Type “make -f client.mk build” without quotes and hit enter

    Building Firefox
    Building Firefox

    Every stage of the build is written to standard output (the console) by default, so you can watch the build progress every step of the way. By the end of the build process you should have your very own build of Firefox. You can find it in the default Windows location of MOZ_OBJDIR\dist\bin\firefox.exe, as specified in your .mozconfig file in Step 3.

    Enjoy your custom-built Firefox!