view configure @ 256:7520e2260097

- added to configure some detection on how to compile .s/.S with --noexecstack (or similar), as compilers' defaults are often insane - since no-execstack handling is now in build, remove .note.GNU-stack section markers (were of limites use, anyways, b/c unportable or implemented inconsistently across platforms) - some ToDo, etc. updates
author Tassilo Philipp
date Sat, 20 May 2017 00:02:59 +0200
parents 5cfe4322c500
children 8bb4618c18d8
line wrap: on
line source

#!/bin/sh

usage() {
cat <<EOF
usage: $0 --<option>=<value> <var>=<value> ..

  --prefix=<dir>
  --target=<platform>       uname/special targets: MacOSX,iOS,iPhoneSimulator
                            use "?" to get a list of explicitly specifiable
                            targets
  --sdk=<version>           Mac OS X/iOS SDK version (e.g. '6.1' or '10.9.3')
                            Tested iOS SDK versions: 4.3, 6.1, 8.1 
  --sdkroot=<dir>

Useful variables CC, CXX, CFLAGS, CXXFLAGS, etc..

EOF
}

C=Makefile.config

# get full path to this file (portable way), and set where to build
SRCTOP="`cd \`dirname "$0"\` && pwd`"
BLDTOP="$PWD"


printf "# auto-generated by $0\n" >$C

while [ $# -gt 0 ]; do
  X=$1
  shift 1
  case $X in
# Shell common:
    --help|-h|-?)
      usage
      exit 1
      ;;
# GNU Compatibility:
    --prefix=*)
      PREFIX=`printf -- "${X}" | cut -c 10-`
      ;;
    --target=*)
      TARGET=`printf -- "${X}" | cut -c 10-`
      ;;
    --sdk=*)
      SDK=`printf -- "${X}" | cut -c 7-`
      ;;
    --sdkroot=*)
      SDKROOT=`printf -- "${X}" | cut -c 11-`
      ;;
# Environment variables:
    [A-Za-z_]*=*)
      printf "${X}\n" >>$C
      k=`printf "${X}" | cut -d = -f 1`
      v=`printf "${X}" | cut -d = -f 2`
      export $k="$v"
      ;;
# Others fail:
    *)
      printf "error: invalid option ${X}\n" >&2
      exit 1
      ;;
  esac
done

printf "PREFIX=${PREFIX:=/usr/local}\n" >>$C

