#!/bin/sh cd `dirname "$0"` . package/info # Helper functions usage () { cat </dev/null 2>&1 && { echo "$1" ; return 0 ; } $1 EOF echo "$1" | sed -e "s/'/'\\\\''/g" -e "1s/^/'/" -e "\$s/\$/'/" -e "s#^'\([-[:alnum:]_,./:]*\)=\(.*\)\$#\1='\2#" -e "s|\*/|* /|g" } fail () { echo "$*" 1>&2 exit 1 } fnmatch () { eval "case \"\$2\" in $1) return 0 ;; *) return 1 ;; esac" } cmdexists () { type "$1" >/dev/null 2>&1 } trycc () { test -z "$CC_AUTO" && cmdexists "$1" && CC_AUTO="$*" } stripdir () { while eval "fnmatch '*/' \"\${$1}\"" ; do eval "$1=\${$1%/}" done } tryflag () { echo "Checking whether compiler accepts $2 ..." echo "typedef int x;" > "$tmpc" if $CC_AUTO "$2" -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then echo " ... yes" eval "$1=\"\${$1} \$2\"" eval "$1=\${$1# }" return 0 else echo " ... no" return 1 fi } tryldflag () { echo "Checking whether linker accepts $2 ..." echo "typedef int x;" > "$tmpc" if $CC_AUTO -nostdlib "$2" -o /dev/null "$tmpc" >/dev/null 2>&1 ; then echo " ... yes" eval "$1=\"\${$1} \$2\"" eval "$1=\${$1# }" return 0 else echo " ... no" return 1 fi } # Sysdeps determination functions iscached () { if test -r "$tmps" && grep -q "^${1}: " "$tmps" ; then grep "^${1}: " "$tmps" | tail -n 1 | { IFS=' ' read -r k v ldlibs if test -n "$ldlibs" ; then echo " ... user-provided: $v with linker args: $ldlibs" echo "$ldlibs" >&3 else echo " ... user-provided: $v" fi echo "${1}: $v" >> "$sysdeps/sysdeps" return 0 ; } else return 1 ; fi } choose () { what="$1" name="$2" echo "Checking whether system has $3..." if iscached "$name" ; then return ; fi shift 3 libs="$*" r=true case "$what" in *c*) $CC_AUTO $CPPFLAGS_AUTO $CPPFLAGS $CPPFLAGS_POST $CFLAGS_AUTO $CFLAGS $CFLAGS_POST -o try$name.o -c src/sysdeps/try$name.c 2>/dev/null || r=false ;; esac if $r ; then case "$what" in *l*) $CC_AUTO $CFLAGS_AUTO $CFLAGS $CFLAGS_POST $LDFLAGS_AUTO $LDFLAGS $LDFLAGS_POST -o try$name try$name.o $libs 2>/dev/null || r=false ;; esac fi if $r ; then case "$what" in *r*) if test -n "$cross" ; then rm -f try$name.o try$name fail "$0: sysdep $name cannot be autodetected when cross-compiling. Please manually provide a value with the --with-sysdep-${name}=yes|no|... option." fi ./try$name >/dev/null 2>&1 ; r=$? case "$r" in 111) fail "$0: test crashed, aborting." ;; 0) r=true ;; *) r=false ;; esac esac fi rm -f try$name.o try$name if $r ; then echo "$name: yes" >> $sysdeps/sysdeps echo " ... yes" else echo "$name: no" >> $sysdeps/sysdeps echo " ... no" fi } trybasic () { $CC_AUTO $CPPFLAGS_AUTO $CPPFLAGS $CPPFLAGS_POST $CFLAGS_AUTO $CFLAGS $CFLAGS_POST -o "$tmpe" -c "$1" 2>/dev/null r=$? rm -f "$tmpe" return $r } tryendianness () { echo "Checking endianness..." if iscached endianness ; then return ; fi for i in endian.h sys/endian.h machine/endian.h arpa/nameser_compat.h ; do cat > "$tmpc" < int a = LITTLE_ENDIAN ; int b = BIG_ENDIAN ; int c = BYTE_ORDER ; EOF trybasic "$tmpc" || continue for j in little big pdp ; do k=`echo $j | tr a-z A-Z` cat > "$tmpc" < int a[BYTE_ORDER == ${k}_ENDIAN ? 1 : -1] ; EOF if trybasic "$tmpc" ; then echo "endianness: $j" >> "$sysdeps/sysdeps" echo " ... $j" rm -f "$tmpc" return fi done rm -f "$tmpc" fail "$0: error: unable to determine endianness according to $i" done rm -f "$tmpc" fail "$0: error: unable to determine endianness: no suitable endian.h found" } trysigned () { cat > "$tmpc" < int a[($1)-1 < 0 ? 1 : -1] ; EOF trybasic "$tmpc" r=$? rm -f "$tmpc" return $r } trysizes () { t="$1" ; shift for arg ; do cat > "$tmpc" < int a[sizeof($t) == $arg ? 1 : -1] ; EOF if trybasic "$tmpc" ; then rm -f "$tmpc" echo "$arg" return fi done rm -f "$tmpc" fail "$0: error: unable to determine the size of $t on the target" } trystdtype () { t="$1" ; shift iscached "sizeofu$t" || { echon "sizeofu${t}: " ; trysizes "$t" "$@" ; } >> "$sysdeps/sysdeps" } trytypes () { echo "Checking size and signedness of standard types..." trystdtype short 2 4 trystdtype int 4 8 2 trystdtype long 8 4 for t in size uid gid pid time dev ino ; do iscached "signed$t" || { echon "signed${t}: " ; if trysigned "${t}_t" ; then echo "yes" ; else echo "no" ; fi ; } >> "$sysdeps/sysdeps" iscached "sizeof$t" || { echon "sizeof${t}: " ; trysizes "${t}_t" 4 8 2 ; } >> "$sysdeps/sysdeps" done echo " ... done" } detectlibs () { args= name=$1 shift if $CC_AUTO $CPPFLAGS_AUTO $CPPFLAGS $CPPFLAGS_POST $CFLAGS_AUTO $CFLAGS $CFLAGS_POST -c -o try$name.o src/sysdeps/try$name.c 2>/dev/null ; then until $CC_AUTO $CFLAGS_AUTO $CFLAGS $CFLAGS_POST $LDFLAGS_AUTO $LDFLAGS $LDFLAGS_POST -o /dev/null try$name.o $args 2>/dev/null ; do if test -z "$*" ; then rm -f try$name.o return 1 fi args="$args $1" shift done echo ${args# } rm -f try$name.o return 0 else return 1 fi } trylibs () { name="$1" libvar="$2"_lib libfile="$2".lib echo "Checking whether system has $3..." shift 3 if { args=`iscached $name 3>&1 1>&4 4>&-` ; } 4>&1 ; then : elif args=`detectlibs "$name" "$@"` ; then echo "${name}: yes" >> "${sysdeps}/sysdeps" if test -z "$args" ; then echo " ... yes" else echo " ... yes, with linker args: $args" fi else echo "${name}: no" >> ${sysdeps}/sysdeps echo " ... no" fi eval "${libvar}=\"$args\"" echo "$args" > "${sysdeps}/$libfile" } # The script starts HERE. # Initialize variables CC_AUTO= CPPFLAGS_AUTO="-D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -Isrc/include" CPPFLAGS_POST="$CPPFLAGS" CPPFLAGS= CFLAGS_AUTO="-pipe -Wall" CFLAGS_POST="$CFLAGS" CFLAGS="-O2" LDFLAGS_AUTO= LDFLAGS_POST="$LDFLAGS" LDFLAGS= LDFLAGS_NOSHARED= LDFLAGS_SHARED=-shared prefix= dynlibdir='$prefix/lib' libdir='$prefix/lib/$package' includedir='$prefix/include' datadir='$prefix/etc' sysdepdir='$prefix/lib/$package/sysdeps' sysdeplist= shared=true static=true allpic=true slashpackage=false ipv6=true select=false taiclock=false ddefaultpath=/usr/bin:/bin defaultpath=$ddefaultpath dpathorig=true sproot= home= exthome= addincpath='' addlibspath='' addlibdpath='' vpaths='' vpathd='' build= # Parse command line for arg ; do case "$arg" in --help) usage ;; --prefix=*) prefix=${arg#*=} ;; --dynlibdir=*) dynlibdir=${arg#*=} ;; --libdir=*) libdir=${arg#*=} ;; --includedir=*) includedir=${arg#*=} ;; --datadir=*) datadir=${arg#*=} ;; --sysdepdir=*) sysdepdir=${arg#*=} ;; --with-include=*) var=${arg#*=} ; stripdir var ; addincpath="$addincpath -I$var" ;; --with-lib=*) var=${arg#*=} ; stripdir var ; addlibspath="$addlibspath -L$var" ; vpaths="$vpaths $var" ;; --with-dynlib=*) var=${arg#*=} ; stripdir var ; addlibdpath="$addlibdpath -L$var" ; vpathd="$vpathd $var" ;; --enable-shared|--enable-shared=yes) shared=true ;; --disable-shared|--enable-shared=no) shared=false ;; --enable-static|--enable-static=yes) static=true ;; --disable-static|--enable-static=no) static=false ;; --enable-all-pic|--enable-all-pic=yes) allpic=true ;; --disable-all-pic|--enable-all-pic=no) allpic=false ;; --enable-slashpackage=*) sproot=${arg#*=} ; slashpackage=true ; ;; --enable-slashpackage) sproot= ; slashpackage=true ;; --disable-slashpackage) sproot= ; slashpackage=false ;; --enable-ipv6|--enable-ipv6=yes) ipv6=true ;; --disable-ipv6|--enable-ipv6=no) ipv6=false ;; --enable-iopause-select|--enable-iopause-select=yes) select=true ;; --disable-iopause-select|--enable-iopause-select=no) select=false ;; --enable-tai-clock|--enable-tai-clock=yes) taiclock=true ;; --disable-tai-clock|--enable-tai-clock=no) taiclock=false ;; --enable-monotonic|--enable-monotonic=yes) echo "$0: warning: --enable-monotonic is now obsolete" 1>&2 ;; --disable-monotonic|--enable-monotonic=no) ;; --with-default-path=*) defaultpath=${arg#*=} ; dpathorig=false ;; --without-default-path) defaultpath=$ddefaultpath ; dpathorig=true ;; --with-sysdep-*=*) sysdeplist="$sysdeplist ${arg#--with-sysdep-}" ;; --without-sysdep-*) sysdeplist="$sysdeplist ${arg#--without-sysdep-}=no" ;; --enable-*|--disable-*|--with-*|--without-*|--*dir=*) ;; --host=*|--target=*) target=${arg#*=} ;; --build=*) build=${arg#*=} ;; -* ) echo "$0: unknown option $arg" ;; *=*) ;; *) target=$arg ;; esac done # Add /usr in the default default case if test -z "$prefix" ; then if test "$libdir" = '$prefix/lib/$package' ; then libdir=/usr/lib/$package fi if test "$includedir" = '$prefix/include' ; then includedir=/usr/include fi if test "$sysdepdir" = '$prefix/lib/$package/sysdeps' ; then sysdepdir=/usr/lib/$package/sysdeps fi fi # Expand installation directories stripdir prefix for i in exec_prefix dynlibdir libdir includedir datadir sysdepdir sysdepspre sproot ; do eval tmp=\${$i} eval $i=$tmp stripdir $i done # Set slashpackage values if $slashpackage ; then home=${sproot}/package/${category}/${package}-${version} exthome=${sproot}/package/${category}/${package} sysdepdir=${home}/sysdeps binprefix=${home}/command extbinprefix=${exthome}/command dynlibdir=${home}/library.so libdir=${home}/library includedir=${home}/include if $dpathorig ; then if echo $defaultpath | tr : '\n' | grep -q '^/command$' ; then : ; else defaultpath="/command:$defaultpath" fi fi fi # Get usable temp filenames i=0 set -C while test "$i" -lt 50 ; do i=$(($i+1)) tmpc="./tmp-configure-$$-$PPID-$i.c" tmpe="./tmp-configure-$$-$PPID-$i.tmp" tmps="./tmp-configure-$$-$PPID-$i.sysdeps" 2>|/dev/null > "$tmpc" && break 2>|/dev/null > "$tmpe" && break 2>|/dev/null > "$tmps" && break done if test "$i" -gt 50 ; then fail "$0: cannot create temporary files" fi set +C trap 'rm -f "$tmpc" "$tmpe" "$tmps"' EXIT ABRT INT QUIT TERM HUP # Preprocess user-provided sysdeps rm -f "$tmps" if test -n "$sysdeplist" ; then :> "$tmps" for i in $sysdeplist ; do k=${i%%=*} echo ${i#*=} | sed 's/,/ /g' | { read v extras if test -z "$k" || test -z "$v" ; then fail "$0: invalid user-provided sysdep: $i" ; fi if test "$v" = "true" ; then v=yes elif test "$v" = "false" ; then v=no fi if grep -q -e "^${k}: " "$tmps" ; then grep -v -e "^${k}: " "$tmps" > "$tmpe" mv -f "$tmpe" "$tmps" fi if test -n "$extras" ; then echo "${k}: $v $extras" else echo "${k}: $v" fi >> "$tmps" } done fi # Find a C compiler to use if test -n "$target" && test x${build} != x${target} ; then cross=${target}- else cross= fi echo "Checking for C compiler..." trycc ${CC} if test -n "$CC_AUTO" ; then b=`basename "$CC"` adjust_cross=false if test "$b" != "$CC" ; then adjust_cross=true echo "$0: warning: compiler $CC is declared with its own path. If it's not accessible via PATH, you will need to pass AR, RANLIB and STRIP make variables to the make invocation." 1>&2 fi if test -n "$cross" ; then if test "$b" = "${b##$cross}" ; then echo "$0: warning: compiler $CC is declared as a cross-compiler for target $target but does not start with prefix ${cross}" 1>&2 elif $adjust_cross ; then cross=`dirname "$CC"`/"$cross" fi fi fi trycc ${cross}gcc trycc ${cross}clang trycc ${cross}cc test -n "$CC_AUTO" || fail "$0: cannot find a C compiler" echo " ... $CC_AUTO" echo "Checking whether C compiler works... " echo "typedef int x;" > "$tmpc" if $CC_AUTO $CPPFLAGS_AUTO $CPPFLAGS $CPPFLAGS_POST $CFLAGS_AUTO $CFLAGS $CFLAGS_POST -c -o /dev/null "$tmpc" 2>"$tmpe" ; then echo " ... yes" else echo " ... no. Compiler output follows:" cat < "$tmpe" exit 1 fi echo "Checking target system type..." if test -z "$target" ; then if test -n "$build" ; then target=$build ; else target=$($CC_AUTO -dumpmachine 2>/dev/null) || target=unknown fi fi echo " ... $target" # Produce automatic compilation flags if $allpic ; then tryflag CPPFLAGS_AUTO -fPIC fi tryflag CFLAGS_AUTO -std=c99 tryflag CFLAGS -fomit-frame-pointer tryflag CFLAGS_AUTO -fno-exceptions tryflag CFLAGS_AUTO -fno-unwind-tables tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables tryflag CFLAGS_AUTO -Wa,--noexecstack tryflag CPPFLAGS_AUTO -Werror=implicit-function-declaration tryflag CPPFLAGS_AUTO -Werror=implicit-int tryflag CPPFLAGS_AUTO -Werror=pointer-sign tryflag CPPFLAGS_AUTO -Werror=pointer-arith tryflag CPPFLAGS_AUTO -Wno-unused-value tryflag CPPFLAGS_AUTO -Wno-parentheses tryflag CFLAGS_AUTO -ffunction-sections tryflag CFLAGS_AUTO -fdata-sections tryldflag LDFLAGS_AUTO -Wl,--sort-section=alignment tryldflag LDFLAGS_AUTO -Wl,--sort-common if $shared ; then tryldflag LDFLAGS -Wl,--hash-style=both fi # And now, determine a big fat batch of sysdeps. sysdeps=sysdeps.cfg mkdir -p $sysdeps echo "$target" > $sysdeps/target :> "$sysdeps/sysdeps" util_lib= echo > $sysdeps/util.lib echo 'Checking required linker flags for socket functions...' socket_lib=`detectlibs lsock -lsocket -lnsl` || fail "$0: unable to determine required linker flags for socket functions" if test -n "$socket_lib" ; then echo " ... $socket_lib" else echo " ... none" fi echo "$socket_lib" > $sysdeps/socket.lib trylibs clockrt sysclock 'clock_gettime()' -lrt choose cl clockmon CLOCK_MONOTONIC `cat "${sysdeps}/sysclock.lib"` choose cl clockboot CLOCK_BOOTTIME `cat "${sysdeps}/sysclock.lib"` trylibs posixspawn spawn 'posix_spawn()' -lrt trylibs timer timer 'timer_create()' -lrt tryendianness trytypes choose cl accept4 'accept4()' choose c cmsgcloexec 'MSG_CMSG_CLOEXEC' choose cl dirfd 'dirfd()' choose cl eventfd 'eventfd()' choose cl flock 'flock()' choose cl getpeereid 'getpeereid()' choose cl sopeercred 'SO_PEERCRED' choose cl getpeerucred 'getpeerucred()' choose cl ipv6 'IPv6 support' $socket_lib choose c msgdontwait 'MSG_DONTWAIT' choose c odirectory 'O_DIRECTORY' choose cl openat 'openat()' choose cl linkat 'linkat()' choose cl memmem 'memmem()' choose cl pipe2 'pipe2()' choose cl ppoll 'ppoll()' choose cl revoke 'revoke()' choose cl sendfile 'sendfile()' choose cl setgroups 'setgroups()' choose cl settimeofday 'settimeofday()' choose cl signalfd 'signalfd()' choose cl splice 'splice()' choose cl strcasestr 'strcasestr()' choose c strnlen 'strnlen()' choose c uint64t 'uint64_t' choose cl futimens 'futimens()' choose cl futimes 'futimes()' choose cl arc4random 'arc4random()' choose cl arc4random_addrandom 'arc4random_addrandom()' choose cl itimer 'setitimer()' choose cl namespaces 'namespaces' choose cl nsgetparent 'NS_GET_PARENT' choose cl explicit_bzero 'explicit_bzero()' choose cl getrandom 'getrandom()' choose cl chroot 'chroot()' # Here are the evil irreducible run-time sysdeps. choose clr devurandom '/dev/urandom' # Finally, produce config.mak and config.h rm -f "$tmps" echo "Creating config.mak..." cmdline=$(quote "$0") for i ; do cmdline="$cmdline $(quote "$i")" ; done exec 3>&1 1>config.mak cat << EOF # This file was generated by: # $cmdline # Any changes made here will be lost if configure is re-run. target := $target package := $package prefix := $prefix datadir := $datadir sysdepdir := $sysdepdir dynlibdir := $dynlibdir libdir := $libdir includedir := $includedir sysdeps := $sysdeps version := $version sproot := $sproot home := $home exthome := ${exthome} ipv6 := ${ipv6} SPAWN_LIB := ${spawn_lib} SOCKET_LIB := ${socket_lib} SYSCLOCK_LIB := ${sysclock_lib} TIMER_LIB := ${timer_lib} UTIL_LIB := ${util_lib} CC := ${CC_AUTO} CPPFLAGS_AUTO := $CPPFLAGS_AUTO CPPFLAGS := $CPPFLAGS $CPPFLAGS_POST CFLAGS_AUTO := $CFLAGS_AUTO CFLAGS := $CFLAGS $CFLAGS_POST LDFLAGS_AUTO := $LDFLAGS_AUTO LDFLAGS := $LDFLAGS $LDFLAGS_POST LDFLAGS_NOSHARED := $LDFLAGS_NOSHARED LDFLAGS_SHARED := $LDFLAGS_SHARED CROSS_COMPILE := ${cross} EOF if test -n "$vpaths" ; then echo "vpath lib%a$vpaths" fi if test -n "$vpathd" ; then echo "vpath lib%.so$vpathd" fi if $static ; then echo "STATIC_LIBS := libskarnet.a.xyzzy" else echo "STATIC_LIBS :=" fi if $shared ; then echo "SHARED_LIBS := libskarnet.so.xyzzy" else echo "SHARED_LIBS :=" fi if $allpic ; then echo "STATIC_LIBS_ARE_PIC := 1" else echo "STATIC_LIBS_ARE_PIC :=" fi exec 1>&3 3>&- echo " ... done." echo "Creating src/include/${package}/config.h..." mkdir -p -m 0755 src/include/${package} exec 3>&1 1> src/include/${package}/config.h cat <&3 3>&- echo " ... done."