rework langinfo code for ABI compat and for use by time code
[musl] / configure
index 1e8b974..327863c 100755 (executable)
--- a/configure
+++ b/configure
@@ -24,6 +24,7 @@ System types:
   --host=HOST             same as --target
 
 Optional features:
+  --enable-optimize=...   optimize listed components for speed over size [auto]
   --enable-debug          build with debugging information [disabled]
   --enable-warnings       build with recommended warnings flags [disabled]
   --enable-gcc-wrapper    build musl-gcc toolchain wrapper [auto]
@@ -34,6 +35,7 @@ Some influential environment variables:
   CC                      C compiler command [detected]
   CFLAGS                  C compiler flags [-Os -pipe ...]
   CROSS_COMPILE           prefix for cross compiler and tools [none]
+  LIBCC                   compiler runtime library [detected]
 
 Use these variables to override the choices made by configure.
 
@@ -49,15 +51,29 @@ fnmatch () { eval "case \"\$2\" in $1) return 0 ;; *) return 1 ;; esac" ; }
 cmdexists () { type "$1" >/dev/null 2>&1 ; }
 trycc () { test -z "$CC" && cmdexists "$1" && CC=$1 ; }
 
-setdir () {
-if eval "test -z \"\${$1}\"" ; then eval "$1=\$2"
-else eval "fnmatch '*/' \"\${$1}\"" && eval "$1=\${$1%/}" ; fi
+stripdir () {
+while eval "fnmatch '*/' \"\${$1}\"" ; do eval "$1=\${$1%/}" ; done
+}
+
+trycppif () {
+printf "checking preprocessor condition %s... " "$1"
+echo "typedef int x;" > "$tmpc"
+echo "#if $1" >> "$tmpc"
+echo "#error yes" >> "$tmpc"
+echo "#endif" >> "$tmpc"
+if $CC $2 -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
+printf "false\n"
+return 1
+else
+printf "true\n"
+return 0
+fi
 }
 
 tryflag () {
 printf "checking whether compiler accepts %s... " "$2"
 echo "typedef int x;" > "$tmpc"
-if "$CC" "$2" -c -o /dev/null "$tmpc" 2>/dev/null ; then
+if $CC "$2" -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
 printf "yes\n"
 eval "$1=\"\${$1} \$2\""
 eval "$1=\${$1# }"
@@ -71,7 +87,7 @@ fi
 tryldflag () {
 printf "checking whether linker accepts %s... " "$2"
 echo "typedef int x;" > "$tmpc"
-if "$CC" -nostdlib -shared "$2" -o /dev/null "$tmpc" 2>/dev/null ; then
+if $CC -nostdlib -shared "$2" -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
 printf "yes\n"
 eval "$1=\"\${$1} \$2\""
 eval "$1=\${$1# }"
@@ -89,15 +105,17 @@ fi
 CFLAGS_C99FSE=
 CFLAGS_AUTO=
 LDFLAGS_AUTO=
-prefix=
-exec_prefix=
-bindir=
-libdir=
-includedir=
-syslibdir=
+OPTIMIZE_GLOBS=
+prefix=/usr/local/musl
+exec_prefix='$(prefix)'
+bindir='$(exec_prefix)/bin'
+libdir='$(prefix)/lib'
+includedir='$(prefix)/include'
+syslibdir='/lib'
 target=
+optimize=auto
 debug=no
-warnings=
+warnings=no
 shared=yes
 static=yes
 
@@ -114,6 +132,9 @@ case "$arg" in
 --disable-shared|--enable-shared=no) shared=no ;;
 --enable-static|--enable-static=yes) static=yes ;;
 --disable-static|--enable-static=no) static=no ;;
+--enable-optimize) optimize=yes ;;
+--enable-optimize=*) optimize=${arg#*=} ;;
+--disable-optimize) optimize=no ;;
 --enable-debug|--enable-debug=yes) debug=yes ;;
 --disable-debug|--enable-debug=no) debug=no ;;
 --enable-warnings|--enable-warnings=yes) warnings=yes ;;
@@ -128,17 +149,15 @@ CFLAGS=*) CFLAGS=${arg#*=} ;;
 CPPFLAGS=*) CPPFLAGS=${arg#*=} ;;
 LDFLAGS=*) LDFLAGS=${arg#*=} ;;
 CROSS_COMPILE=*) CROSS_COMPILE=${arg#*=} ;;
+LIBCC=*) LIBCC=${arg#*=} ;;
 *=*) ;;
 *) target=$arg ;;
 esac
 done
 
-setdir prefix /usr/local/musl
-setdir exec_prefix '$(prefix)'
-setdir bindir '$(exec_prefix)/bin'
-setdir libdir '$(prefix)/lib'
-setdir includedir '$(prefix)/include'
-setdir syslibdir '/lib'
+for i in prefix exec_prefix bindir libdir includedir syslibdir ; do
+stripdir $i
+done
 
 #
 # Get a temp filename we can use
@@ -147,7 +166,7 @@ i=0
 set -C
 while : ; do i=$(($i+1))
 tmpc="./conf$$-$PPID-$i.c"
