#!/bin/sh set -e CONFIGDIR="$(dirname $0)/config" show_help() { cat <<-EOF usage: ./configure [options...] Options: -a arch Choose the underlying architecture to build for: $(awk '{ printf("\t%s\n", $0); }' ${CONFIGDIR}/architecture) -c version Conform to: $(awk '{ printf("\t%s\n", $0); }' ${CONFIGDIR}/versions.c) -p version Conform to: $(awk '{ printf("\t%s\n", $0); }' ${CONFIGDIR}/versions.posix) -w wordsize Choose a word size for the architecuture: $(awk '{ printf("\t%s\n", $0); }' ${CONFIGDIR}/wordsize) -x version Conform to: $(awk '{ printf("\t%s\n", $0); }' ${CONFIGDIR}/versions.xopen) EOF } validate_option() { option="${CONFIGDIR}/$1" for opt in $(awk '/^[0-9]/ { print $1 }' "${option}"); do if [ "$2" = "${opt}" ]; then echo "$2" return 0 fi done printf 'Invalid option '%s'. Valid options are:\n' "$2" >&2 cat "${option}" >&2 exit 1 } option= architecture=x86 wordsize=64 standard_c= posix= xopen= while getopts hc:p:x: option; do case ${option} in a) architecture=$(validate_option architecture ${OPTARG}) ;; c) standard_c=$(validate_option c ${OPTARG}) ;; p) posix=$(validate_option posix ${OPTARG}) ;; w) wordsize=$(validate_option wordsize ${OPTARG}) ;; x) xopen=$(validate_option xopen ${OPTARG}) ;; h) show_help exit 0 ;; ?) printf 'Unknown option "%c". Try "-h" for help.\n' $option exit 1 ;; esac done if [ -z "${standard_c}" ] && [ -z "${posix}" ] && [ -z "${xopen}" ]; then xopen=700 fi if [ -n "${posix}" ] && [ -n "${xopen}" ]; then printf 'Specify only one of "-x" or "-p".\n' exit 1 fi if [ -n "${xopen}" ]; then if [ $xopen -eq 700 ]; then posix=200809 elif [ $xopen -eq 600 ]; then posix=200112 elif [ $xopen -eq 500 ]; then posix=199506 else posix=2 fi fi if [ -z "${standard_c}" ] && [ -n "${posix}" ]; then if [ $posix -ge 200112 ]; then standard_c=199901 else standard_c=1 fi fi if [ ${posix:-0} -ge 200112 ] && [ $standard_c -lt 199901 ]; then printf 'POSIX.1-2001 and newer require C99 or newer.\n' exit 1 fi printf 'Building C library for %d-bit %s conforming to:\n' "${wordsize}" "${architecture}" printf 'ISO C: %d\n' ${standard_c} test -n "${posix}" && printf 'POSIX: %d\n' ${posix} test -n "${xopen}" && printf 'X/OPEN: %d\n' ${xopen} cat <<-EOF > .config.mk .POSIX: ARCHITECTURE=${architecture} WORDSIZE=${wordsize} TOPDIR=$(dirname $0) SRCDIR=\$(TOPDIR)/src INCDIR=\$(TOPDIR)/include OBJDIR=./obj EOF if [ ${standard_c:-1} -lt 199901 ]; then printf 'CC=c89\n' >> .config.mk else printf 'CC=c%02d\n' $(( (standard_c / 100) % 100 )) >> .config.mk fi if [ -n "${xopen}" ]; then if [ $xopen -eq 400 ]; then printf 'CFLAGS=-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1\n' >> .config.mk else printf 'CFLAGS=-D_XOPEN_SOURCE=%d\n' "${xopen}" >> .config.mk fi elif [ -n "${posix}" ]; then printf 'CFLAGS=-D_POSIX_C_SOURCE=%d\n' "${posix}" >> .config.mk fi ### generate .build.mk cat < .build.mk .POSIX: # work-around GNU ar's default "deterministic" mode ARFLAGS=rvU default: all include .config.mk include \$(TOPDIR)/.deps.mk EOF rm -f .build.all.mk for lib in $(ls $(dirname $0)/.deps/lib* | sed -e 's#^.*/\(lib.*\)\..*$#\1#g' | grep -v '\.h$' | sort -u); do printf '%s.a:' "${lib}" for cver in $(ls $(dirname $0)/.deps/${lib}.C_* 2>/dev/null | sed -e 's#^.*\.C_##g'); do if [ $cver -le ${standard_c:-1} ]; then printf ' $(%s_C_%d_OBJS)' "${lib}" "${cver}" printf '%s\n' "${lib}" >> .build.all.mk fi done for pver in $(ls $(dirname $0)/.deps/${lib}.POSIX_* 2>/dev/null | sed -e 's#^.*\.POSIX_##g'); do if [ $pver -le ${posix:-0} ]; then printf ' $(%s_POSIX_%d_OBJS)' "${lib}" "${pver}" printf '%s\n' "${lib}" >> .build.all.mk fi done for xver in $(ls $(dirname $0)/.deps/${lib}.XOPEN_* 2>/dev/null | sed -e 's#^.*\.XOPEN_##g'); do if [ $xver -le ${xopen:-0} ]; then printf ' $(%s_XOPEN_%d_OBJS)' "${lib}" "${xver}" printf '%s\n' "${lib}" >> .build.all.mk fi done printf '\n\t$(AR) $(ARFLAGS) $@ $?\n\n' done >> .build.mk printf 'all:' >> .build.mk sort -u .build.all.mk | awk '{printf(" %s.a", $0);}' >> .build.mk printf '\n' >> .build.mk rm -f .build.all.mk for i in $libs; do echo $i done >> .build.mk ### generate main Makefile ### FIXME: this can probably be kept as a fixed file cat < Makefile .POSIX: .DEFAULT:;\$(MAKE) all include .config.mk all: \$(TOPDIR)/.deps.mk \$(INCDIR) @mkdir -p \$(OBJDIR) \$(MAKE) -f .build.mk deps: \$(TOPDIR)/.headers.mk \$(TOPDIR)/.deps.mk \$(TOPDIR)/.deps.mk: \$(TOPDIR)/mk.sh sh -c '. \$(TOPDIR)/mk.sh; cd \$(TOPDIR); make_deps_mk' \$(TOPDIR)/.headers.mk: \$(TOPDIR)/mk.sh sh -c '. \$(TOPDIR)/mk.sh; cd \$(TOPDIR); make_headers_mk' headers \$(INCDIR): \$(TOPDIR)/.headers.mk \$(TOPDIR)/mkh.sh \$(MAKE) -f \$(TOPDIR)/.headers.mk headers ctags: ctags \$\$(find src -name \*.c) clean: rm -rf \$(OBJDIR) *.a extra-clean: clean rm -rf .deps .deps.mk .headers.mk \$(INCDIR) EOF