libostd/build.sh

308 lines
6.6 KiB
Bash
Executable file

#!/bin/sh
# fail on error
set -e
# example sources
EXAMPLES="format listdir range range_pipe signal"
EXAMPLES="${EXAMPLES} stream1 stream2 coroutine1 coroutine2"
# assembly sources
ASM_SOURCE_DIR="src/asm"
ASM_SOURCES="jump_all_gas make_all_gas ontop_all_gas"
# c++ sources
CXX_SOURCE_DIR="src"
CXX_SOURCES="context_stack"
# output lib
OSTD_LIB="libostd"
OSTD_DYNLIB=""
# default opts
BUILD_EXAMPLES="true"
BUILD_TESTSUITE="true"
BUILD_LIB="mixed"
BUILD_CFG="debug"
VERBOSE="false"
CLEAN="false"
print_help() {
echo "$1 [options]"
echo "Available options:"
echo " [no-]examples - (do not) build examples (default: build)"
echo " [no-]test-suite - (do not) build test suite (default: build)"
echo " static-lib - static libostd"
echo " shared-lib - shared libostd"
echo " mixed-lib - static + shared libostd (default)"
echo " release - release build (strip, no -g)"
echo " debug - debug build (default, no strip, -g)"
echo " verbose - print entire commands"
echo " clean - remove temporary files and exit"
echo " help - print this"
}
for arg in "$@"; do
case "$arg" in
examples) BUILD_EXAMPLES="true" ;;
no-examples) BUILD_EXAMPLES="false" ;;
test-suite) BUILD_TESTSUITE="true" ;;
no-test-suite) BUILD_TESTSUITE="false" ;;
static-lib) BUILD_LIB="static" ;;
shared-lib) BUILD_LIB="shared" ;;
mixed-lib) BUILD_LIB="mixed" ;;
release) BUILD_CFG="release" ;;
debug) BUILD_CFG="debug" ;;
verbose) VERBOSE="true" ;;
clean) CLEAN="true" ;;
help) print_help "$0"; exit 0 ;;
*) ;;
esac
shift
done
if [ "$BUILD_LIB" = "shared" ]; then
OSTD_LIB="${OSTD_LIB}.so"
OSTD_DYNLIB=""
else
OSTD_LIB="${OSTD_LIB}.a"
OSTD_DYNLIB="${OSTD_LIB}.so"
fi
# compiler
if [ -z "$CXX" ]; then
CXX="c++"
fi
# preprocessor
if [ -z "$CPP" ]; then
CPP="cpp"
fi
# assembler
if [ -z "$AS" ]; then
AS="as"
fi
# ar
if [ -z "$AR" ]; then
AR="ar"
fi
# ar
if [ -z "$STRIP" ]; then
STRIP="strip"
fi
# cross builds
if [ -z "$CROSS" ]; then
CXX="${CROSS}${CXX}"
CPP="${CROSS}${CPP}"
AS="${CROSS}${AS}"
AR="${CROSS}${AR}"
STRIP="${CROSS}${STRIP}"
fi
# c++ standard
OSTD_CXXFLAGS="-std=c++1z"
# includes
OSTD_CXXFLAGS="${OSTD_CXXFLAGS} -I."
# optimization flags
OSTD_CXXFLAGS="${OSTD_CXXFLAGS} -O2"
# warnings
OSTD_CXXFLAGS="${OSTD_CXXFLAGS} -Wall -Wextra -Wshadow -Wold-style-cast"
# -fPIC for shared libs
if [ "$BUILD_LIB" = "shared" ]; then
OSTD_CXXFLAGS="${OSTD_CXXFLAGS} -fPIC"
fi
# -g for debug builds
if [ "$BUILD_CFG" = "debug" ]; then
OSTD_CXXFLAGS="${OSTD_CXXFLAGS} -g"
fi
# custom cxxflags
if [ ! -z "$CXXFLAGS" ]; then
OSTD_CXXFLAGS="${OSTD_CXXFLAGS} ${CXXFLAGS}"
fi
# preprocessor flags
OSTD_CPPFLAGS=""
# custom cppflags
if [ ! -z "$CPPFLAGS" ]; then
OSTD_CPPFLAGS="${OSTD_CPPFLAGS} ${CPPFLAGS}"
fi
# linker flags
OSTD_LDFLAGS=""
# custom linker flags
if [ ! -z "$LDFLAGS" ]; then
OSTD_LDFLAGS="${OSTD_LDFLAGS} ${LDFLAGS}"
fi
# assembler flags
OSTD_ASFLAGS=""
# custom assembler flags
if [ ! -z "$LDFLAGS" ]; then
OSTD_LDFLAGS="${OSTD_LDFLAGS} ${LDFLAGS}"
fi
#
# BUILD LOGIC
#
evalv() {
if [ "$VERBOSE" = "true" ]; then
echo "$@"
fi
eval "$@"
}
echoq() {
if [ "$VERBOSE" = "false" ]; then
echo "$@"
fi
}
# clean everything
clean() {
echo "Cleaning..."
for ex in ${EXAMPLES}; do
evalv "rm -f \"examples/${ex}\" \"examples/${ex}.o\""
done
for as in ${ASM_SOURCES}; do
evalv "rm -f \"${ASM_SOURCE_DIR}/${as}.o\""
evalv "rm -f \"${ASM_SOURCE_DIR}/${as}_dyn.o\""
done
for cs in ${CXX_SOURCES}; do
evalv "rm -f \"${CXX_SOURCE_DIR}/${cs}.o\""
evalv "rm -f \"${CXX_SOURCE_DIR}/${cs}_dyn.o\""
done
evalv "rm -f \"$OSTD_LIB\""
if [ "$BUILD_LIB" = "mixed" ]; then
evalv "rm -f \"$OSTD_DYNLIB\""
fi
evalv "rm -f test_runner.o test_runner"
}
# call_cxx input output
call_cxx() {
echoq "CXX: $1"
evalv "${CXX} ${OSTD_CPPFLAGS} ${OSTD_CXXFLAGS} -c -o \"${2}\" \"${1}\""
if [ "$BUILD_LIB" = "mixed" ] && [ "x$3" = "xlib" ]; then
echoq "CXX (dynamic): $1"
DYNOBJ=$(echo "$2" | sed 's/\.o/_dyn\.o/g')
evalv "${CXX} ${OSTD_CPPFLAGS} ${OSTD_CXXFLAGS} -fPIC -c -o \"${DYNOBJ}\" \"${1}\""
fi
}
# call_as input output
call_as() {
echoq "AS: $1"
evalv "${CPP} -x assembler-with-cpp \"${1}\" | ${AS} -o \"${2}\""
if [ "$BUILD_LIB" = "mixed" ]; then
cp "$2" "$(echo $2 | sed 's/\.o/_dyn\.o/')"
fi
}
# call_ld output file1 file2 ...
call_ld() {
echoq "LD: $1"
evalv "${CXX} ${OSTD_CPPFLAGS} ${OSTD_CXXFLAGS} ${OSTD_LDFLAGS} -o $@"
if [ "$BUILD_CFG" = "release" ]; then
echoq "STRIP: $1"
evalv "$STRIP \"$1\""
fi
}
# call_ldlib output file1 file2 ...
call_ldlib() {
if [ "$BUILD_LIB" = "shared" ]; then
call_ld "$@" "-shared"
else
echoq "AR: $1"
evalv "${AR} rcs $@"
fi
if [ "$BUILD_LIB" = "mixed" ]; then
OUT=$(echo "$1" | sed 's/\.a/\.so/')
shift
OBJS="$@"
DYN_OBJ=$(echo "$OBJS" | sed 's/\.o/_dyn\.o/g')
call_ld "$OUT" "$DYN_OBJ" "-fPIC -shared"
fi
}
# build_example name
build_example() {
call_cxx "examples/${1}.cc" "examples/${1}.o"
call_ld "examples/${1}" "examples/${1}.o" "$OSTD_LIB"
rm -f "examples/${1}.o"
}
# build test runner
build_test_runner() {
call_cxx test_runner.cc test_runner.o
call_ld test_runner test_runner.o "$OSTD_LIB"
rm -f test_runner.o
}
# add_sfx_pfx str sfx pfx
add_sfx_pfx() {
RET=""
for it in $1; do
RET="$RET ${3}${it}${2}"
done
echo $RET
}
# check if cleaning
if [ "$CLEAN" = "true" ]; then
clean
exit 0
fi
# build assembly
echo "Building the library..."
for as in $ASM_SOURCES; do
call_as "${ASM_SOURCE_DIR}/${as}.S" "${ASM_SOURCE_DIR}/${as}.o" &
done
for cs in $CXX_SOURCES; do
call_cxx "${CXX_SOURCE_DIR}/${cs}.cc" "${CXX_SOURCE_DIR}/${cs}.o" lib &
done
wait
ASM_OBJ=$(add_sfx_pfx "$ASM_SOURCES" ".o" "$ASM_SOURCE_DIR/")
CXX_OBJ=$(add_sfx_pfx "$CXX_SOURCES" ".o" "$CXX_SOURCE_DIR/")
CXX_DYNOBJ=$(add_sfx_pfx "$CXX_SOURCES" ".o" "$CXX_SOURCE_DIR/dyn_")
call_ldlib "$OSTD_LIB" "$ASM_OBJ" "$CXX_OBJ"
evalv "rm -f $ASM_OBJ"
evalv "rm -f $CXX_OBJ"
# build test runner
if [ "$BUILD_TESTSUITE" = "true" ]; then
echo "Building test runner..."
build_test_runner &
fi
# build examples
if [ "$BUILD_EXAMPLES" = "true" ]; then
echo "Building examples..."
for ex in $EXAMPLES; do
build_example "$ex" &
done
fi
# wait for remaining tasks
wait
# done
exit 0