Bash build script: Difference between revisions

From MozillaZine Knowledge Base
Jump to navigationJump to search
mNo edit summary
(→‎Script 1: fix from ryan@ryanium.com to support the content registration with flags ("content APPNAME content/ contentaccessible=yes"))
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{extdev}}
{{extdev}}


Two bash scripts that automate [[packaging extensions]].
__TOC__
== Script 1 ==
Here is a bash script I'm using to package my extensions (under [http://www.cygwin.com/ Cygwin]). See also [[Windows build script]].
Here is a bash script I'm using to package my extensions (under [http://www.cygwin.com/ Cygwin]). See also [[Windows build script]].


Line 7: Line 11:
# build.sh -- builds JAR and XPI files for mozilla extensions
# build.sh -- builds JAR and XPI files for mozilla extensions
#  by Nickolay Ponomarev <asqueella@gmail.com>
#  by Nickolay Ponomarev <asqueella@gmail.com>
#  based on Nathan Yergler's build script
(original version based on Nathan Yergler's build script)
# Most recent version is at <http://kb.mozillazine.org/Bash_build_script>
# Most recent version is at <http://kb.mozillazine.org/Bash_build_script>


# this script assumes the following directory structure:
# This script assumes the following directory structure:
# ./
# ./
#  chrome.manifest (optional - for newer extensions)
#  chrome.manifest (optional - for newer extensions)
#  install.rdf
#  install.rdf
#  (other files listed in $ROOT_FILES)
#  (other files listed in $ROOT_FILES)
#
#  content/    |
#  content/    |
#  locale/    |} these can be named arbitrary and listed in $CHROME_PROVIDERS
#  locale/    |} these can be named arbitrary and listed in $CHROME_PROVIDERS
#  skin/      |
#  skin/      |
#  defaults/    (only if $HAS_DEFAULTS=1)
#  components/  (only if $HAS_COMPONENTS=1)
#
#
# It uses a temporary directory ./build; don't use that!
#  defaults/  |
# Its output is:
#  components/ |} these must be listed in $ROOT_DIRS in order to be packaged
#  ...        |
#
# It uses a temporary directory ./build when building; don't use that!
# Script's output is:
# ./$APP_NAME.xpi
# ./$APP_NAME.xpi
# ./$APP_NAME.jar  (only if $KEEP_JAR=1)
# ./$APP_NAME.jar  (only if $KEEP_JAR=1)
Line 30: Line 37:
#      chrome/$APP_NAME.jar!/*
#      chrome/$APP_NAME.jar!/*


#### editable items
#
APP_NAME=helloworld  # short-name, jar and xpi files name
# default configuration file is ./config_build.sh, unless another file is
CHROME_PROVIDERS="content locale skin" # which chrome providers we have
# specified in command-line. Available config variables:
HAS_DEFAULTS=0      # whether to package defaults/
APP_NAME=         # short-name, jar and xpi files name. Must be lowercase with no spaces
HAS_COMPONENTS=0    # same for components/
CHROME_PROVIDERS= # which chrome providers we have (space-separated list)
KEEP_JAR=1          # leave the jar when done?
CLEAN_UP=         # delete the jar / "files" when done?       (1/0)
ROOT_FILES="readme.txt" # put these files in root of xpi
ROOT_FILES=       # put these files in root of xpi (space separated list of leaf filenames)
BEFORE_BUILD=./update_builddate.sh # run this before building
ROOT_DIRS=         # ...and these directories      (space separated list)
AFTER_BUILD=                       # and this after the build
BEFORE_BUILD=      # run this before building       (bash command)
#### editable items end
AFTER_BUILD=       # ...and this after the build   (bash command)
 
if [ -z $1 ]; then
  . ./config_build.sh
else
  . $1
fi
 
if [ -z $APP_NAME ]; then
  echo "You need to create build config file first!"
  echo "Read comments at the beginning of this script for more info."
  exit;
fi


ROOT_DIR=`pwd`
ROOT_DIR=`pwd`
Line 48: Line 67:


# remove any left-over files from previous build
# remove any left-over files from previous build
rm $APP_NAME.jar
rm -f $APP_NAME.jar $APP_NAME.xpi files
rm $APP_NAME.xpi
rm files
rm -rf $TMP_DIR
rm -rf $TMP_DIR


Line 57: Line 74:
mkdir --parents --verbose $TMP_DIR/chrome
mkdir --parents --verbose $TMP_DIR/chrome


# generate the JAR file, excluding CVS and temporary files
# generate the JAR file, excluding CVS, SVN, and temporary files
JAR_FILE=$TMP_DIR/chrome/$APP_NAME.jar
JAR_FILE=$TMP_DIR/chrome/$APP_NAME.jar
echo "Generating $JAR_FILE..."
echo "Generating $JAR_FILE..."
for CHROME_SUBDIR in $CHROME_PROVIDERS; do
for CHROME_SUBDIR in $CHROME_PROVIDERS; do
   find $CHROME_SUBDIR -path '*CVS*' -prune -o -type f -print | grep -v \~ >> files
   find $CHROME_SUBDIR \( -path '*CVS*' -o -path '*.svn*' \) -prune -o -type f -print | grep -v \~ >> files
done
done


zip -0 -r $JAR_FILE `cat files`
zip -0 -r $JAR_FILE -@ < files
# The following statement should be used instead if you don't wish to use the JAR file
# The following statement should be used instead if you don't wish to use the JAR file
#cp --verbose --parents `cat files` $TMP_DIR/chrome
#cp --verbose --parents `cat files` $TMP_DIR/chrome
Line 70: Line 87:
# prepare components and defaults
# prepare components and defaults
echo "Copying various files to $TMP_DIR folder..."
echo "Copying various files to $TMP_DIR folder..."
if [ $HAS_COMPONENTS = 1 ]; then
for DIR in $ROOT_DIRS; do
   mkdir $TMP_DIR/components
   mkdir $TMP_DIR/$DIR
   COMPONENT_FILES="`find components -path '*CVS*' -prune -o -type f -print | grep -v \~`"
   FILES="`find $DIR \( -path '*CVS*' -o -path '*.svn*' \) -prune -o -type f -print | grep -v \~`"
  echo $COMPONENT_FILES >> files
   echo $FILES >> files
  cp --verbose --parents $COMPONENT_FILES $TMP_DIR
   cp --verbose --parents $FILES $TMP_DIR
fi
done
 
if [ $HAS_DEFAULTS = 1 ]; then
  DEFAULT_FILES="`find defaults -path '*CVS*' -prune -o -type f -print | grep -v \~`"
   echo $DEFAULT_FILES >> files
   cp --verbose --parents $DEFAULT_FILES $TMP_DIR
fi


# Copy other files to the root of future XPI.
# Copy other files to the root of future XPI.
Line 96: Line 107:
   echo "Preprocessing chrome.manifest..."
   echo "Preprocessing chrome.manifest..."
   # You think this is scary?
   # You think this is scary?
   #s/^(content\s+\S*\s+)(\S*\/)$/\1jar:chrome\/$APP_NAME\.jar!\/\2/
   #s/^(content\s+\S*\s+)(\S*\/)(.*)$/\1jar:chrome\/$APP_NAME\.jar!\/\2\3/
   #s/^(skin|locale)(\s+\S*\s+\S*\s+)(.*\/)$/\1\2jar:chrome\/$APP_NAME\.jar!\/\3/
   #s/^(skin|locale)(\s+\S*\s+\S*\s+)(.*\/)$/\1\2jar:chrome\/$APP_NAME\.jar!\/\3/
   #
   #
   # Then try this! (Same, but with characters escaped for bash :)
   # Then try this! (Same, but with characters escaped for bash :)
   sed -i -r s/^\(content\\s+\\S*\\s+\)\(\\S*\\/\)$/\\1jar:chrome\\/$APP_NAME\\.jar!\\/\\2/ chrome.manifest
   sed -i -r s/^\(content\\s+\\S*\\s+\)\(\\S*\\/\)\(.*\)$/\\1jar:chrome\\/$APP_NAME\\.jar!\\/\\2\\3/ chrome.manifest
   sed -i -r s/^\(skin\|locale\)\(\\s+\\S*\\s+\\S*\\s+\)\(.*\\/\)$/\\1\\2jar:chrome\\/$APP_NAME\\.jar!\\/\\3/ chrome.manifest
   sed -i -r s/^\(skin\|locale\)\(\\s+\\S*\\s+\\S*\\s+\)\(.*\\/\)$/\\1\\2jar:chrome\\/$APP_NAME\\.jar!\\/\\3/ chrome.manifest


Line 110: Line 121:
zip -r ../$APP_NAME.xpi *
zip -r ../$APP_NAME.xpi *


cd $ROOT_DIR
cd "$ROOT_DIR"


echo "Cleanup..."
echo "Cleanup..."
if [ $KEEP_JAR = 1 ]; then
if [ $CLEAN_UP = 0 ]; then
   # save the jar file
   # save the jar file
   mv $TMP_DIR/chrome/$APP_NAME.jar .
   mv $TMP_DIR/chrome/$APP_NAME.jar .
else
  rm ./files
fi
fi


Line 124: Line 137:
$AFTER_BUILD
$AFTER_BUILD
</pre>
</pre>
Example <tt>config_build.sh</tt> file:
<pre>
#!/bin/bash
# Build config for the build script, build.sh. Look there for more info.
APP_NAME=helloworld
CHROME_PROVIDERS="content locale skin"
CLEAN_UP=1
ROOT_FILES="readme.txt"
ROOT_DIRS=
BEFORE_BUILD=
AFTER_BUILD=
</pre>
== Script 2 ==
The extension has to be packed for distribution as .xpi file. To automate this, you can use a small shell script which does the zipping for you:
#!/bin/bash
buildid=$1
<nowiki>[[ "$buildid" == "" ]]</nowiki> && buildid=cvs-`date +%Y%m%d`
xpifile=dispmua-$buildid.xpi
cd src
zip -r ../messenger-dispmua.jar . -x "CVS"
cd ..
mkdir chrome
mv messenger-dispmua.jar chrome/
rm "$xpifile"
zip "$xpifile" chrome/messenger-dispmua.jar install.rdf
rm -r chrome/
echo -n Created file:
ls "$xpifile"
Of course you have to change the jar file name from messenger-dispmua to one matching your extension, but you see how to do it.
One more thing: If you pass a parameter to the script, it is taken as the version and appended to the name of the xpi file


[[Category:Development]]
[[Category:Development]]

Latest revision as of 12:20, 11 July 2010

This page is part of the extension development documentation project.

Ask your questions in MozillaZine Forums. Also try browsing example code.

Note: development documentation is in process of being moved to Mozilla Development Center (MDC).

Two bash scripts that automate packaging extensions.

Script 1

Here is a bash script I'm using to package my extensions (under Cygwin). See also Windows build script.

#!/bin/bash
# build.sh -- builds JAR and XPI files for mozilla extensions
#   by Nickolay Ponomarev <asqueella@gmail.com>
#   (original version based on Nathan Yergler's build script)
# Most recent version is at <http://kb.mozillazine.org/Bash_build_script>

# This script assumes the following directory structure:
# ./
#   chrome.manifest (optional - for newer extensions)
#   install.rdf
#   (other files listed in $ROOT_FILES)
#
#   content/    |
#   locale/     |} these can be named arbitrary and listed in $CHROME_PROVIDERS
#   skin/       |
#
#   defaults/   |
#   components/ |} these must be listed in $ROOT_DIRS in order to be packaged
#   ...         |
#
# It uses a temporary directory ./build when building; don't use that!
# Script's output is:
# ./$APP_NAME.xpi
# ./$APP_NAME.jar  (only if $KEEP_JAR=1)
# ./files -- the list of packaged files
#
# Note: It modifies chrome.manifest when packaging so that it points to 
#       chrome/$APP_NAME.jar!/*

#
# default configuration file is ./config_build.sh, unless another file is 
# specified in command-line. Available config variables:
APP_NAME=          # short-name, jar and xpi files name. Must be lowercase with no spaces
CHROME_PROVIDERS=  # which chrome providers we have (space-separated list)
CLEAN_UP=          # delete the jar / "files" when done?       (1/0)
ROOT_FILES=        # put these files in root of xpi (space separated list of leaf filenames)
ROOT_DIRS=         # ...and these directories       (space separated list)
BEFORE_BUILD=      # run this before building       (bash command)
AFTER_BUILD=       # ...and this after the build    (bash command)

if [ -z $1 ]; then
  . ./config_build.sh
else
  . $1
fi

if [ -z $APP_NAME ]; then
  echo "You need to create build config file first!"
  echo "Read comments at the beginning of this script for more info."
  exit;
fi

ROOT_DIR=`pwd`
TMP_DIR=build

#uncomment to debug
#set -x

# remove any left-over files from previous build
rm -f $APP_NAME.jar $APP_NAME.xpi files
rm -rf $TMP_DIR

$BEFORE_BUILD

mkdir --parents --verbose $TMP_DIR/chrome

# generate the JAR file, excluding CVS, SVN, and temporary files
JAR_FILE=$TMP_DIR/chrome/$APP_NAME.jar
echo "Generating $JAR_FILE..."
for CHROME_SUBDIR in $CHROME_PROVIDERS; do
  find $CHROME_SUBDIR \( -path '*CVS*' -o -path '*.svn*' \) -prune -o -type f -print | grep -v \~ >> files
done

zip -0 -r $JAR_FILE -@ < files
# The following statement should be used instead if you don't wish to use the JAR file
#cp --verbose --parents `cat files` $TMP_DIR/chrome

# prepare components and defaults
echo "Copying various files to $TMP_DIR folder..."
for DIR in $ROOT_DIRS; do
  mkdir $TMP_DIR/$DIR
  FILES="`find $DIR \( -path '*CVS*' -o -path '*.svn*' \) -prune -o -type f -print | grep -v \~`"
  echo $FILES >> files
  cp --verbose --parents $FILES $TMP_DIR
done

# Copy other files to the root of future XPI.
for ROOT_FILE in $ROOT_FILES install.rdf chrome.manifest; do
  cp --verbose $ROOT_FILE $TMP_DIR
  if [ -f $ROOT_FILE ]; then
    echo $ROOT_FILE >> files
  fi
done

cd $TMP_DIR

if [ -f "chrome.manifest" ]; then
  echo "Preprocessing chrome.manifest..."
  # You think this is scary?
  #s/^(content\s+\S*\s+)(\S*\/)(.*)$/\1jar:chrome\/$APP_NAME\.jar!\/\2\3/
  #s/^(skin|locale)(\s+\S*\s+\S*\s+)(.*\/)$/\1\2jar:chrome\/$APP_NAME\.jar!\/\3/
  #
  # Then try this! (Same, but with characters escaped for bash :)
  sed -i -r s/^\(content\\s+\\S*\\s+\)\(\\S*\\/\)\(.*\)$/\\1jar:chrome\\/$APP_NAME\\.jar!\\/\\2\\3/ chrome.manifest
  sed -i -r s/^\(skin\|locale\)\(\\s+\\S*\\s+\\S*\\s+\)\(.*\\/\)$/\\1\\2jar:chrome\\/$APP_NAME\\.jar!\\/\\3/ chrome.manifest

  # (it simply adds jar:chrome/whatever.jar!/ at appropriate positions of chrome.manifest)
fi

# generate the XPI file
echo "Generating $APP_NAME.xpi..."
zip -r ../$APP_NAME.xpi *

cd "$ROOT_DIR"

echo "Cleanup..."
if [ $CLEAN_UP = 0 ]; then
  # save the jar file
  mv $TMP_DIR/chrome/$APP_NAME.jar .
else
  rm ./files
fi

# remove the working files
rm -rf $TMP_DIR
echo "Done!"

$AFTER_BUILD

Example config_build.sh file:

#!/bin/bash

# Build config for the build script, build.sh. Look there for more info.

APP_NAME=helloworld
CHROME_PROVIDERS="content locale skin"
CLEAN_UP=1
ROOT_FILES="readme.txt"
ROOT_DIRS=
BEFORE_BUILD=
AFTER_BUILD=

Script 2

The extension has to be packed for distribution as .xpi file. To automate this, you can use a small shell script which does the zipping for you:

#!/bin/bash
buildid=$1
[[ "$buildid" == "" ]] && buildid=cvs-`date +%Y%m%d`
xpifile=dispmua-$buildid.xpi
cd src
zip -r ../messenger-dispmua.jar . -x "CVS"
cd ..
mkdir chrome
mv messenger-dispmua.jar chrome/
rm "$xpifile"
zip "$xpifile" chrome/messenger-dispmua.jar install.rdf
rm -r chrome/
echo -n Created file:
ls "$xpifile"

Of course you have to change the jar file name from messenger-dispmua to one matching your extension, but you see how to do it. One more thing: If you pass a parameter to the script, it is taken as the version and appended to the name of the xpi file