#!/bin/sh # Configure script by blankhex # Global variables source_path="" cc=$CC ar=$AR staticlib=libbh.a dynamiclib=libbh.so exe="" enable_dynamic="no" enable_mt="yes" enable_lfs="no" enable_tests="yes" use_clock_gettime="no" if [ -z "$cc" ]; then cc="gcc"; fi if [ -z "$ld" ]; then ld="gcc"; fi if [ -z "$ar" ]; then ar="ar"; fi # Internal functions assign_option() { set -- "${1#--}" "$2" set -- "${2:-${1%%=*}}" "${1#*=}" eval "$1=\"$2\"" } assign_toggle() { set -- "${1#--}" "$2" "$3" set -- "${2:-${1%%=*}}" "${1#*=}" "$3" "$1" if test "$4" = "$2"; then set -- "$1" "$3"; fi eval "$1=$2" } add_trailing_slash() { set -- "$1" "$(printf "%s" "$1" | tail -c 1)" if [ "$2" = "/" ]; then echo "$1"; else echo "$1/"; fi } # Option parsing for option do case $option in --cc=*) assign_option "$option"; ;; --ar=*) assign_option "$option"; ;; --extra-cflags=*) assign_option "$option" extra_cflags; ;; --extra-ldflags=*) assign_option "$option" extra_ldflags; ;; --extra-ldlibs=*) assign_option "$option" extra_ldlibs; ;; --platform=*) assign_option "$option"; ;; --enable-dynamic|--enable-dynamic=*) assign_toggle "$option" enable_dynamic yes; ;; --enable-mt|--enable-mt=*) assign_toggle "$option" enable_mt yes; ;; --enable-lfs|--enable-lfs=*) assign_toggle "$option" enable_lfs yes; ;; --enable-tests|--enable-tests=*) assign_toggle "$option" enable_tests yes; ;; --use-clock_gettime|--use-clock_gettime=*) assign_toggle "$option" use_clock_gettime yes; ;; --source=*) assign_option "$option" source_path; ;; --help|-h) display_help="yes"; ;; *) echo "configure: WARNING: unrecognized option $option"; ;; esac done # Help message show_help() { cat << EOF Usage: configure [OPTIONS] Options: --help Print this message --source= Path to the source code --cc=CC C compiler --ar=AR Library archiver --extra-cflags= Extra compiler flags --extra-ldflags= Extra linker flags --extra-ldlibs= Extra libraries --platform=[Posix|Win32|Dummy] Specify target platform --enable-dynamic[=yes|no] Make dynamic library --enable-mt[=yes|no] Enable multithreading support --enable-lfs[=yes|no] Enable large file support --enable-tests[=yes|no] Enable unit tests --use-clock_gettime[=yes|no] Use of clock_gettime regardless of the support EOF exit 1 } if [ -n "$display_help" ]; then show_help; fi # Add trailing slash if needed if [ -n "$source_path" ]; then source_path=$(add_trailing_slash "$source_path") fi # Detect OS and platform, because it wasn't specified os="Unknown" if [ -z "$platform" ]; then case $(uname) in Darwin) os="MacOS"; platform="Posix"; ;; Linux) os="Linux"; platform="Posix"; ;; *BSD) os="BSD"; platform="Posix"; ;; CYGWIN*|MINGW*|MSYS*) os="Windows"; platform="Win32"; ;; *) os="Unknown"; platform="Dummy"; ;; esac fi # Validate platforms case $platform in Posix) ;; Win32) ;; Dummy) ;; *) echo "configure: WARNING: unrecognized platform $platform"; platform=Dummy; ;; esac # Make build magic cflags="-fPIC -I${source_path}include -I." ldflags="" ldlibs="-lm" cflags="$cflags $extra_cflags" ldflags="$ldflags $extra_ldflags" ldlibs="$ldlibs $extra_ldlibs" # Make sure that build directories exist mkdir src src/Platform src/Math src/String 2> /dev/null # Build source list sources="${source_path}src/Platform/Spinlock.c" # Platform dependant sources if [ "$platform" = "Posix" ]; then sources="$sources:${source_path}src/Platform/Posix/File.c" mkdir src/Platform/Posix 2> /dev/null elif [ "$platform" = "Win32" ]; then exe=".exe" dynamiclib="bh.dll" sources="$sources:${source_path}src/Platform/Win32/File.c" mkdir src/Platform/Win32 2> /dev/null else sources="$sources:${source_path}src/Platform/Dummy/File.c" mkdir src/Platform/Dummy 2> /dev/null fi if [ "$platform" = "Posix" ] && [ "$enable_mt" = "yes" ]; then sources="$sources:${source_path}src/Platform/Posix/Condition.c" sources="$sources:${source_path}src/Platform/Posix/Mutex.c" sources="$sources:${source_path}src/Platform/Posix/Semaphore.c" sources="$sources:${source_path}src/Platform/Posix/Thread.c" sources="$sources:${source_path}src/Platform/Posix/Tss.c" ldlibs="$ldlibs -pthread" mkdir src/Platform/Posix 2> /dev/null elif [ "$platform" = "Win32" ] && [ "$enable_mt" = "yes" ]; then sources="$sources:${source_path}src/Platform/Win32/Condition.c" sources="$sources:${source_path}src/Platform/Win32/Mutex.c" sources="$sources:${source_path}src/Platform/Win32/Semaphore.c" sources="$sources:${source_path}src/Platform/Win32/Thread.c" sources="$sources:${source_path}src/Platform/Win32/Tss.c" mkdir src/Platform/Win32 2> /dev/null else sources="$sources:${source_path}src/Platform/Dummy/Condition.c" sources="$sources:${source_path}src/Platform/Dummy/Mutex.c" sources="$sources:${source_path}src/Platform/Dummy/Semaphore.c" sources="$sources:${source_path}src/Platform/Dummy/Thread.c" sources="$sources:${source_path}src/Platform/Dummy/Tss.c" mkdir src/Platform/Dummy 2> /dev/null fi # Platform independant sources for file in "${source_path}src"/*.c; do sources="$sources:$file" done for file in "${source_path}src/Math"/*.c; do sources="$sources:$file" done for file in "${source_path}src/String"/*.c; do sources="$sources:$file" done # Tests if [ "$enable_tests" = "yes" ]; then tests="" mkdir test test/src 2> /dev/null for file in "${source_path}test/src"/*.c; do if [ -n "$tests" ]; then tests="$tests:$file" else tests="$file"; fi done fi # Makefile generation { # Generate variables echo "CC=$cc" echo "AR=$ar" echo "CFLAGS=$cflags" echo "LDFLAGS=$ldflags" echo "LDLIBS=$ldlibs" echo "STATICLIB=$staticlib" if [ "$enable_dynamic" = "yes" ]; then echo "DYNAMICLIB=$dynamiclib" fi # Set a list of objects printf "\nOBJS=" ( IFS=":" for source in $sources; do object=${source%%.c}.o object=${object#${source_path}} echo " \\" printf " %s" "$object" done ) printf "\n\n" # Check if dynamic linking is enabled and add rules if [ "$enable_dynamic" = "yes" ]; then printf "all: static dynamic\n\n" printf "dynamic: \$(DYNAMICLIB)\n\n" printf "\$(DYNAMICLIB): \$(OBJS)\n" printf "\t\$(CC) \$(LDFLAGS) -shared \$(OBJS) -o \$(DYNAMICLIB) \$(LDLIBS)\n\n" else printf "all: static\n\n" fi # Add rules for static linking printf "static: \$(STATICLIB)\n\n" printf "\$(STATICLIB): \$(OBJS)\n" printf "\t\$(AR) r \$(STATICLIB) \$(OBJS)\n\n" # Generate rules for tests if [ "$enable_tests" = "yes" ]; then ( IFS=":" for source in $tests; do object=${source%%.c}${exe} object=${object#${source_path}} printf "%s: %s \$(STATICLIB)\n" $object $source printf "\t\$(CC) \$(CFLAGS) -I${source_path}unit/include \$(LDFLAGS) %s %s \$(STATICLIB) -o %s \$(LDLIBS)\n\n" "$source" "${source_path}unit/src/Unit.c" "$object" done ) printf "tests: " ( IFS=":" for source in $tests; do object=${source%%.c}${exe} object=${object#${source_path}} echo " \\" printf " %s" "$object" done ) printf "\n\n" fi # Generate rules for main objects ( IFS=":" for source in $sources; do object=${source%%.c}.o object=${object#${source_path}} printf "$object: $source\n" printf "\t\$(CC) -c \$(CFLAGS) %s -o %s\n\n" "$source" "$object" done ) printf "\n\n" # Generate clean rules printf "clean:\n" printf "\t-rm -f \$(OBJS) \$(STATICLIB)" if [ "$enable_dynamic" = "yes" ]; then printf " \$(DYNAMICLIB)" fi if [ "$enable_tests" = "yes" ]; then ( IFS=":" for source in $tests; do object=${source%%.c}${exe} object=${object#${source_path}} printf " %s" "$object" done ) fi printf "\n\n" } > Makefile # Generate internal config.h { printf "#ifndef BH_SRC_CONFIG_H\n#define BH_SRC_CONFIG_H\n\n" if [ "$use_clock_gettime" ]; then printf "#define BH_USE_CLOCK_GETTIME\n"; fi if [ "$enable_lfs" ]; then printf "#define BH_ENABLE_LFS\n"; fi printf "\n#endif /* BH_SRC_CONFIG_H */\n" } > Config.h echo "OS: $os" echo "Platform: $platform" echo "Source path: $source_path" echo "CC: $cc" echo "AR: $ar" echo "CFLAGS: $cflags" echo "LDFLAGS: $ldflags" echo "LDLIBS: $ldlibs" echo "Enable multithreading: $enable_mt" echo "Enable long file support: $enable_lfs" echo "Enable tests: $enable_tests" echo "Build dynamic library: $enable_dynamic" echo "Use clock_gettime: $use_clock_gettime"