#!/bin/sh # Copyright © Tavian Barnes <tavianator@tavianator.com> # SPDX-License-Identifier: 0BSD # bfs build configuration script set -eu # Save the ./configure command line for bfs --version export CONFIG="$0 $*" # Default to `make` MAKE="${MAKE:-make}" # Pass -j$(nproc) unless MAKEFLAGS is set if [ "${MAKEFLAGS+y}" ]; then j="" else j="-j$({ nproc || sysctl -n hw.ncpu || getconf _NPROCESSORS_ONLN || echo 1; } 2>/dev/null)" fi # Convert kebab-case to UPPER_CASE toupper() { printf '%s' "$1" | tr 'a-z-' 'A-Z_' } # Report an argument parsing error invalid() { printf 'error: Unrecognized option "%s"\n\n' "$1" >&2 printf 'Run %s --help for more information.\n' "$0" >&2 exit 1 } for arg; do # --[(enable|disable|with|without)-]$name[=$value] value="${arg#*=}" name="${arg%%=*}" name="${name#--}" case "$arg" in --enable-*|--disable-*|--with-*|--without-*) name="${name#*-}" ;; esac NAME=$(printf '%s' "$name" | tr 'a-z-' 'A-Z_') # y/n modality case "$arg" in --enable-*|--with-*) case "$arg" in *=y|*=yes) yn=y ;; *=n|*=no) yn=n ;; *=*) invalid "$arg" ;; *) yn=y ;; esac ;; --disable-*|--without-*) case "$arg" in *=*) invalid "arg" ;; *) yn=n ;; esac ;; esac # Fix up --enable-lib* to --with-lib* case "$arg" in --enable-*|--disable-*) case "$name" in libacl|libcap|libselinux|liburing|oniguruma) old="$arg" case "$arg" in --enable-*) arg="--with-${arg#--*-}" ;; --disable-*) arg="--without-${arg#--*-}" ;; esac printf 'warning: Treating "%s" like "%s"\n' "$old" "$arg" >&2 ;; esac ;; esac case "$arg" in -h|--help) cat <<EOF Usage: \$ $0 [--enable-*|--disable-*] [--with-*|--without-*] [CC=...] [...] \$ $MAKE $j Variables set in the environment or on the command line will be picked up: MAKE The make implementation to use CC The C compiler to use CPPFLAGS="-I... -D..." CFLAGS="-W... -f..." LDFLAGS="-L... -Wl,..." Preprocessor/compiler/linker flags LDLIBS="-l... -l..." Dynamic libraries to link EXTRA_{CPPFLAGS,CFLAGS,LDFLAGS,LDLIBS} Adds to the default flags, instead of replacing them The default flags result in a plain debug build. Other build profiles include: --enable-release Enable optimizations, disable assertions --enable-{asan,lsan,msan,tsan,ubsan} Enable sanitizers --enable-gcov Enable code coverage instrumentation External dependencies are auto-detected by default, but you can build --with or --without them explicitly: --with-libacl --without-libacl --with-libcap --without-libcap --with-libselinux --without-libselinux --with-liburing --without-liburing --with-oniguruma --without-oniguruma Packaging: --prefix=/path Set the installation prefix (default: /usr) --mandir=/path Set the man page directory (default: \$PREFIX/share/man) This script is a thin wrapper around a makefile-based configuration system. Any other arguments will be passed directly to the $MAKE invocation, e.g. \$ $0 $j V=1 EOF exit 0 ;; --enable-*|--disable-*) case "$name" in release|asan|lsan|msan|tsan|ubsan|lint|gcov) shift set -- "$@" "$NAME=$yn" ;; *) invalid "$arg" ;; esac ;; --with-*|--without-*) case "$name" in libacl|libcap|libselinux|liburing|oniguruma) shift set -- "$@" "WITH_$NAME=$yn" ;; *) invalid "$arg" ;; esac ;; --prefix=*|--mandir=*) shift set -- "$@" "$NAME=$value" ;; --infodir=*|--build=*|--host=*|--target=*) shift printf 'warning: Ignoring option "%s"\n' "$arg" >&2 ;; MAKE=*) shift MAKE="$value" ;; # make flag (-j2) or variable (CC=clang) -*|*=*) continue ;; *) invalid "$arg" ;; esac done # Get the relative path to the source tree based on how the script was run DIR=$(dirname -- "$0") # Set up symbolic links for out-of-tree builds for f in Makefile build completions docs src tests; do test -e "$f" || ln -s "$DIR/$f" "$f" done # Set MAKEFLAGS to -j$(nproc) if it's unset export MAKEFLAGS="${MAKEFLAGS-$j}" $MAKE -rf build/config.mk "$@"