mike chambers | about

Building and Packaging FireFox Extensions on OS X

Sunday, November 28, 2004

I have been learning how to build FireFox extensions on OS X. Actually doing a build and packaging it to install and test the extension is a little involved (you have to create multiple jar files and and an xpi file). Luckily there are a couple of scripts available that basically automate this process:

I am running on OS X so I was using the Bash / Linux script. However, this needed a few tweaks to get it to work correctly. Basically, I had to fix some path errors, and also get it to not package the mac .DS_Store folders.

Here is the updated script, which is based on the script found here.

#!/bin/bash
# build.sh: build JAR and XPI files from source
# based on Nathan Yergler's build script
# Modified to work on OS X by Mike Chambers (http://www.mikechambers.com)

#### editable items (none of these can be blank)
APP_NAME=helloworld    # short-name, jar and xpi files name.
HAS_DEFAULTS=0       # whether the ext. provides default values for user prefs etc.
HAS_COMPONENTS=0     # whether the ext. includes any components
HAS_LOCALE=0         # package APP_NAME.jar/locale/ ?
HAS_SKIN=1           # package APP_NAME.jar/skin/ ?
KEEP_JAR=1           # leave the jar when done?
ROOT_FILES="license.txt install.rdf install.js" # put these files in root of xpi
#### editable items end

TMP_DIR=build.tmp

#uncomment to debug
#set -x

# remove any left-over files
rm $APP_NAME.jar
rm $APP_NAME.xpi
rm -rf $TMP_DIR

# create xpi directory layout and populate it
mkdir $TMP_DIR
mkdir $TMP_DIR/chrome

if [ $HAS_COMPONENTS = 1 ]; then
  mkdir $TMP_DIR/components
  cp components/* $TMP_DIR/components
fi

if [ $HAS_DEFAULTS = 1 ]; then
  DEFAULT_FILES="`find ./defaults -path '*DS_Store*' -prune -o -type f -print | grep -v \~`"
  cp --parents $DEFAULT_FILES $TMP_DIR
fi

# Copy other files to the root of future XPI.
cp $ROOT_FILES $TMP_DIR

# generate the JAR file, excluding .DS_Store and temporary files
zip -0 -r $TMP_DIR/chrome/$APP_NAME.jar `find content -path '*DS_Store*' -prune -o -type f -print | grep -v \~`
if [ $HAS_LOCALE = 1 ]; then
  zip -0 -r $TMP_DIR/chrome/$APP_NAME.jar `find locale -path '*DS_Store*' -prune -o -type f -print | grep -v \~`
fi
if [ $HAS_SKIN = 1 ]; then
  zip -0 -r $TMP_DIR/chrome/$APP_NAME.jar `find skin -path '*DS_Store*' -prune -o -type f -print | grep -v \~`
fi

# generate the XPI file
cd $TMP_DIR
zip -r ../$APP_NAME.xpi *
cd ..

if [ $KEEP_JAR = 1 ]; then
  # save the jar file
  mv $TMP_DIR/chrome/$APP_NAME.jar .
fi

# remove the working files
rm -rf $TMP_DIR

In order to use this, you need to set up the directory structure in a specific way. Using the HelloWorld extension from this tutorial (highly recommended), the directory structure would look like this:

You can download the files and directory structure from here.

Notice that the build.sh file is in the same directory as the install.rdf. In order to build the extension, edit the parameters at the top of the build.sh file (at a minimum set the APP_NAME variable to match your extension name), and then just run it from the terminal. If it doesn’t run, make sure that it is set to be executable by running the following command:

chmod 755 ./build.sh

from the terminal.

Thanks to everyone in the Mozilla Extension forum for helping me out, roachfiend.com for a great extension tutorial, and to whoever wrote the Linux / Bash package script that the OS X script was based on.

twitter github flickr behance