#!/usr/bin/env sh # # Argument Parsing # echo "Build Configuration" echo "-------------------" BUILD="build" OUT="out" SRC="src" INCLUDE="src/include" TOOLS="tools/src" SCHEMA="Schema" CFLAGS="-Wall -Wextra -pedantic -std=c89 -O3 -pipe -D_DEFAULT_SOURCE -I${INCLUDE} -I${BUILD}" LIBS="-lm -pthread -lCytoplasm" # Set default args for all platforms SCRIPT_ARGS="--cc=cc --prefix=/usr/local --enable-ld-extra --bin-name=telodendria --version=1.7.0-alpha4 --static $@" echo "Processing options..." echo "Ran with arguments: $SCRIPT_ARGS" # Process all arguments for arg in $SCRIPT_ARGS; do case "$arg" in --cc=*) CC=$(echo "$arg" | cut -d '=' -f 2-) ;; --prefix=*) PREFIX=$(echo "$arg" | cut -d '=' -f 2-) ;; --enable-ld-extra) LD_EXTRA="-flto -fdata-sections -ffunction-sections -s -Wl,-gc-sections" ;; --disable-ld-extra) LD_EXTRA="" ;; --bin-name=*) BIN_NAME=$(echo "$arg" | cut -d '=' -f 2-) ;; --version=*) VERSION=$(echo "$arg" | cut -d '=' -f 2-) ;; --enable-debug) DEBUG="-O0 -g" echo "Notice: --enable-debug implies --disable-ld-extra and --no-static." echo "You must explicitly provide --enable-ld-extra and/or --static after" echo "specifying --enable-debug if you wish to enable these features in debug mode." LD_EXTRA="" STATIC="" ;; --disable-debug) DEBUG="" ;; --static) STATIC="-static -Wl,-static" ;; --no-static) STATIC="" ;; *) echo "Invalid argument: $arg" exit 1 ;; esac done CFLAGS="${CFLAGS} '-DTELODENDRIA_VERSION=\"${VERSION}\"' ${DEBUG}" LDFLAGS="${LIBS} ${LD_EXTRA}" # # Makefile generation # collect() { from="$1" orig_ext="$2" new_ext="$3" prefix="$4" exec="$5" find "${from}" -name "*${orig_ext}" -type f | while IFS= read -r src; do src=$(echo "$src" | sed -e "s|^${from}||g") obj=$(echo "$src" | sed -e "s|${orig_ext}\$|${new_ext}|g") obj="${prefix}${obj}" src="${from}${src}" "${exec}" "${src}" "${obj}" done } prefix() { prefix="$1" shift for thing in $@; do printf "${prefix}${thing} " done } print_src() { printf '%s ' "$1" } print_obj() { printf '%s ' "$2" } compile_obj() { src="$1" obj="$2" pref=$(${CC} -I${INCLUDE} -I${BUILD} -MM -MT "${obj}" "${src}") echo "$pref $(collect ${SCHEMA}/ .json .h ${BUILD}/Schema/ print_obj)" echo "${TAB}@mkdir -p $(dirname ${obj})" echo "${TAB}\$(CC) \$(CFLAGS) -fPIC -c -o \"${obj}\" \"${src}\"" } compile_bin() { src="$1" out="$2" depObjs=$(prefix ${BUILD}/ CanonicalJson.o Telodendria.o) echo "${out}: ${src}" echo "${TAB}@mkdir -p ${OUT}/bin" echo "${TAB}\$(CC) \$(CFLAGS) -o \"${out}\" \"${src}\" $depObjs \$(LDFLAGS) ${STATIC}" } compile_doc() { src="$1" out="$2" if echo "${src}" | grep "Schema" > /dev/null; then return fi echo "${out}: ${src}" echo "${TAB}@mkdir -p ${OUT}/man/man3" echo "${TAB}hdoc -D \"Os=${BIN_NAME}\" -i \"${src}\" -o \"${out}\"" } print_doc() { if echo "${src}" | grep "Schema" > /dev/null; then return fi printf '%s ' "$2" } compile_schema() { src="$1" out="$2" obj="${BUILD}/Schema/${out}.o" echo "${BUILD}/Schema/${out}.h:" echo "${TAB}@mkdir -p ${BUILD}/Schema" echo "${TAB}j2s -s \"${src}\" -h \"${BUILD}/Schema/${out}.h\" -c \"${BUILD}/Schema/${out}.c\"" echo "${BUILD}/Schema/${out}.c:" echo "${TAB}@mkdir -p ${BUILD}/Schema" echo "${TAB}j2s -s \"${src}\" -h \"${BUILD}/Schema/${out}.h\" -c \"${BUILD}/Schema/${out}.c\"" echo "${obj}: ${src} ${BUILD}/Schema/${out}.c" echo "${TAB}@mkdir -p ${BUILD}/Schema" echo "${TAB}\$(CC) \$(CFLAGS) -fPIC -c -o \"${obj}\" \"${BUILD}/Schema/${out}.c\"" } install_out() { src="$1" out="$2" echo "${TAB}install -D \"$src\" \"$out\"" } install_man() { src="${OUT}/man/man3/${BIN_NAME}-$(basename $1 .h).3" out="$2" echo "${TAB}install -D \"$src\" \"$out\"" } uninstall_out() { src="$1" out="$2" echo "${TAB}rm \"$out\"" } echo "Generating Makefile..." OBJS="$(collect ${SRC}/ .c .o ${BUILD}/ print_obj) $(collect ${SCHEMA}/ .json .o ${BUILD}/Schema/ print_obj)" TAB=$(printf '\t') cat << EOF > Makefile .POSIX: # Generated by '$0' on $(date). # This file should generally not be manually edited. CC = ${CC} PREFIX = ${PREFIX} CFLAGS = ${CFLAGS} LDFLAGS = ${LDFLAGS} all: ${BIN_NAME} docs tools docs: $(collect ${INCLUDE}/ .h .3 ${OUT}/man/man3/${BIN_NAME}- print_doc) tools: $(collect ${TOOLS}/ .c '' ${OUT}/bin/ print_obj) format: ${TAB}find . -name '*.c' | while IFS= read -r src; do \\ ${TAB} if indent "\$\$src"; then \\ ${TAB} rm \$\$(basename "\$\$src").BAK; \\ ${TAB} fi \\ ${TAB}done license: ${TAB}find . -name '*.[ch]' | while IFS= read -r src; do \\ ${TAB} srcHeader=\$\$(grep -n -m 1 '^ \*/' "\$\$src" | cut -d ':' -f 1); \\ ${TAB} head -n\$\$srcHeader \$\$src | \\ ${TAB} diff -u -p - "LICENSE.txt" | \\ ${TAB} patch "\$\$src" | grep -v "^Hmm"; \\ ${TAB}done ${BIN_NAME}: ${OUT}/bin/${BIN_NAME} install: ${BIN_NAME} ${TAB}install -D ${OUT}/bin/${BIN_NAME} \$(PREFIX)/bin/${BIN_NAME} uninstall: ${TAB}rm \$(PREFIX)/bin/${BIN_NAME} clean: ${TAB}rm -r "${BUILD}" "${OUT}" ${OUT}/bin/${BIN_NAME}: ${OBJS} ${TAB}@mkdir -p "${OUT}/bin" ${TAB}\$(CC) -o "${OUT}/bin/${BIN_NAME}" ${OBJS} \$(CFLAGS) \$(LDFLAGS) $(collect ${SCHEMA}/ .json '' '' compile_schema) $(collect ${SRC}/ .c .o ${BUILD}/ compile_obj) $(collect ${TOOLS}/ .c '' ${OUT}/bin/ compile_bin) $(collect ${INCLUDE}/ .h .3 ${OUT}/man/man3/${BIN_NAME}- compile_doc) EOF echo "Done. Run 'make' to build ${BIN_NAME}."