123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- #!/bin/bash
- #
- # This is a "compiler" for JTalk code. Run without arguments for help.
- # Get JTalk root directory from the location of this script so that
- # we can find the st and js directories etc.
- # Earlier we used this but it does not work on Mac
- # JTALK=$(readlink -f `dirname ${0}`/..)
- TARGET=`dirname ${0}`/..
- pushd . >/dev/null
- cd $TARGET
- JTALK="`\pwd -P`"
- popd >/dev/null
- function usage {
- cat <<ENDOFHELP
- Usage: $0 [-N|D|E] [-K|C|J] [-o] [-O|-A] [-g] [-p prefix] [-m class] [-M file]
- [-i] [-I file] [file1 [file2 ...]] [Program]
- Will compile Jtalk files - either separately or into a runnable complete
- program. If no files are listed only a linking stage is performed.
- Files listed will be handled using these rules:
- *.js
- Files are concatenated in listed order.
- If not found we look in $JTALK/js
- *.st
- Files are compiled into .js files before concatenated.
- If not found we look in $JTALK/st.
- NOTE: Each file is currently considered to be a fileout of a single class
- category of the same name as the file!
- If no Program is specified each given .st file will be compiled into
- a .js file. Otherwise a <Program>.js file is linked together based on
- the options:
- -N or -D or -E
- Compilation target. Currently Node.js, D8 (V8 shell) or Enyo (webOS 3.0).
- All currentl imply "-K -I" so boot.js and Kernel.js are added first and init.js
- is added last.
- -K
- Add libraries to get minimal Jtalk Kernel running.
- -C
- Add libraries to get minimal Jtalk Compiler running.
- -J
- Add libraries to get minimal Jtalk IDE running.
- -o
- Optimize each js file using the Google closure compiler.
- Using Closure at ~/compiler.jar
- -O
- Optimize final <Program>.js using the Google closure compiler.
- Using Closure at ~/compiler.jar
- -A Same as -O but use --compilation_level ADVANCED_OPTIMIZATIONS
- -g
- Compile Jtalk code in debug mode - include source and references etc.
- -p prefix
- Add <prefix> to compiled js files so that File.st is compiled into
- <prefix>File.st.
- -l library1,library2
- Load listed libraries (no spaces) into Compiler before compiling.
- -L library1,library2
- Load listed libraries (no spaces) into Compiler before compiling and also
- into Program.js in listed order.
- -i file
- Add library initializer <file>.
- -I
- Add library standard initializer $JTALK/js/init.js
- -m class
- Add call to #main in class <class>.
- -M file
- Add javascript file <file> at the end acting as main.
- Example invocations:
- Just compile Kernel.st to Kernel.js:
- jtalkc Kernel.st
- Compile Hello.st to Hello.js and create complete program called
- Program.js for Node.js and adding a call to class method #main
- in class Hello:
- jtalkc -N -m Hello Hello.st Program
- Compile two .st files into corresponding .js files,
- and link with specific myboot.js, myKernel.js, myinit.js
- and main.js and create complete program called Program.js:
- jtalkc -M main.js -I myinit.js myboot.js myKernel.js Cat1.st Cat2.st Program
- ENDOFHELP
- exit 1;
- }
- # Check we at least got one argument
- if [ -z $1 ] ; then
- usage
- fi
- # Define our predefined library combinations
- BOOT="boot.js"
- KERNEL="$BOOT Kernel.js"
- COMPILER="$KERNEL Parser.js Compiler.js"
- CANVAS="$COMPILER Canvas.js"
- IDE="$CANVAS JQuery.js IDE.js SUnit.js Examples.js"
- # Predefined initializer
- INITIALIZER="$JTALK/js/init.js"
- # Default values
- ENV=
- INIT=
- MAIN=
- MAINFILE=
- BASE=
- LOAD=
- LOADANDADD=
- CLOSUREOPTS=
- # Ok, bad coding practice but hey, who would use such a prefix?
- PREFIX=no-silly-prefix
- PREFIXUSED=
- DEBUG=false
- NODECOMPILE=nodecompile.js
- # Read options and shift them away
- while getopts "NDEKCJoOAgp:l:L:i:IM:m:h?" o; do
- case "$o" in
- N) ENV=NODE
- BASE=$KERNEL
- INIT=$INITIALIZER;;
- D) ENV=D8
- BASE=$KERNEL
- INIT=$INITIALIZER;;
- E) ENV=ENYO
- BASE=$KERNEL
- INIT=$INITIALIZER;;
- K) BASE=$KERNEL;;
- C) BASE=$COMPILER;;
- J) BASE=$IDE;;
- o) CLOSURE=true
- CLOSUREPARTS=true;;
- O) CLOSURE=true
- CLOSUREFULL=true;;
- A) CLOSURE=true
- CLOSUREOPTS="$CLOSUREOPTS --compilation_level ADVANCED_OPTIMIZATIONS"
- CLOSUREFULL=true;;
- g) DEBUG=true;;
- p) PREFIX=$OPTARG
- PREFIXUSED=$PREFIX;;
- l) LOAD=$OPTARG;;
- L) LOADANDADD=$OPTARG;;
- I) INIT=$INITIALIZER;;
- i) INIT=$OPTARG;;
- M) MAINFILE=$OPTARG;;
- m) MAIN=$OPTARG;;
- h) usage;;
- [?]) usage;;
- esac
- done
- shift $(($OPTIND - 1))
- # Check for Closure compiler and Java
- if [ ! -z $CLOSURE ]; then
- java > /dev/null
- if [ $? -eq 0 ]; then
- if [ ! -f ~/compiler.jar ]; then
- echo "Can not find Closure compiler at ~/compiler.jar"
- exit 1
- fi
- else
- echo "java is not installed and is needed for -O, -A or -o (Closure compiler)."
- exit 1
- fi
- fi
- # Function for looking up listed js files
- function resolvejs {
- if [ -f "$1" ]; then
- RESOLVED="$1"
- else
- if [ -f $JTALK/js/$1 ]; then
- RESOLVED="$JTALK/js/$1"
- else
- echo "Javascript file not found: $1"
- exit 1
- fi
- fi
- }
- # Resolve listed libraries in $BASE separated by spaces
- for FILE in $BASE
- do
- resolvejs $FILE
- TOBASE="$TOBASE $RESOLVED"
- done
- # Resolve listed libraries in $LOAD separated by spaces
- LOAD=${LOAD//,/\ }
- for FILE in $LOAD
- do
- resolvejs $FILE
- TOLOAD="$TOLOAD $RESOLVED"
- done
- # Resolve listed libraries in $LOADANDADD separated by spaces
- LOADANDADD=${LOADANDADD//,/\ }
- for FILE in $LOADANDADD
- do
- resolvejs $FILE
- TOLOAD="$TOLOAD $RESOLVED"
- TOADD="$TOADD $RESOLVED"
- done
- # Define our Compiler loading supplied libraries
- OURCOMPILER="$COMPILER $TOLOAD init.js $JTALK/nodejs/$NODECOMPILE"
- # Resolve OURCOMPILER
- for FILE in $OURCOMPILER
- do
- resolvejs $FILE
- TOOURCOMPILER="$TOOURCOMPILER $RESOLVED"
- done
- # Add supplied libraries
- LIBS="$TOBASE $TOADD"
- # Get a unique tempdir and make it get auto removed on exit
- TMPDIR=`mktemp -d`
- trap "rm -rf $TMPDIR" EXIT
- # --------------------------------------------------
- # Collect libraries and Smalltalk files looking
- # both locally and in $JTALK/js and $JTALK/st
- # --------------------------------------------------
- PROGRAM=
- until [ "$*" = "" ]
- do
- case $1 in
- *.st)
- CATEGORY=`basename $1 .st`
- if [ -f "$1" ]; then
- COMPILE="$COMPILE $1 $CATEGORY"
- COMPILED="$COMPILED $PREFIXUSED$CATEGORY.js"
- else
- if [ -f $JTALK/st/$1 ]; then
- COMPILE="$COMPILE $JTALK/st/$1 $CATEGORY"
- COMPILED="$COMPILED $PREFIXUSED$CATEGORY.js"
- else
- echo "JTalk file not found: $1"
- exit 1
- fi
- fi
- ;;
- *.js)
- resolvejs $1
- LIBS="$LIBS $RESOLVED"
- ;;
- *)
- # Will end up being the last non js/st argument
- PROGRAM=$1
- ;;
- esac
- shift
- done
- # --------------------------------------------------
- # Actual compilation phase of collected .st files
- # --------------------------------------------------
- # Create compiler dynamically
- cat $TOOURCOMPILER > $TMPDIR/compiler.js
-
- # Compile all collected .st files to .js
- echo "Loading libraries $TOOURCOMPILER and compiling ..."
- node $TMPDIR/compiler.js $DEBUG $PREFIX $COMPILE
- # Verify all .js files corresponding to .st files were created, otherwise exit
- IFS=" "
- for FILE in $COMPILED
- do
- if [ ! -f "$FILE" ]; then
- echo "Failed compilation of $FILE, exiting."
- exit 1
- fi
- done
- if [ ! -z $CLOSUREPARTS ]; then
- echo "Compiling all js files using Google closure compiler."
- ALLJSFILES="$COMPILED $LIBS"
- for FILE in $ALLJSFILES
- do
- mv $FILE $FILE.original
- java -jar ~/compiler.jar $CLOSUREOPTS --js $FILE.original --js_output_file $FILE
- rm $FILE.original
- done
- fi
- if [ -z $PROGRAM ]; then
- echo "Done."
- exit 0
- fi
- # --------------------------------------------------
- # Now we start composing resulting javascript file.
- # --------------------------------------------------
- # Add collected libraries to libs.js file.
- if [ ! -z "$LIBS" ]; then
- echo "Adding libraries $LIBS ..."
- cat $LIBS > $TMPDIR/libs.js
- LIBS=$TMPDIR/libs.js
- fi
- echo "Adding Jtalk code$COMPILED ..."
- # Check for init file
- if [ ! -z "$INIT" ]; then
- if [ -f "$INIT" ]; then
- echo "Adding initializer $INIT ..."
- else
- echo "Can not find init file $INIT, exiting."
- exit 1
- fi
- fi
- # Check for adding main
- if [ ! -z "$MAIN" ]; then
- echo "Adding call to $MAIN class >> main ..."
- echo "smalltalk.$MAIN._main()" > $TMPDIR/main.js
- MAIN=$TMPDIR/main.js
- fi
- # Check for adding main file
- if [ ! -z "$MAINFILE" ]; then
- if [ -f "$MAINFILE" ]; then
- echo "Adding main as $MAINFILE ..."
- else
- echo "Can not find main file $MAINFILE, exiting."
- exit 1
- fi
- MAIN=$MAINFILE
- fi
- # And finally concatenate Program.js
- echo "Writing $PROGRAM.js ..."
- cat $LIBS $COMPILED $INIT $MAIN > $PROGRAM.js
- echo "Done."
- if [ ! -z $CLOSUREFULL ]; then
- echo "Compiling $PROGRAM.js file using Google closure compiler."
- mv $PROGRAM.js $PROGRAM.js.original
- java -jar ~/compiler.jar $CLOSUREOPTS --js $PROGRAM.js.original --js_output_file $PROGRAM.js
- rm $PROGRAM.js.original
- echo "Done."
- fi
|