diff options
| author | Mikhail Romanko <me@blankhex.com> | 2025-09-02 10:24:05 +0300 |
|---|---|---|
| committer | Mikhail Romanko <me@blankhex.com> | 2025-09-02 10:24:05 +0300 |
| commit | 5dc36b222f498726481f3896ff82d38c7826b9ba (patch) | |
| tree | 2eb0f5e0365b84797aa1aa4f69027168444753ce | |
| parent | a4c5ce98ce123469dee4b7d46ddf7de652f04564 (diff) | |
| download | bhlib-5dc36b222f498726481f3896ff82d38c7826b9ba.tar.gz | |
Refactor configure, add install targets
| -rwxr-xr-x | configure | 495 |
1 files changed, 275 insertions, 220 deletions
@@ -1,306 +1,361 @@ #!/bin/sh # Configure script by blankhex -# Global variables -source_path=$(dirname "$0") -cc=$CC -ar=$AR -staticlib=libbh.a -dynamiclib=libbh.so -exe="" -enable_dynamic="no" +# Default values +cc=${CC:-gcc} +ld=${LD:-gcc} +ar=${AR:-ar} +source_path="$(dirname "$0")" +prefix_path=${PREFIX:-/usr/local} +enable_shared="no" enable_mt="yes" enable_lfs="no" enable_tests="yes" +enable_pic="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 +arflags=${ARFLAGS:-cr} +cflags=${CFLAGS} +ldflags=${LDFLAGS} +ldlibs=${LDLIBS} +ldshared=${LDSHARED:--shared} +platform="" +display_help="no" + +# Parse arguments 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"; ;; + --cc=*) cc="${option#--cc=}" ;; + --ar=*) ar="${option#--ar=}" ;; + --ld=*) ld="${option#--ld=}" ;; + --arflags=*) arflags="${option#--arflags=}" ;; + --cflags=*) cflags="${option#--cflags=}" ;; + --ldflags=*) ldflags="${option#--ldflags=}" ;; + --ldlibs=*) ldlibs="${option#--ldlibs=}" ;; + --ldshared=*) ldshared="${option#--ldshared=}" ;; + --platform=*) platform="${option#--platform=}" ;; + --prefix=*) prefix_path="${option#--prefix=}" ;; + --enable-shared|--enable-shared=yes) enable_shared="yes" ;; + --enable-shared=no) enable_shared="no" ;; + --enable-mt|--enable-mt=yes) enable_mt="yes" ;; + --enable-mt=no) enable_mt="no" ;; + --enable-lfs|--enable-lfs=yes) enable_lfs="yes" ;; + --enable-lfs=no) enable_lfs="no" ;; + --enable-tests|--enable-tests=yes) enable_tests="yes" ;; + --enable-tests=no) enable_tests="no" ;; + --use-clock_gettime|--use-clock_gettime=yes) use_clock_gettime="yes" ;; + --use-clock_gettime=no) use_clock_gettime="no" ;; + --source=*) source_path="${option#--source=}" ;; + --enable-pic|--with-pic=yes) enable_pic="yes" ;; + --enable-pic=no) enable_pic="no" ;; + --help|-h) display_help="yes" ;; + *) echo "configure: WARNING unrecognized option $option" ;; esac done -# Help message -show_help() { -cat << EOF +if [ "$display_help" = "yes" ]; then + cat << EOF Usage: configure [OPTIONS] Options: --help Print this message --source= Path to the source code --cc=CC C compiler + --ld=LD Linker --ar=AR Library archiver - --extra-cflags= Extra compiler flags - --extra-ldflags= Extra linker flags - --extra-ldlibs= Extra libraries + --arflags= Archiver flags + --cflags= Compiler flags + --ldflags= Linker flags + --ldlibs= Extra libraries + --ldshared= Linker flags for shared libraries --platform=[Posix|Win32|Dummy] Specify target platform - --enable-dynamic[=yes|no] Make dynamic library + --prefix= Install prefix + --enable-shared[=yes|no] Make shared library + --enable-pic[=yes|no] Enable position independent code (PIC) --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") + exit 1 fi -# Detect OS and platform, because it wasn't specified +# Ensure that source_path ends on / +case "$source_path" in + */) ;; + *) source_path="$source_path/" ;; +esac + +# Detect and validate OS 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 +case "${platform:-$(uname)}" in + Posix|Win32|Dummy) ;; + Darwin*) os="MacOS"; platform="Posix" ;; + Linux*) os="Linux"; platform="Posix" ;; + *BSD) os="BSD"; platform="Posix" ;; + CYGWIN*|MINGW*|MSYS*) os="Windows"; platform="Win32" ;; + *) platform="Dummy" ;; +esac -# Validate platforms -case $platform in - Posix) ;; - Win32) ;; - Dummy) ;; - *) echo "configure: WARNING: unrecognized platform $platform"; platform=Dummy; ;; +case "$platform" in + Posix|Win32|Dummy) ;; + *) echo "configure: WARNING: unsupported platform '$platform'"; platform="Dummy" ;; esac -# Make build magic -cflags="-fPIC -I${source_path}include -I." -ldflags="" -ldlibs="-lm" - -# 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 +# Platform-specific settings +exe_suffix="" +dll_prefix="libbh" +dll_suffix=".so" +if [ "$platform" = "Win32" ]; then + exe_suffix=".exe" + dll_prefix="bh" + dll_suffix=".dll" +fi + +# Build flags +cflags="-I${source_path}include -I. $cflags" +ldlibs="-lm $ldlibs" + +if [ "$enable_pic" = "yes" ]; then + cflags="$cflags -fPIC" 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" +if [ "$enable_pic" = "no" ] && [ "$enable_shared" = "yes" ]; then + echo "configure: WARNING: requested shared library while PIC is disabled" + echo "configure: WARNING: expect build failure" +fi + +if [ "$enable_mt" = "yes" ] && [ "$platform" = "Posix" ]; then 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 +# Create directories +mkdir src src/Platform src/Math src/String 2>/dev/null +mkdir src/Platform/Posix src/Platform/Win32 src/Platform/Dummy 2>/dev/null +if [ "$enable_tests" = "yes" ]; then + mkdir test test/src unit unit/src 2>/dev/null +fi -for file in "${source_path}src/Math"/*.c; do - sources="$sources:$file" -done +library="" +add_source() { library="${library}${library:+:}$1"; } -for file in "${source_path}src/String"/*.c; do - sources="$sources:$file" +# Main source +for file in "${source_path}"src/*.c; do + add_source "$file" +done +for file in "${source_path}"src/Math/*.c; do + add_source "$file" +done +for file in "${source_path}"src/String/*.c; do + add_source "$file" done +# Platform specific code +add_source "${source_path}src/Platform/Spinlock.c" + +case "$platform" in + Posix) add_source "${source_path}src/Platform/Posix/File.c" ;; + Win32) add_source "${source_path}src/Platform/Win32/File.c" ;; + *) add_source "${source_path}src/Platform/Dummy/File.c" ;; +esac + +if [ "$enable_mt" = "yes" ]; then + case "$platform" in + Posix) + for item in Condition Mutex Semaphore Thread Tss; do + add_source "${source_path}src/Platform/Posix/${item}.c" + done + ;; + Win32) + for item in Condition Mutex Semaphore Thread Tss; do + add_source "${source_path}src/Platform/Win32/${item}.c" + done + ;; + *) + for item in Condition Mutex Semaphore Thread Tss; do + add_source "${source_path}src/Platform/Dummy/${item}.c" + done + ;; + esac +else + for item in Condition Mutex Semaphore Thread Tss; do + add_source "${source_path}src/Platform/Dummy/${item}.c" + done +fi + # Tests +tests="" +unit="" +add_test() { tests="${tests}${tests:+:}$1"; } + 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 + unit="${source_path}unit/src/Unit.c" + for file in "${source_path}"test/src/*.c; do + add_test "$file" done fi -# Add extra flags -cflags="$cflags $extra_cflags" -ldflags="$ldflags $extra_ldflags" -ldlibs="$ldlibs $extra_ldlibs" - -# Makefile generation +# Generate Makefile { - # Generate variables echo "CC=$cc" + echo "LD=$ld" echo "AR=$ar" + echo "ARFLAGS=$arflags" 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" + echo "LDSHARED=$ldshared" + echo "PREFIX=$prefix_path" + echo "STATICLIB=libbh.a" + + # Shared library + if [ "$enable_shared" = "yes" ]; then + printf "SHAREDLIB=${dll_prefix}${dll_suffix}\n" + printf "\nall: static shared\n" + printf "\nshared: \${SHAREDLIB}\n" + + printf "\n\$(SHAREDLIB): " + ( IFS=":"; for item in $library; do item="${item#$source_path}"; printf "%s " "${item%.c}.o"; done; ) + printf "\n\t\$(LD) \$(LDFLAGS) \$(LDSHARED) -o \$@ " + ( IFS=":"; for item in $library; do item="${item#$source_path}"; printf "%s " "${item%.c}.o"; done; ) + printf "\$(LDLIBS)\n" else - printf "all: static\n\n" + printf "\nall: static\n" fi - # Add rules for static linking - printf "static: \$(STATICLIB)\n\n" - printf "\$(STATICLIB): \$(OBJS)\n" - printf "\t\$(AR) r \$(STATICLIB) \$(OBJS)\n\n" + # Static library + printf "\nstatic: \${STATICLIB}\n" + printf "\n\$(STATICLIB): " + ( IFS=":"; for item in $library; do item="${item#$source_path}"; printf "%s " "${item%.c}.o"; done; ) + printf "\n\t\$(AR) \$(ARFLAGS) \$@ " + ( IFS=":"; for item in $library; do item="${item#$source_path}"; printf "%s " "${item%.c}.o"; done; ) + printf "\n" - # Generate rules for tests - if [ "$enable_tests" = "yes" ]; then + # Compile sources ( - 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" + IFS=":"; + for item in $library; do + object="${item#$source_path}" + printf "\n%s: %s\n" "${object%.c}.o" "$item" + printf "\t\$(CC) \$(CFLAGS) -c -o \$@ %s\n" "$item" 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" + + # Tests + if [ "$enable_tests" = "yes" ]; then + ( + unit_obj="${unit#$source_path}" + printf "\n%s: %s\n" "${unit_obj%.c}.o" "$unit" + printf "\t\$(CC) \$(CFLAGS) -I${source_path}unit/include -c -o \$@ %s\n" "$unit" + + IFS=":"; + for item in $tests; do + object="${item#$source_path}" + printf "\n%s: %s %s \$(STATICLIB)\n" "${object%.c}${exe_suffix}" "${object%.c}.o" "${unit_obj%.c}.o" + printf "\t\$(LD) \$(LDFLAGS) -o \$@ %s %s \$(STATICLIB) \$(LDLIBS)\n" "${object%.c}.o" "${unit_obj%.c}.o" + + printf "\n%s: %s\n" "${object%.c}.o" "$item" + printf "\t\$(CC) \$(CFLAGS) -I${source_path}unit/include -c -o \$@ %s\n" "$item" + done + + printf "\ntest: " + for item in $tests; do + object="${item#$source_path}" + printf "%s " "${object%.c}${exe_suffix}" + done + echo + for item in $tests; do + object="${item#$source_path}" + printf "\t./%s\n" "${object%.c}${exe_suffix}" + done + echo + ) fi - # Generate rules for main objects + # Clean + printf "\nclean:\n" + printf "\t-rm -f %s\n" "\$(STATICLIB)" + if [ "$enable_shared" = "yes" ]; then + printf "\t-rm -f %s\n" "\$(SHAREDLIB)" + fi ( 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" + for item in $library; do + item="${item#$source_path}"; + printf "\t-rm -f %s\n" "${item%.c}.o" done + + if [ "$enable_tests" = "yes" ]; then + unit_obj="${unit#$source_path}" + printf "\t-rm -f %s\n" "${unit_obj%.c}.o" + for item in $tests; do + item="${item#$source_path}" + printf "\t-rm -f %s\n" "${item%.c}.o" + printf "\t-rm -f %s\n" "${item%.c}${exe_suffix}" + done + fi ) - printf "\n\n" - # Generate clean rules - printf "clean:\n" - printf "\t-rm -f \$(OBJS) \$(STATICLIB)" - if [ "$enable_dynamic" = "yes" ]; then - printf " \$(DYNAMICLIB)" + # Install + printf "\ninstall: \$(STATICLIB) " + if [ "$enable_shared" = "yes" ]; then + printf "\$(SHAREDLIB)" + fi + printf "\n\tinstall -d \$(DESTDIR)\$(PREFIX)/lib/\n" + printf "\tinstall -d \$(DESTDIR)\$(PREFIX)/include/BH/Math\n" + printf "\tinstall -m 644 \$(STATICLIB) \$(DESTDIR)\$(PREFIX)/lib\n" + if [ "$enable_shared" = "yes" ]; then + printf "\tinstall -m 644 \$(SHAREDLIB) \$(DESTDIR)\$(PREFIX)/lib\n" fi + for file in "${source_path}"include/BH/*.h; do + printf "\tinstall -m 644 \"%s\" \$(DESTDIR)\$(PREFIX)/include/BH\n" "$file" + done + for file in "${source_path}"include/BH/Math/*.h; do + printf "\tinstall -m 644 \"%s\" \$(DESTDIR)\$(PREFIX)/include/BH/Math\n" "$file" + done - if [ "$enable_tests" = "yes" ]; then - ( - IFS=":" - for source in $tests; do - object=${source%%.c}${exe} - object=${object#${source_path}} - printf " %s" "$object" - done - ) + # Uninstall + printf "\nuninstall:\n" + printf "\trm -rf \$(DESTDIR)\$(PREFIX)/include/BH\n" + printf "\trm -rf \$(DESTDIR)\$(PREFIX)/lib/\$(STATICLIB)\n" + if [ "$enabled_shared" = "yes" ]; then + printf "\trm -rf \$(DESTDIR)\$(PREFIX)/lib/\$(SHAREDLIB)\n" fi - printf "\n\n" + } > Makefile -# Generate internal config.h +# Generate Config.h { - printf "#ifndef BH_SRC_CONFIG_H\n#define BH_SRC_CONFIG_H\n\n" - if [ "$use_clock_gettime" = "yes" ]; then printf "#define BH_USE_CLOCK_GETTIME\n"; fi - if [ "$enable_lfs" = "yes" ]; then printf "#define BH_ENABLE_LFS\n"; fi + printf "#ifndef BH_SRC_CONFIG_H\n" + printf "#define BH_SRC_CONFIG_H\n\n" + if [ "$use_clock_gettime" = "yes" ]; then + printf "#define BH_USE_CLOCK_GETTIME\n"; + fi + if [ "$enable_lfs" = "yes" ]; then + printf "#define BH_ENABLE_LFS\n"; + fi printf "\n#endif /* BH_SRC_CONFIG_H */\n" } > Config.h +echo " --- General information --- " echo "OS: $os" echo "Platform: $platform" echo "Source path: $source_path" +echo +echo " --- Makefile variables --- " echo "CC: $cc" +echo "LD: $ld" echo "AR: $ar" +echo "ARFLAGS: $arflags" echo "CFLAGS: $cflags" echo "LDFLAGS: $ldflags" echo "LDLIBS: $ldlibs" +echo "LDSHARED: $ldshared" +echo "PREFIX: $prefix_path" +echo +echo " --- Enabled options --- " echo "Enable multithreading: $enable_mt" echo "Enable long file support: $enable_lfs" echo "Enable tests: $enable_tests" -echo "Build dynamic library: $enable_dynamic" +echo "Enable PIC: $enable_pic" +echo "Build shared library: $enable_shared" echo "Use clock_gettime: $use_clock_gettime" |
