forked from Telodendria/Telodendria
321 lines
7.7 KiB
Bash
Executable file
321 lines
7.7 KiB
Bash
Executable file
#!/usr/bin/env sh
|
|
|
|
#
|
|
# Argument Parsing
|
|
#
|
|
|
|
echo "Build Configuration"
|
|
echo "-------------------"
|
|
|
|
BUILD="build"
|
|
OUT="out"
|
|
SRC="src"
|
|
INCLUDE="src/include"
|
|
TOOLS="tools/src"
|
|
SCHEMA="Schema"
|
|
CYTOPLASM="Cytoplasm"
|
|
|
|
CFLAGS="-O1 -D_DEFAULT_SOURCE -I${INCLUDE} -I${SRC} -I${BUILD}"
|
|
LIBS="-lm -pthread -lCytoplasm"
|
|
|
|
|
|
# Set default args for all platforms
|
|
SCRIPT_ARGS="--prefix=/usr/local --bin-name=telodendria --version=1.7.0-alpha4"
|
|
|
|
if [ -f "${CYTOPLASM}/configure" ]; then
|
|
SCRIPT_ARGS="${SCRIPT_ARGS} --cytoplasm=${CYTOPLASM}"
|
|
else
|
|
SCRIPT_ARGS="${SCRIPT_ARGS} --cytoplasm=" # No cytoplasm path.
|
|
fi
|
|
|
|
# Set compiler depending on the platform.
|
|
case "$(uname)" in
|
|
Linux|NetBSD)
|
|
# These systems typically use GCC.
|
|
SCRIPT_ARGS="${SCRIPT_ARGS} --cc=gcc"
|
|
;;
|
|
OpenBSD|FreeBSD|Darwin)
|
|
# These systems typically use Clang.
|
|
SCRIPT_ARGS="${SCRIPT_ARGS} --cc=clang"
|
|
;;
|
|
*)
|
|
# Use default compiler which is required to be present on
|
|
# all POSIX-compliant systems.
|
|
SCRIPT_ARGS="${SCRIPT_ARGS} --cc=c99"
|
|
;;
|
|
esac
|
|
|
|
# Append any additional args specified by user
|
|
SCRIPT_ARGS="${SCRIPT_ARGS} $@"
|
|
|
|
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-)
|
|
case "${CC}" in
|
|
gcc*|clang*)
|
|
# "Fancy" compilers that support a plethora of additional flags we
|
|
# want to enable if present.
|
|
CFLAGS="-Wall -Wextra -Werror -pedantic -std=c99 -O3 ${CFLAGS}"
|
|
LDFLAGS="${LDFLAGS} -flto -fdata-sections -ffunction-sections -s -Wl,-gc-sections"
|
|
;;
|
|
esac
|
|
;;
|
|
--prefix=*)
|
|
PREFIX=$(echo "$arg" | cut -d '=' -f 2-)
|
|
;;
|
|
--bin-name=*)
|
|
BIN_NAME=$(echo "$arg" | cut -d '=' -f 2-)
|
|
;;
|
|
--version=*)
|
|
VERSION=$(echo "$arg" | cut -d '=' -f 2-)
|
|
;;
|
|
--enable-debug)
|
|
DEBUG="-O0 -g"
|
|
;;
|
|
--disable-debug)
|
|
DEBUG=""
|
|
;;
|
|
--cytoplasm=*)
|
|
CYTOPLASM=$(echo "$arg" | cut -d '=' -f 2-)
|
|
if [ -n "${CYTOPLASM}" ]; then
|
|
if [ ! -f "${CYTOPLASM}/configure" ]; then
|
|
echo "Path for Cytoplasm does not appear to actually contain Cytoplasm source:"
|
|
echo "${CYTOPLASM}"
|
|
exit 1
|
|
fi
|
|
|
|
CFLAGS="${CFLAGS} -I${CYTOPLASM}/include"
|
|
LDFLAGS="-L${CYTOPLASM}/out/lib ${LDFLAGS}"
|
|
fi
|
|
;;
|
|
*)
|
|
echo "Invalid argument: $arg"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
CFLAGS="${CFLAGS} '-DTELODENDRIA_VERSION=\"${VERSION}\"' ${DEBUG}"
|
|
LDFLAGS="${LDFLAGS} ${LIBS}"
|
|
|
|
#
|
|
# 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
|
|
}
|
|
|
|
cytoplasm_tool() {
|
|
tool="$1"
|
|
|
|
if [ -n "${CYTOPLASM}" ]; then
|
|
echo "LD_LIBRARY_PATH=${CYTOPLASM}/out/lib ${CYTOPLASM}/out/bin/$tool"
|
|
else
|
|
echo "$tool"
|
|
fi
|
|
}
|
|
|
|
print_src() {
|
|
printf '%s ' "$1"
|
|
}
|
|
|
|
print_obj() {
|
|
printf '%s ' "$2"
|
|
}
|
|
|
|
get_deps() {
|
|
src="$1"
|
|
|
|
${CC} -I${SRC} -I${INCLUDE} -I${BUILD} $(if [ -n "${CYTOPLASM}" ]; then echo "-I${CYTOPLASM}/include"; fi) -E "$src" \
|
|
| grep '^#' \
|
|
| awk '{print $3}' \
|
|
| cut -d '"' -f 2 \
|
|
| sort \
|
|
| uniq \
|
|
| grep -v '^[/<]' \
|
|
| grep -e "^${SRC}/" -e "^${BUILD}/" \
|
|
| while IFS= read -r dep; do
|
|
printf "%s " "$dep"
|
|
done
|
|
}
|
|
|
|
compile_obj() {
|
|
src="$1"
|
|
obj="$2"
|
|
|
|
pref="${obj}: $(get_deps ${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)"
|
|
}
|
|
|
|
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}$(cytoplasm_tool 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}$(cytoplasm_tool 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}$(cytoplasm_tool 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"
|
|
dir=$(dirname "$out")
|
|
|
|
echo "${TAB}mkdir -p \"$dir\""
|
|
echo "${TAB}cp \"$src\" \"$out\""
|
|
}
|
|
|
|
install_man() {
|
|
src="${OUT}/man/man3/${BIN_NAME}-$(basename $1 .h).3"
|
|
out="$2"
|
|
dir=$(dirname "$out")
|
|
|
|
echo "${TAB}mkdir -p \"$dir\""
|
|
echo "${TAB}cp \"$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}mkdir -p \$(PREFIX)/bin
|
|
${TAB}cp ${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)
|
|
|
|
$(
|
|
if [ -n "${CYTOPLASM}" ]; then
|
|
echo "cytoplasm:"
|
|
echo "${TAB}cd ${CYTOPLASM} && ./configure && \$(MAKE)"
|
|
fi
|
|
)
|
|
|
|
EOF
|
|
|
|
echo "Done. Run 'make' to build ${BIN_NAME}."
|