#!/usr/bin/env bash
# flx - felix script harness
CYGWIN=0
WIN32=0
HAVE_GXX=1
HAVE_MSVC=0
CCOBJ_DLLIB="g++ -fPIC -c -Wall -Wno-invalid-offsetof "
CCLINK_DLLIB="g++ -shared "
CCOBJ_STATIC_LIB="g++ -c -Wall -Wno-invalid-offsetof "
CCLINK_STATIC="g++ "
VERSION="1.1.1"
EXT_LIB=".a"
EXT_OBJ=".o"
EXT_EXE=""
EXT_SHLIB=".so"
SPEC_OBJ_FILENAME="-o "
SPEC_EXE_FILENAME="-o "
OPTIMISE="-O3 -fomit-frame-pointer --inline -DNDEBUG "
DEBUG_FLAGS="-g "
DYNLINK_STRING='-Lrtl -lflx_dynamic'
# check for test mode: this argument must come first
TESTMODE=0
RECOMPILE=0
DEBUG=0
INLINE=10
ECHO=0
TIME=0
STATIC=0
RUNIT=1
CCFLAGS=""
FELIX=1
grab=1
INCLUDE_DIRS=""
while (( "$grab" == "1" ));
do
case x$1 in
x--test)
TESTMODE=1
shift
;;
x--force)
RECOMPILE=1
shift
;;
x--debug)
DEBUG=1
ECHO=1
shift
;;
x--time)
TIME=1
shift
;;
x--echo)
ECHO=1
shift
;;
x--static)
STATIC=1
shift
;;
x--inline=*)
INLINE=${1:9}
shift
;;
x--inline)
INLINE=50
shift
;;
x--noinline)
INLINE=0
shift
;;
x--opt=1)
INLINE=10
CCFLAGS="-O1 $CCFLAGS"
shift
;;
x--opt=2)
INLINE=20
CCFLAGS="$CCFLAGS$OPTIMISE"
shift
;;
x--opt=3)
INLINE=50
CCFLAGS="$CCFLAGS$OPTIMISE"
shift
;;
x--optimise)
INLINE=10
CCFLAGS="$CCFLAGS$OPTIMISE"
shift
;;
x--optimize)
INLINE=10
CCFLAGS="$CCFLAGS$OPTIMISE"
shift
;;
x--version)
echo $VERSION
exit 0
;;
x--help)
man flx
exit 0
;;
x-c)
RUNIT=0
shift
;;
x-I*)
INCLUDE_DIRS="$INCLUDE_DIRS $1"
shift
;;
x--nofelix)
FELIX=0
shift
;;
x*)
grab=0
;;
esac
done
if [ "$TESTMODE" = "1" -a "$ECHO" = "1" ]
then
echo "TESTMODE: running felix from current directory"
fi
# make a list of any *.cpp files (or other g++ options ..)
cpps=""
cppos=""
grab=1
pkgs=""
while (( "$grab" == "1" ));
do
case "$1" in
*.cpp)
cpps="$cpps $1"
cppos="$cppos `dirname $1`/`basename $1 .cpp`$EXT_OBJ"
shift
;;
*.cxx)
cpps="$cpps $1"
cppos="$cppos `dirname $1`/`basename $1 .cxx`$EXT_OBJ"
shift
;;
*.c)
cpps="$cpps $1"
cppos="$cppos `dirname $1`/`basename $1 .c`$EXT_OBJ"
shift
;;
*.o)
cppos="$cppos `dirname $1`/`basename $1 .o`$EXT_OBJ"
shift
;;
*.obj)
cppos="$cppos `dirname $1`/`basename $1 .obj`$EXT_OBJ"
shift
;;
*.a)
cppos="$cppos $1"
shift
;;
*.lib)
cppos="$cppos $1"
shift
;;
--pkg=*)
pkgs=" `echo \"$1\" | sed 's/--pkg=\(.*\)/\\1/'`"
shift
;;
# unknown flag .. pass to both compile and link
-*)
cpps="$cpps $1"
cppos="$cppos $1"
shift
;;
*)
grab=0
;;
esac
done
if [ "x$pkgs" = "x" ]
then
PKGS=""
else
PKGS=`pkg-config --cflags --libs $pkgs`
fi
if [ "x$1" = "x" ]
then
echo "usage: flx filename"
exit 1
fi
# Strip trailing .flx or .so
# users should type 'flx file' without extension,
# but #! interpreter always passes extension ..
case "$1" in
*.flx)
arg="`echo $1 | sed 's/\.flx$//'`"
is_flx=1
;;
*.so)
arg="`echo $1 | sed 's/\.so$//'`"
is_so=1
;;
*)
arg="$1"
esac
# Find absolute pathname
base=$arg
if [ "x$base" = "x" ]
then
echo "No such felix program: $arg" >&2
exit 1
fi
shift
# grab arguments
grab=1
args=""
while (( "$grab" == "1" ));
do
case "x$1" in
x)
grab=0
;;
x*)
args="$args $1"
shift
;;
esac
done
if [ "$TESTMODE" = "1" ]
then
INCLUDE_DIR="./rtl"
FLXLIB="./lib"
if [ "$CYGWIN" = "1" -o "$WIN32" = "1" ]
then
# bash is a heap of crap! The escaped quotes here are
# required in case the PATH has a filename with spaces
# However this actually fails on Linux!
FLXG="env \"PATH=./bin:\$PATH\" ./bin/flxg"
FLXRUN="env \"PATH=./bin:\$PATH\" ./bin/flx_run"
else
FLXG="env PATH=./bin:\$PATH ./bin/flxg"
FLXRUN="env LD_LIBRARY_PATH=./rtl:\$LD_LIBRARY_PATH ./bin/flx_run"
fi
FLXRTL="./rtl"
FLXBIN="./bin"
FLXAR="./rtl"
if [ "$CYGWIN" = "1" -o "$WIN32" = "1" ]
then
FLXSHLIB="./bin"
else
FLXSHLIB="./rtl"
fi
else
# Locate the felix installation
prefix=""
for dir in `echo "$PATH" | sed 's/:/ /g'`
do
dir=$dir
if [ -x "$dir/flxg" ]
then
prefix="$dir/flxg"
break
fi
done
prefix="`echo $prefix | sed 's/\/bin\/flxg$//'`"
INCLUDE_DIR="$prefix/lib/felix/rtl"
FLXG="$prefix/bin/flxg"
FLXRUN="$prefix/bin/flx_run"
FLXLIB="$prefix/lib/felix/lib"
FLXRTL="$prefix/lib/felix/lib"
FLXBIN="$prefix/bin"
FLXAR="$prefix/lib"
if [ "$CYGWIN" = "1" -o "$WIN32" = "1" ]
then
FLXSHLIB="$prefix/bin"
else
FLXSHLIB="$prefix/lib"
fi
fi
if [ "$DEBUG" = "1" ]; then FLXRUN="$FLXRUN --debug"; fi
STATIC_ENV=""
if [ "$DEBUG" = "1" ]; then STATIC_ENV="env FLX_DEBUG=1 "; fi
# No need to compile, just run it
if [ $STATIC = 0 ]
then
if [ $RECOMPILE = 0 -a -r "$base$EXT_SHLIB" -a "(" ! -r "$base.flx" -o "$base$EXT_SHLIB" -nt "$base.flx" ")" ]
then
if [ $RUNIT = 1 ]
then
cmd="$FLXRUN $base$EXT_SHLIB $args"
if [ $ECHO = 1 ]; then echo $cmd; fi
eval $cmd
fi
exit $?
fi
else
if [ $RECOMPILE = 0 -a -r "$base$EXT_EXE" -a "(" ! -r "$base.flx" -o "$base$EXT_EXE" -nt "$base.flx" ")" ]
then
if [ $RUNIT = 1 ]
then
cmd="$STATIC_ENV $base $args"
if [ $ECHO = 1 ]; then echo $cmd; fi
eval $cmd
fi
exit $?
fi
fi
# Need Felix and c++ compile, then run it
if [ $DEBUG = 1 ]
then
VERBOSE="-v"
CCFLAGS="$CCFLAGS$DEBUG_FLAGS"
else
VERBOSE="-q"
fi
FLXFLAGS="--inline=$INLINE"
if [ $STATIC = 0 ]
then
if [ $FELIX = 1 ]
then
FCMD="$FLXG $VERBOSE $FLXFLAGS -I$FLXLIB $INCLUDE_DIRS $base"
if [ $ECHO = 1 ]; then echo "$FCMD"; fi
eval $FCMD
fi
if [ $? = 0 ]
then
CCMD="$CCOBJ_DLLIB $CCFLAGS -I$INCLUDE_DIR $INCLUDE_DIRS $PKGS $cpps $base.cpp $SPEC_OBJ_FILENAME$base$EXT_OBJ"
LCMD="$CCLINK_DLLIB $CCFLAGS $PKGS $cppos $base$EXT_OBJ $SPEC_EXE_FILENAME$base$EXT_SHLIB $DYNLINK_STRING"
if [ $ECHO = 1 ]; then echo "$CCMD"; fi
if `echo $CCMD`
then
if [ $ECHO = 1 ]; then echo "$LCMD"; fi
if `echo $LCMD`
then
if [ $RUNIT = 1 ]
then
if [ $TIME = 1 ]
then
cmd="time $FLXRUN $base$EXT_SHLIB $args"
else
cmd="$FLXRUN $base$EXT_SHLIB $args"
fi
if [ $ECHO = 1 ]; then echo $cmd; fi
eval $cmd
fi
exit $?
else
exit $?
fi
else
exit $?
fi
fi
else
if [ $FELIX = 1 ]
then
FCMD="$FLXG $VERBOSE $FLXFLAGS -I$FLXLIB $INCLUDE_DIRS $base"
if [ $ECHO = 1 ]; then echo "$FCMD"; fi
eval $FCMD
fi
if [ $? = 0 ]
then
CCMD="$CCOBJ_STATIC_LIB $CCFLAGS -DFLX_STATIC_LINK -I$INCLUDE_DIR $INCLUDE_DIRS $PKGS $cpps $base.cpp $SPEC_OBJ_FILENAME$base$EXT_OBJ"
LCMD="$CCLINK_STATIC $FLXRTL/flx_run_static$EXT_OBJ $PKGS $cppos $base$EXT_OBJ $FLXAR/libflx_static$EXT_LIB $SPEC_EXE_FILENAME$base$EXT_EXE"
if [ $ECHO = 1 ]; then echo "$CCMD"; fi
if `echo $CCMD`
then
if [ $ECHO = 1 ]; then echo "$LCMD"; fi
if `echo $LCMD`
then
# rm -f "$base.cpp"
if [ $RUNIT = 1 ]
then
if [ $TIME = 1 ]
then
cmd="time $STATIC_ENV $base $args"
else
cmd="$STATIC_ENV $base $args"
fi
if [ $ECHO = 1 ]; then echo $cmd; fi
eval $cmd
fi
exit $?
else
exit $?
fi
else
exit $?
fi
fi
fi