#!/bin/sh # Copyright © Tavian Barnes <tavianator@tavianator.com> # SPDX-License-Identifier: 0BSD # bfs build configuration script set -eu # Get the relative path to the source tree based on how the script was run DIR=$(dirname -- "$0") # Print the help message help() { cat <<EOF Usage: \$ $0 [--enable-*|--disable-*] [--with-*|--without-*] [CC=...] [...] \$ $MAKE -j$(nproc) 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) --version=X.Y.Z Set the version string (default: $("$DIR/build/version.sh")) 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$(nproc) V=1 EOF } # 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 } # Get the number of cores to use nproc() { { command nproc \ || sysctl -n hw.ncpu \ || getconf _NPROCESSORS_ONLN \ || echo 1 } 2>/dev/null } # Save the ./configure command line for bfs --version export CONFFLAGS="$*" # Default to `make` MAKE="${MAKE-make}" # Parse the command-line arguments for arg; do shift # --[(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) help exit 0 ;; --enable-*|--disable-*) case "$name" in release|asan|lsan|msan|tsan|ubsan|lint|gcov) set -- "$@" "$NAME=$yn" ;; *) invalid "$arg" ;; esac ;; --with-*|--without-*) case "$name" in libacl|libcap|libselinux|liburing|oniguruma) set -- "$@" "WITH_$NAME=$yn" ;; *) invalid "$arg" ;; esac ;; --prefix=*|--mandir=*|--version=*) set -- "$@" "$NAME=$value" ;; --infodir=*|--build=*|--host=*|--target=*) printf 'warning: Ignoring option "%s"\n' "$arg" >&2 ;; MAKE=*) MAKE="$value" ;; # make flag (-j2) or variable (CC=clang) -*|*=*) set -- "$@" "$arg" ;; *) invalid "$arg" ;; esac done # 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$(nproc)}" $MAKE -rf build/config.mk "$@"