case ${TARGET:=`uname`} in
  Linux|GNU/kFreeBSD)
    if [ -z "${CFLAGS}" ]; then
      printf "CFLAGS=-fPIC\n" >>$C
    fi
    printf "LDLIBS=-lm -ldl\n" >>$C
    ;;
  OpenBSD)
    if [ -z "${CFLAGS}" ]; then
      # dl_iterate_phdr() got introduced in 3.7, so for older versions force DL_DLADDR_TO_LIBPATH
      if (uname -r | grep '^\([0-2]\.\|3\.[0-6]\)' > /dev/null); then
        printf "CFLAGS=-fPIC -DDL_DLADDR_TO_LIBPATH\n" >>$C
      else
        printf "CFLAGS=-fPIC\n" >>$C
      fi
    fi
    printf "LDLIBS=-lm\n" >>$C
    ;;
  NetBSD|DragonFly)
    if [ -z "${CFLAGS}" ]; then
      printf "CFLAGS=-fPIC\n" >>$C
    fi
    printf "LDLIBS=-lm\n" >>$C
    ;;
  FreeBSD)
    if [ -z "${CFLAGS}" ]; then
      printf "CFLAGS=-fPIC\n" >>$C
    fi
    printf "LDLIBS=-lm\n" >>$C
    printf "RM=rm -f\n" >>$C
    ;;
  MacOSX|Darwin)
    # if Apple's libtool (not to be confused with GNU's) is available, which is according to libtool(1) "with -static [...] intended
    # to replace ar(5) and ranlib", use it - if it is shadowed by some install of GNU's libtool assume that a foreign environment is
    # intentionally used, and fall back to using 'ar rs' (the equivalent to 'libtool -static'), for compatibility:
    if libtool -V >/dev/null 2>/dev/null; then # Apple's libtool has -V for version, which GNU does not.
      printf "AR=libtool\n" >>$C
      printf "ARFLAGS=-static -o\n" >>$C
    else
      printf "AR=ar\n" >>$C
      printf "ARFLAGS=rs\n" >>$C # 's' is crucial for universal binary archives
    fi
    if [ `uname -n` = 'iPhone' ]; then # building on iPhone itself, uname yields Darwin (gcc setup for current/correct arch)
      printf "CC=gcc\n" >>$C
    elif [ -z ${SDK} ]; then
      case `sw_vers -productVersion` in
        10.4.*)
          ARCHS="-arch ppc -arch i386 -arch x86_64" 
          ;;
        10.5.*)
          ARCHS="-arch i386 -arch x86_64 -arch ppc"
          ;;
        10.6.*)
          ARCHS="-arch i386 -arch x86_64"
          ;;
        10.[789].*|10.1?.*|10.1?)
          ARCHS="-arch x86_64 -arch i386"
          ;;
      esac
      printf "ASFLAGS=${ARCHS}\n" >>$C
      printf "CFLAGS=${ARCHS}\n" >>$C
      printf "CXXFLAGS=${ARCHS}\n" >>$C
    else
      if [ -z ${SDKROOT} ]; then
        SDKROOT="`xcode-select -print-path`/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${SDK}.sdk"
      fi
      printf "CFLAGS=-isysroot ${SDKROOT}\n" >>$C
      printf "CXXFLAGS=-isysroot ${SDKROOT}\n" >>$C
    fi
    ;;
  iPhoneOS|iOS)
    if [ -z ${SDKROOT} ]; then
      SDKROOT="`xcode-select -print-path`/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${SDK}.sdk"
    fi
    if [ -z "${ARCHS}" ]; then
      case "${SDK}" in
        [45].*)
          ARCHS="-arch armv6"
          ;;
        [67].*)
          ARCHS="-arch armv7"
          ;;
        [89].*)
          ARCHS="-arch armv7 -arch arm64"
          ;;
      esac
    fi
    printf "ARFLAGS=rs\n" >>$C # 's' is crucial for universal binary archives
    printf "ASFLAGS=${ARCHS} -isysroot ${SDKROOT}\n" >>$C
    printf "CFLAGS=${ARCHS} -isysroot ${SDKROOT}\n" >>$C
    printf "CXXFLAGS=${ARCHS} -isysroot ${SDKROOT}\n" >>$C
    printf "LDFLAGS=-Wl,-syslibroot ${SDKROOT}\n" >>$C
    ;;
  iPhoneSimulator)
    if [ -z ${SDKROOT} ]; then
      SDKROOT="`xcode-select -print-path`/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${SDK}.sdk"
    fi
    ARCHS="-arch i386"
    printf "ASFLAGS=${ARCHS} -isysroot ${SDKROOT}\n" >>$C
    printf "CFLAGS=${ARCHS} -isysroot ${SDKROOT}\n" >>$C
    printf "CXXFLAGS=${ARCHS} -isysroot ${SDKROOT}\n" >>$C
    printf "LDFLAGS=-Wl,-syslibroot ${SDKROOT}\n" >>$C
    ;;
  SunOS)
    # open distributions often don't come with default cc and CC, check for common alternatives.
    printf "CC=` (which cc gcc clang  ) | grep -v '^no ' | head -1`\n" >>$C
    printf "CXX=`(which CC g++ clang++) | grep -v '^no ' | head -1`\n" >>$C # C++ compiler traditionally named CC
    printf "CCC=\${CXX}\n" >>$C # Sun make's rules use CCC for c++ compiler
    printf "LDLIBS=-lm -ldl\n" >>$C
    ;;
  Minix)
    printf "CC=gcc\n" >>$C
    printf "CXX=g++\n">>$C
    printf "AR=ar\n"  >>$C
    ;;
  PSP)
    SDKROOT="`psp-config --pspsdk-path`"
    printf "CC=psp-gcc\n" >>$C
    printf "CXX=psp-gcc\n">>$C # don't use psp-g++, buggy
    printf "AR=psp-ar\n"  >>$C
    printf "CFLAGS=-I${SDKROOT}/include/\n" >>$C
    printf "CXXFLAGS=-I${SDKROOT}/include/\n" >>$C
    # Pulling in dyncall libs below is a hack, for some reason psp-ld is super-picky about order.
    # Use your C lib of choice, from the PSPSDK, or...
    #printf "LDLIBS=-L${SDKROOT}/lib/ -L${SRCTOP}/dyncall -L${SRCTOP}/dyncallback -ldyncall_s -ldyncallback_s -lm -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lstdc++ -lpsplibc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser \n" >>$C
    # ... newlib.
    printf "LDLIBS=-L${SDKROOT}/lib/ -L${SRCTOP}/dyncall -L${SRCTOP}/dyncallback -ldyncall_s -ldyncallback_s -lm -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lstdc++ -lc       -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser \n" >>$C
    ;;
  ?)
    cat $0 | awk '/^esac$/{b=0}/^  [A-Za-z0-9|]+\)/{if(b==1) print substr($1,1,length($1)-1)}BEGIN{b=0}/^case.*TARGET.*uname.*in$/{b=1}' | tr '|' '\n'
    exit 0
    ;;
