| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- #!/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"
|