From e274a54cf869cf9b1b599cfe0380dfb1a00dd505 Mon Sep 17 00:00:00 2001 From: q66 Date: Thu, 9 Mar 2017 04:17:20 +0100 Subject: [PATCH] add shared libs and other improvements to buildsystem --- build.sh | 178 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 151 insertions(+), 27 deletions(-) diff --git a/build.sh b/build.sh index a74d32b..7cb2ccb 100755 --- a/build.sh +++ b/build.sh @@ -16,7 +16,58 @@ CXX_SOURCE_DIR="src" CXX_SOURCES="context_stack" # output lib -OSTD_LIB="libostd.a" +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 @@ -38,6 +89,20 @@ 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" @@ -50,6 +115,16 @@ 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}" @@ -83,44 +158,85 @@ 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 - rm -f "examples/${ex}" "examples/${ex}.o" + evalv "rm -f \"examples/${ex}\" \"examples/${ex}.o\"" done for as in ${ASM_SOURCES}; do - rm -f "${ASM_SOURCE_DIR}/${as}.o" + evalv "rm -f \"${ASM_SOURCE_DIR}/${as}.o\"" + evalv "rm -f \"${ASM_SOURCE_DIR}/${as}_dyn.o\"" done for cs in ${CXX_SOURCES}; do - rm -f "${CXX_SOURCE_DIR}/${cs}.o" + evalv "rm -f \"${CXX_SOURCE_DIR}/${cs}.o\"" + evalv "rm -f \"${CXX_SOURCE_DIR}/${cs}_dyn.o\"" done - rm -f "$OSTD_LIB" - rm -f test_runner.o test_runner + 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() { - echo "CXX: $1" - eval "${CXX} ${OSTD_CPPFLAGS} ${OSTD_CXXFLAGS} -c -o \"${2}\" \"${1}\"" + 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() { - echo "AS: $1" - eval "${CPP} -x assembler-with-cpp \"${1}\" | ${AS} -o \"${2}\"" + 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() { - echo "LD: $1" - eval "${CXX} ${OSTD_CPPFLAGS} ${OSTD_CXXFLAGS} ${OSTD_LDFLAGS} -o $@" + 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() { - echo "AR: $1" - eval "${AR} rcs $@" + 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 @@ -147,7 +263,7 @@ add_sfx_pfx() { } # check if cleaning -if [ "$1" = "clean" ]; then +if [ "$CLEAN" = "true" ]; then clean exit 0 fi @@ -158,25 +274,33 @@ 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" & + call_cxx "${CXX_SOURCE_DIR}/${cs}.cc" "${CXX_SOURCE_DIR}/${cs}.o" lib & done wait -call_ldlib "$OSTD_LIB" \ - $(add_sfx_pfx "$ASM_SOURCES" ".o" "$ASM_SOURCE_DIR/") \ - $(add_sfx_pfx "$CXX_SOURCES" ".o" "$CXX_SOURCE_DIR/") -rm -f $(add_sfx_pfx "$ASM_SOURCES" ".o" "$ASM_SOURCE_DIR/") -rm -f $(add_sfx_pfx "$CXX_SOURCES" ".o" "$CXX_SOURCE_DIR/") +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 -echo "Building test runner..." -build_test_runner & +if [ "$BUILD_TESTSUITE" = "true" ]; then + echo "Building test runner..." + build_test_runner & +fi # build examples -echo "Building examples..." -for ex in $EXAMPLES; do - build_example "$ex" & -done +if [ "$BUILD_EXAMPLES" = "true" ]; then + echo "Building examples..." + for ex in $EXAMPLES; do + build_example "$ex" & + done +fi + +# wait for remaining tasks wait # done