esac


# Assure objects not asking for an execstack (or binary that links dyncall might end
# up with one, for no reason).

# We run our .s and .S files through $CC. GCC and others (annoyingly) assume without
# being told explicitly that an executable stack may be required for those.
# Trying to specify this per source via .section .note.GNU-stack,"",... turned out to
# be not consistently implemented across our supported platforms and toolchains, and
# thus not being portable (on some platforms even resulting in the opposite, the mere
# presence of this section, no matter the flags, creating an rwx stack).
# So, let's set the needed build flags by running a few tests, if we find any that
# work.

#determine_asflags() {
#	AS_PROG=".global main\nmain:\n"
#	echo "${AS_PROG}"                              | cc -xassembler -o rwxtest.d.out -
#	echo "${AS_PROG}.section .note.GNU-stack,\"\"" | cc -xassembler -o rwxtest.s.out -
#	echo "${AS_PROG}"                              | cc -xassembler -o rwxtest.f.out -Wa,--noexecstack -

# @@@ find solution for platforms without objdump
RWXTESTBIN="$BLDTOP/rwxtest.out" # @@@ put this maybe all in Makefile.generic? out of source builds?
STACKFLAGS=`make -f - <<MAKEFILE
include $C
t:
	@(echo .global main;echo main:) | \\\${CC} -xassembler -o "$RWXTESTBIN" -Wa,--noexecstack -
	@(which objdump && objdump -p "$RWXTESTBIN") | grep -A1 STACK | sed '1d;s/^.*flags //' | awk '{print \\\$1}'
MAKEFILE
`
rm "$RWXTESTBIN" 2>/dev/null
if [ "$STACKFLAGS" = "rw-" ]; then
  # platforms differe here, so set them all
  printf "ASFLAGS=-Wa,--noexecstack\n" >>$C # common on GNU
  printf "ACFLAGS=-Wa,--noexecstack\n" >>$C # specifically for .S.o
  printf "AFLAGS=--noexecstack\n"      >>$C # for direct assembler invocation
fi

#if echo ".global main\nmain:\n" | cc -xassembler -o rwxtest.f.out -Wa,--noexecstack -
#(which objdump && objdump -p rwxtest.f.out  || echo stack flags lookup_err) | grep -i -A1 stack | grep 'flags.*' | sed 's/^.*flags //'
#}

#printf "ACFLAGS=-Wa,--noexecstack\n" >>$C
#printf "AFLAGS=--noexecstack\n" >>$C


# Generate all makefiles needed

FILES=`( cd $SRCTOP ; find . -name "Makefile.generic" )`
for FILE in $FILES ; do
  SRCFILE="$SRCTOP/$FILE"
  BLDFILE="$BLDTOP/$FILE"
  SRCDIR=`dirname $SRCFILE`
  BLDDIR=`dirname $BLDFILE`
  mkdir -p "$BLDDIR"
  cat <<EOF >$BLDDIR/Makefile
VPATH = $SRCDIR
include $BLDTOP/Makefile.config
include \${VPATH}/Makefile.generic
EOF
done