-2>/dev/null > "$tmpc" && break
+2>|/dev/null > "$tmpc" && break
 test "$i" -gt 50 && fail "$0: cannot create temporary file $tmpc"
 done
 set +C
@@ -168,7 +187,7 @@ test -n "$CC" || { echo "$0: cannot find a C compiler" ; exit 1 ; }
 #
 if test -z "$wrapper" ; then
 printf "checking whether compiler is gcc... "
-if fnmatch '*gcc\ version*' "$("$CC" -v 2>&1)" ; then
+if fnmatch '*gcc\ version*' "$($CC -v 2>&1)" ; then
 echo yes
 printf "checking whether to build musl-gcc wrapper... "
 wrapper=yes
@@ -189,7 +208,7 @@ fi
 # Find the target architecture
 #
 printf "checking target system type... "
-test -n "$target" || target=$("$CC" -dumpmachine 2>/dev/null) || target=unknown
+test -n "$target" || target=$($CC -dumpmachine 2>/dev/null) || target=unknown
 printf "%s\n" "$target"
 
 #
@@ -200,6 +219,8 @@ arm*) ARCH=arm ;;
 i?86*) ARCH=i386 ;;
 x86_64*) ARCH=x86_64 ;;
 mips-*|mipsel-*) ARCH=mips ;;
+microblaze-*) ARCH=microblaze ;;
+powerpc-*) ARCH=powerpc ;;
 unknown) fail "$0: unable to detect target arch; try $0 --target=..." ;;
 *) fail "$0: unknown or unsupported target \"$target\"" ;;
 esac
@@ -215,33 +236,84 @@ tryflag CFLAGS_C99FSE -fexcess-precision=standard \
 || { test "$ARCH" = i386 && tryflag CFLAGS_C99FSE -ffloat-store ; }
 tryflag CFLAGS_C99FSE -frounding-math
 
+
 #
-# Setup basic default CFLAGS: debug, optimization, and -pipe
+# If debugging is explicitly enabled, don't auto-enable optimizations
 #
-if fnmatch '-O*|*\ -O*' "$CFLAGS_AUTO $CFLAGS" ; then :
+if test "$debug" = yes ; then
+CFLAGS_AUTO=-g
+test "$optimize" = auto && optimize=no
+fi
+
+#
+# Possibly add a -O option to CFLAGS and select modules to optimize with
+# -O3 based on the status of --enable-optimize and provided CFLAGS.
+#
+printf "checking for optimization settings... "
+case "x$optimize" in
+xauto)
+if fnmatch '-O*|*\ -O*' "$CFLAGS_AUTO $CFLAGS" ; then
+printf "using provided CFLAGS\n" ;optimize=no
 else
-tryflag CFLAGS_AUTO -Os || tryflag CFLAGS_AUTO -O2
+printf "using defaults\n" ; optimize=yes
 fi
