#!/bin/sh . package/info 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 "$*" 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 } choose () { what="$1" name="$2" macro="$3" echo "Checking whether system has $4..." shift 4 libs="$*" r=true case "$what" in *c*) $CC_AUTO $CPPFLAGS_AUTO $CFLAGS_AUTO -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 $LDFLAGS_AUTO -o try$name try$name.o $libs 2>/dev/null || r=false ;; esac fi if $r ; then case "$what" in *r*) ./try$name >/dev/null 2>&1 ; r=$? case "$r" in 111) echo " ... test crashed, aborting." ; exit 111 ;; 0) r=true ;; *) r=false ;; esac esac fi rm -f try$name.o try$name if $r ; then echo "$name: yes" >> $sysdeps/sysdeps echo "#define ${package_macro_name}_HAS$macro" >> $sysdeps/sysdeps.h echo " ... yes" else echo "$name: no" >> $sysdeps/sysdeps echo "#undef ${package_macro_name}_HAS$macro" >> $sysdeps/sysdeps.h echo " ... no" fi } trytypes () { echo "Checking size and signedness of standard types..." $CC_AUTO $CPPFLAGS_AUTO $CFLAGS_AUTO $LDFLAGS_AUTO -o output-types src/sysdeps/output-types.c ./output-types >> $sysdeps/sysdeps ./output-types | grep -F sizeof | while read key value ; do caps=$(echo $key | sed s/:\$// | tr a-z A-Z) echo "#define ${package_macro_name}_${caps} $value" >> $sysdeps/sysdeps.h done ./output-types | grep -F signed | while read key value ; do caps=$(echo $key | sed s/:\$// | tr a-z A-Z) if test $value = yes ; then echo "#define ${package_macro_name}_HASSIGNED${caps}" echo "#undef ${package_macro_name}_HASUNSIGNED${caps}" else echo "#undef ${package_macro_name}_HASSIGNED${caps}" echo "#define ${package_macro_name}_HASUNSIGNED${caps}" fi >> $sysdeps/sysdeps.h done rm -f output-types echo " ... done" } trylibs () { args= name=$1 echo "Checking whether system has $2..." >&3 shift 2 if $CC_AUTO $CPPFLAGS_AUTO $CFLAGS_AUTO -c -o try$name.o src/sysdeps/try$name.c 2>/dev/null ; then until $CC_AUTO $CFLAGS_AUTO $LDFLAGS_AUTO -o /dev/null try$name.o $args 2>/dev/null ; do if test -z "$*" ; then rm -f try$name.o echo echo " ... no" >&3 return 1 fi args="$args $1" shift done echo ${args# } if test -z "$args" ; then echo " ... yes" >&3 else echo " ... yes, with$args" >&3 fi rm -f try$name.o return 0 else echo echo " ... no" >&3 return 1 fi } # Actual script CC_AUTO= CFLAGS_AUTO="$CFLAGS" CPPFLAGS_AUTO="-D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -O2 $CPPFLAGS" LDFLAGS_AUTO="$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' sysdeps= shared=true static=true slashpackage=false ipv6=true select=false taiclock=false clockrt=false clockmon=false ddefaultpath=/usr/bin:/bin defaultpath=$ddefaultpath dpathorig=true sproot= home= exthome= addincpath='' addlibspath='' addlibdpath='' vpaths='' vpathd='' build= 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-sysdeps=*) sysdeps=${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-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-clock|--enable-clock=yes) clockrt=true ;; --disable-clock|--enable-clock=no) clockrt=false ;; --enable-monotonic|--enable-monotonic=yes) clockmon=true ;; --disable-monotonic|--enable-monotonic=no) clockmon=false ;; --with-default-path=*) defaultpath=${arg#*=} ; dpathorig=false ;; --without-default-path) defaultpath=$ddefaultpath ; dpathorig=true ;; --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 sysdeps sproot ; do eval tmp=\${$i} eval $i=$tmp stripdir $i done # Get usable temp filenames i=0 set -C while : ; do i=$(($i+1)) tmpc="./tmp-configure-$$-$PPID-$i.c" tmpe="./tmp-configure-$$-$PPID-$i.tmp" 2>|/dev/null > "$tmpc" && break 2>|/dev/null > "$tmpe" && break test "$i" -gt 50 && fail "$0: cannot create temporary files" done set +C trap 'rm -f "$tmpc" "$tmpe"' EXIT ABRT INT QUIT TERM HUP # 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 # 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 ${cross}${CC} trycc ${cross}gcc trycc ${cross}clang trycc ${cross}cc test -n "$CC_AUTO" || { echo "$0: cannot find a C compiler" ; exit 1 ; } echo " ... $CC_AUTO" echo "Checking whether C compiler works... " echo "typedef int x;" > "$tmpc" if $CC_AUTO $CPPFLAGS_AUTO $CFLAGS_AUTO -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" tryflag CPPFLAGS_AUTO -std=c99 tryflag CPPFLAGS_AUTO -fomit-frame-pointer tryflag CPPFLAGS_AUTO -fno-exceptions tryflag CPPFLAGS_AUTO -fno-unwind-tables tryflag CPPFLAGS_AUTO -fno-asynchronous-unwind-tables tryflag CPPFLAGS_AUTO -Wa,--noexecstack tryflag CPPFLAGS_AUTO -fno-stack-protector 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_AUTO -Wl,--hash-style=both fi if test -n "$sysdeps" ; then if test ! -d $sysdeps || test ! -f $sysdeps/target ; then echo "$0: error: $sysdeps is not a valid sysdeps directory" exit 1 fi if [ "x$target" != "x$(cat $sysdeps/target)" ] ; then echo "$0: error: target $target does not match the contents of $sysdeps/target" exit 1 fi echo "Using pre-computed sysdeps in $sysdeps." spawn_lib=$(cat $sysdeps/spawn.lib) socket_lib=$(cat $sysdeps/socket.lib) sysclock_lib=$(cat $sysdeps/sysclock.lib) tainnow_lib=$(cat $sysdeps/tainnow.lib) timer_lib=$(cat $sysdeps/timer.lib) util_lib=$(cat $sysdeps/util.lib) else sysdeps=sysdeps.cfg mkdir -p $sysdeps echo "$target" > $sysdeps/target echo "target: $target" > $sysdeps/sysdeps cat < $sysdeps/sysdeps.h /* ISC license. */ #ifndef SYSDEPS_H #define SYSDEPS_H #define SKALIBS_TARGET "$target" EOF exec 3>&1 util_lib= echo > $sysdeps/util.lib socket_lib=`trylibs lsock 'accessible socket functions' -lsocket -lnsl` || fail "$0: unable to determine socket.lib sysdep" echo "$socket_lib" > $sysdeps/socket.lib hasclock=true sysclock_lib=`trylibs clockrt 'clock_gettime()' -lrt` || hasclock=false if $clockrt ; then tainnow_lib=$sysclock_lib else tainnow_lib= fi echo "$sysclock_lib" > $sysdeps/sysclock.lib echo "$tainnow_lib" > $sysdeps/tainnow.lib if $hasclock ; then echo 'clockrt: yes' >> $sysdeps/sysdeps echo "#define ${package_macro_name}_HASCLOCKRT" >> $sysdeps/sysdeps.h choose cl clockmon CLOCKMON CLOCK_MONOTONIC $sysclock_lib else echo 'clockrt: no' >> $sysdeps/sysdeps echo "#undef ${package_macro_name}_HASCLOCKRT" >> $sysdeps/sysdeps.h fi hasspawn=true spawn_lib=`trylibs posixspawn 'posix_spawn()' -lrt` || hasspawn=false echo "$spawn_lib" > $sysdeps/spawn.lib if $hasspawn ; then echo 'posixspawn: yes' >> $sysdeps/sysdeps echo "#define ${package_macro_name}_HASPOSIXSPAWN" >> $sysdeps/sysdeps.h else echo 'posixspawn: no' >> $sysdeps/sysdeps echo "#undef ${package_macro_name}_HASPOSIXSPAWN" >> $sysdeps/sysdeps.h fi hastimer=true timer_lib=`trylibs timer 'timer_create()' -lrt` || hastimer=false echo "$timer_lib" > $sysdeps/timer.lib if $hastimer ; then echo 'timer: yes' >> $sysdeps/sysdeps echo "#define ${package_macro_name}_HASTIMER" >> $sysdeps/sysdeps.h else echo 'timer: no' >> $sysdeps/sysdeps echo "#undef ${package_macro_name}_HASTIMER" >> $sysdeps/sysdeps.h fi exec 3>&- echo "Checking system endianness..." $CC_AUTO $CPPFLAGS_AUTO $CFLAGS_AUTO -o tryendianness src/sysdeps/tryendianness.c endianness=$(./tryendianness) || fail "$0: unable to determine endianness" echo "endianness: $endianness" >> $sysdeps/sysdeps echo "#define ${package_macro_name}_ENDIANNESS \"$endianness\"" >> $sysdeps/sysdeps.h echo " ... $endianness" rm -f tryendianness trytypes choose clr accept4 ACCEPT4 'accept4()' choose clr ancilautoclose ANCILAUTOCLOSE 'auto-close after fd-passing' choose c cmsgcloexec CMSGCLOEXEC 'MSG_CMSG_CLOEXEC' choose clr devurandom DEVURANDOM '/dev/urandom' choose c eproto EPROTO EPROTO choose cl eventfd EVENTFD 'eventfd()' choose cl flock FLOCK 'flock()' choose cl getpeereid GETPEEREID 'getpeereid()' choose cl sopeercred SOPEERCRED 'SO_PEERCRED' choose cl getpeerucred GETPEERUCRED 'getpeerucred()' choose cl ipv6 IPV6 'IPv6 support' $socket_lib choose clr malloc0 MALLOC0 'non-NULL malloc(0)' choose c msgdontwait MSGDONTWAIT 'MSG_DONTWAIT' choose clr nbwaitall NBWAITALL 'non-blocking MSG_WAITALL' choose cl openat OPENAT 'openat()' choose cl linkat LINKAT 'linkat()' choose clr pipe2 PIPE2 'pipe2()' choose clr ppoll PPOLL 'ppoll()' choose cl revoke REVOKE 'revoke()' choose cl sendfile SENDFILE 'sendfile()' choose cl setgroups SETGROUPS 'setgroups()' choose cl settimeofday SETTIMEOFDAY 'settimeofday()' choose clr signalfd SIGNALFD 'signalfd()' choose clr splice SPLICE 'splice()' choose cl strcasestr STRCASESTR 'strcasestr()' choose cl strnlen STRNLEN 'strnlen()' choose c uint64t UINT64T 'uint64_t' choose cl futimens FUTIMENS 'futimens()' choose cl futimes FUTIMES 'futimes()' choose cl arc4random ARC4RANDOM 'arc4random()' choose cl arc4random_addrandom ARC4RANDOM_ADDRANDOM 'arc4random_addrandom()' choose clr getrandom GETRANDOM 'getrandom()' choose cl itimer ITIMER 'setitimer()' echo '#endif' >> $sysdeps/sysdeps.h fi echo "Copying $sysdeps/sysdeps.h to src/include/${package}/sysdeps.h ..." cat < $sysdeps/sysdeps.h > src/include/${package}/sysdeps.h echo " ... done" 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} TAINNOW_LIB := ${tainnow_lib} TIMER_LIB := ${timer_lib} UTIL_LIB := ${util_lib} CC := ${CC_AUTO##${cross}} CFLAGS := $CFLAGS_AUTO CPPFLAGS := $CPPFLAGS_AUTO LDFLAGS := $LDFLAGS_AUTO 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 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."