|
|
@@ -0,0 +1,139 @@
|
|
|
+#!/bin/sh
|
|
|
+
|
|
|
+#set -x
|
|
|
+
|
|
|
+ERR() {
|
|
|
+ printf '[ERROR] %s\n' "$1"
|
|
|
+ [ "$2" ] && exit "$2"
|
|
|
+}
|
|
|
+
|
|
|
+INFO() {
|
|
|
+ printf '[INFO] %s\n' "$1"
|
|
|
+ [ "$2" ] && exit "$2"
|
|
|
+}
|
|
|
+
|
|
|
+: "${CC:=gcc}"
|
|
|
+
|
|
|
+SRCDIR='src'
|
|
|
+OBJDIR='.obj'
|
|
|
+BINDIR='bin'
|
|
|
+TARGET=''
|
|
|
+
|
|
|
+clena_op='N'
|
|
|
+debug_op='N'
|
|
|
+tags_op='N'
|
|
|
+deps_op='Y'
|
|
|
+
|
|
|
+while [ "$1" ]
|
|
|
+do
|
|
|
+ case "$1" in
|
|
|
+ --no-debug) debug_op='N';;
|
|
|
+ --debug|-d) debug_op='Y';;
|
|
|
+ --clean|-c) clean_op='Y';;
|
|
|
+ --tags|-t) tags_op='Y';;
|
|
|
+ --no-deps) deps_op='N';;
|
|
|
+
|
|
|
+ --srcdir|-sd) SRCDIR="$2"; shift ;;
|
|
|
+ --objdir|-od) OBJDIR="$2"; shift ;;
|
|
|
+ --bindir|-bd) BINDIR="$2"; shift ;;
|
|
|
+ --cc) CC="$2"; shift ;;
|
|
|
+
|
|
|
+ -*|--*) ERR "Invalid flag: $1" 1;;
|
|
|
+
|
|
|
+ *) TARGET="$1" ;;
|
|
|
+ esac
|
|
|
+ shift
|
|
|
+done
|
|
|
+
|
|
|
+if [ "$clean_op" = 'Y' ]
|
|
|
+then
|
|
|
+ rm -rfv "$OBJDIR" "$BINDIR"
|
|
|
+ exit 0
|
|
|
+fi
|
|
|
+
|
|
|
+if [ "$tags_op" = 'Y' ]
|
|
|
+then
|
|
|
+ INFO 'Genereting etags for all .c and .h files in project'
|
|
|
+ find -name '*.c' -type f -exec etags -a {} \;
|
|
|
+ find -name '*.h' -type f -exec etags -a {} \;
|
|
|
+ exit 0
|
|
|
+fi
|
|
|
+
|
|
|
+if [ -z "$TARGET" ]
|
|
|
+then
|
|
|
+ ERR '*MUST* Provide the target as the last argument.' 1
|
|
|
+fi
|
|
|
+
|
|
|
+INCS="-I include/"
|
|
|
+
|
|
|
+CFLAGS="${CFLAGS} -m64 ${INCS} -pedantic -Wall -Wextra -Wshadow
|
|
|
+-Wcast-align -Wunused -Wconversion -Wmisleading-indentation
|
|
|
+-Wduplicated-cond -Wduplicated-branches -Wlogical-op
|
|
|
+-Wdouble-promotion -Wformat=2 -Wbad-function-cast
|
|
|
+-Wmissing-declarations -Wmissing-parameter-type
|
|
|
+-Wmissing-prototypes -Wnested-externs -Werror"
|
|
|
+
|
|
|
+CC="${CC} -std=c99"
|
|
|
+
|
|
|
+LDFLAGS="${LDFLAGS} -lc -lm"
|
|
|
+
|
|
|
+if [ "$debug_op" = 'Y' ]
|
|
|
+then
|
|
|
+ CFLAGS="${CFLAGS} -Og -g"
|
|
|
+ LDFLAGS="${LDFLAGS} -g"
|
|
|
+else
|
|
|
+ CFLAGS="${CFLAGS} -O3"
|
|
|
+fi
|
|
|
+
|
|
|
+CFLAGS="${CFLAGS} -Og -g"
|
|
|
+
|
|
|
+compile() {
|
|
|
+ obj="${OBJDIR}/$1.o"
|
|
|
+ src="${SRCDIR}/$1.c"
|
|
|
+ [ -d "$(dirname "$obj")" ] || mkdir -pv "$(dirname "$obj")"
|
|
|
+ # [ "$obj" -ot "$src" ] || { INFO "$obj Already up to date" ; return 0; }
|
|
|
+ INFO "[CC] $obj $src"
|
|
|
+ $CC -c $CFLAGS -o "$obj" "$src"
|
|
|
+}
|
|
|
+
|
|
|
+link() {
|
|
|
+ bin="${BINDIR}/$1"
|
|
|
+ objs="${OBJDIR}/$1.o"
|
|
|
+ deps="$2"
|
|
|
+
|
|
|
+ for dep in $deps
|
|
|
+ do
|
|
|
+ objs="$objs $OBJDIR/$dep.o"
|
|
|
+ done
|
|
|
+
|
|
|
+ [ -d "$BINDIR" ] || mkdir -pv "$BINDIR"
|
|
|
+
|
|
|
+ for obj in $objs
|
|
|
+ do
|
|
|
+ # [ "$bin" -ot "$obj" ] && {
|
|
|
+ INFO "[LD] $bin $objs";
|
|
|
+ $CC $LDFLAGS -o "$bin" $objs;
|
|
|
+ return 0;
|
|
|
+ # }
|
|
|
+ done
|
|
|
+ INFO "$bin Already up to date"
|
|
|
+ return 0
|
|
|
+}
|
|
|
+
|
|
|
+deps="$(grep '#include ".*"' "${SRCDIR}"/"$TARGET".c | \
|
|
|
+ sed 's/#include "\(.*\)"/\1/' | \
|
|
|
+ tr -d '.h')"
|
|
|
+
|
|
|
+compile "$TARGET" || exit 1
|
|
|
+
|
|
|
+if [ "$deps_op" = 'Y' ]
|
|
|
+then
|
|
|
+ for dep in $deps
|
|
|
+ do
|
|
|
+ compile "$dep" || exit 1
|
|
|
+ done
|
|
|
+fi
|
|
|
+
|
|
|
+link "$TARGET" "$dep" || exit 1
|
|
|
+
|
|
|
+exec ./"$BINDIR"/"$TARGET"
|