-test "x$debug" = xyes && CFLAGS_AUTO="-g"
+;;
+xsize|xnone) printf "minimize size\n" ; optimize=size ;;
+xno|x) printf "disabled\n" ; optimize=no ;;
+*) printf "custom\n" ;;
+esac
+
+test "$optimize" = no || tryflag CFLAGS_AUTO -Os || tryflag CFLAGS_AUTO -O2
+test "$optimize" = yes && optimize="internal,malloc,math,string"
+
+if fnmatch 'no|size' "$optimize" ; then :
+else
+printf "components to be optimized for speed:"
+while test "$optimize" ; do
+case "$optimize" in
+*,*) this=${optimize%%,*} optimize=${optimize#*,} ;;
+*) this=$optimize optimize=
+esac
+printf " $this"
+case "$this" in
+*/*.c) ;;
+*/*) this=$this*.c ;;
+*) this=$this/*.c ;;
+esac
+OPTIMIZE_GLOBS="$OPTIMIZE_GLOBS $this"
+done
+OPTIMIZE_GLOBS=${OPTIMIZE_GLOBS# }
+printf "\n"
+fi
+
+# Always try -pipe
 tryflag CFLAGS_AUTO -pipe
 
 #
-# If debugging is disabled, omit bloated DWARF2 unwind tables & frame ptr
+# If debugging is disabled, omit frame pointer. Modern GCC does this
+# anyway on most archs even when debugging is enabled since the frame
+# pointer is no longer needed for debugging.
 #
 if fnmatch '-g*|*\ -g*' "$CFLAGS_AUTO $CFLAGS" ; then :
 else 
-tryflag CFLAGS_AUTO -fno-unwind-tables
-tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables
 tryflag CFLAGS_AUTO -fomit-frame-pointer
 fi
 
 #
-# Some optimization levels add bloated alignment that hurt performance
+# Modern GCC wants to put DWARF tables (used for debugging and
+# unwinding) in the loaded part of the program where they are
+# unstrippable. These options force them back to debug sections (and
+# cause them not to get generated at all if debugging is off).
+#
+tryflag CFLAGS_AUTO -fno-unwind-tables
+tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables
+
+#
+# The GNU toolchain defaults to assuming unmarked files need an
+# executable stack, potentially exposing vulnerabilities in programs
+# linked with such object files. Fix this.
 #
-tryflag CFLAGS_AUTO -falign-functions=1
-tryflag CFLAGS_AUTO -falign-labels=1
-tryflag CFLAGS_AUTO -falign-loops=1
-tryflag CFLAGS_AUTO -falign-jumps=1
+tryflag CFLAGS_AUTO -Wa,--noexecstack
 
 #
 # On x86, make sure we don't have incompatible instruction set
@@ -250,13 +322,23 @@ tryflag CFLAGS_AUTO -falign-jumps=1
 # work anyway (issues with atomic ops).
 #
 if test "$ARCH" = "i386" ; then
-fnmatch '-march=*|*\ -march=*' "$CFLAGS" || tryflag CFLAGS_AUTO -march=i486
-fnmatch '-mtune=*|*\ -mtune=*' "$CFLAGS" || tryflag CFLAGS_AUTO -mtune=generic
+fnmatch '-march=*|*\ -march=*' "$CFLAGS" || tryldflag CFLAGS_AUTO -march=i486
+fnmatch '-mtune=*|*\ -mtune=*' "$CFLAGS" || tryldflag CFLAGS_AUTO -mtune=generic
 fi
 
+#
+# Even with -std=c99, gcc accepts some constructs which are constraint
+# violations. We want to treat these as errors regardless of whether
+# other purely stylistic warnings are enabled -- especially implicit
+# function declarations, which are a dangerous programming error.
+#
+tryflag CFLAGS_AUTO -Werror=implicit-function-declaration
+tryflag CFLAGS_AUTO -Werror=implicit-int
+tryflag CFLAGS_AUTO -Werror=pointer-sign
+tryflag CFLAGS_AUTO -Werror=pointer-arith
+
 if test "x$warnings" = xyes ; then
 tryflag CFLAGS_AUTO -Wall
-tryflag CFLAGS_AUTO -Wpointer-arith
 tryflag CFLAGS_AUTO -Wcast-align
 tryflag CFLAGS_AUTO -Wno-parentheses
 tryflag CFLAGS_AUTO -Wno-uninitialized
@@ -268,7 +350,7 @@ fi
 
 # Some patched GCC builds have these defaults messed up...
 tryflag CFLAGS_AUTO -fno-stack-protector
-tryldflag LDFLAGS_AUTO -Wl,--hash-style=sysv
+tryldflag LDFLAGS_AUTO -Wl,--hash-style=both
 
 # Disable dynamic linking if ld is broken and can't do -Bsymbolic-functions
 LDFLAGS_DUMMY=
@@ -277,7 +359,30 @@ printf "warning: disabling dynamic linking support\n"
 shared=no
 }
 
+# Find compiler runtime library
+test -z "$LIBCC" && tryldflag LIBCC -lgcc && tryldflag LIBCC -lgcc_eh
+test -z "$LIBCC" && tryldflag LIBCC -lcompiler_rt
+test -z "$LIBCC" && try_libcc=`$CC -print-file-name=libpcc.a 2>/dev/null` \
+                 && tryldflag LIBCC "$try_libcc"
+printf "using compiler runtime libraries: %s\n" "$LIBCC"
+
+# Figure out arch variants for archs with variants
+SUBARCH=
+t="$CFLAGS_C99FSE $CPPFLAGS $CFLAGS_AUTO $CFLAGS"
+
+if test "$ARCH" = "arm" ; then
+trycppif __ARMEB__ "$t" && SUBARCH=${SUBARCH}eb
+trycppif __SOFTFP__ "$t" || SUBARCH=${SUBARCH}hf
+fi
+
+test "$ARCH" = "mips" && trycppif "_MIPSEL || __MIPSEL || __MIPSEL__" "$t" \
+&& SUBARCH=${SUBARCH}el
+
+test "$ARCH" = "microblaze" && trycppif __MICROBLAZEEL__ "$t" \
+&& SUBARCH=${SUBARCH}el
 
+test "$SUBARCH" \
+&& printf "configured for %s variant: %s\n" "$ARCH" "$ARCH$SUBARCH"
 
 printf "creating config.mak... "
 
@@ -288,6 +393,7 @@ cat << EOF
 # This version of config.mak was generated by configure
 # Any changes made here will be lost if configure is re-run
 ARCH = $ARCH
+SUBARCH = $SUBARCH
 prefix = $prefix
 exec_prefix = $exec_prefix
 bindir = $bindir
@@ -300,6 +406,8 @@ CFLAGS_C99FSE = $CFLAGS_C99FSE
 CPPFLAGS = $CPPFLAGS
 LDFLAGS = $LDFLAGS_AUTO $LDFLAGS
 CROSS_COMPILE = $CROSS_COMPILE
+LIBCC = $LIBCC
+OPTIMIZE_GLOBS = $OPTIMIZE_GLOBS
 EOF
 test "x$static" = xno && echo "STATIC_LIBS ="
 test "x$shared" = xno && echo "SHARED_LIBS ="