#!/bin/sh ### Automatic build configuration script for Dinit. ### This script generates an "mconfig" file suitable for building on the current system. ## Initial preparation set -eu cd "$(dirname "$0")" ## Helper functions # According to POSIX, echo has some unspecified behavior in some cases, for example # when its first argument is "-n" or backslash ("\"). We prefer to rely on # POSIX documented things. # So we replace shell built-in echo with a printf based function. # For more info see http://www.etalabs.net/sh_tricks.html echo() { IFS=" " printf %s\\n "$*" } info() { echo "$*" } sub_info() { echo " ... $*" } error() { >&2 echo "Error: $*" exit 1 } sub_error() { >&2 echo " ... Error: $*" exit 1 } warning() { echo echo "Warning: $*" } sub_warning() { echo " ... $*" echo } cxx_works() { info Checking whether \""$1"\" is a working C++ compiler... if ! $CXX -o testfile.o testfile.cc; then rm -f testfile* sub_error It seems like \""$CXX"\" is not working a working C++ compiler. Please specify compiler. else rm -f testfile sub_info Yes. fi } try_cxx_argument() { info Checking whether the compiler accepts "$2"... if $CXX $CXXFLAGS $2 $CXXFLAGS_EXTRA $LDFLAGS $LDFLAGS_EXTRA testfile.cc -o testfile > /dev/null 2>&1; then rm testfile sub_info Yes. eval "$1=\"\${$1} \$2\"" eval "$1=\${$1# }" else if [ "$2" = "-std=c++11" ]; then sub_error "It seems like the C++ compiler don't support the (required) \"$2\" option!" else sub_info No. fi fi } try_ld_argument() { info Checking whether "$2" is accepted as a link-time option... if $CXX $CXXFLAGS $CXXFLAGS_EXTRA $LDFLAGS $LDFLAGS_EXTRA $2 testfile.cc -o testfile > /dev/null 2>&1; then sub_info Yes. eval "$1=\"\${$1} \$2\"" eval "$1=\${$1# }" else sub_info No. fi } try_both_argument() { info Checking whether the compiler/linker accept "$3"... if $CXX $CXXFLAGS $CXXFLAGS_EXTRA $LDFLAGS $LDFLAGS_EXTRA $3 testfile.cc -o testfile > /dev/null 2>&1; then sub_info Yes. eval "$1=\"\${$1} \$3\"" eval "$1=\${$1# }" eval "$2=\"\${$2} \$3\"" eval "$2=\${$2# }" else sub_info No. fi } usage() { cat << _EOF Usage: $0 [OPTION]... Generates build configuration for Dinit. Defaults for the options are specified in brackets. --help This help message. --quiet Don't print normal messages, just errors. --clean Clear mconfig and configure's temporary files. Target options: --platform=PLATFORM Set the platform manually (Just for cross-platform cross-compile!) [autodetected] Note: for all cross-compiles please specify correct CXX and CXX_FOR_BUILD! Installation directories: --prefix=PREFIX Main installation prefix [/usr] --exec-prefix=EPREFIX Main executables prefix [/] --sbindir=SBINDIR Dinit executables [EPREFIX/sbin] --mandir=MANDIR Dinit man-pages location [PREFIX/share/man] --syscontrolsocket=SOCKETPATH Dinitctl socket location [/run/dinitctl] on Linux systems [/var/run/dinitctl] on other systems Optional options: --shutdown-prefix=PREFIX Name prefix for shutdown, poweroff, reboot, halt programs [] --enable-shutdown Build shutdown, poweroff, reboot, halt programs [Enabled only on Linux systems] --disable-shutdown Don't build shutdown, poweroff, reboot, halt programs --enable-cgroups Enable Cgroups support [Enabled only on Linux based systems] --disable-cgroups Disable Cgroups support --enable-utmpx Enable manipulating the utmp/utmpx database via the related POSIX functions [auto] --disable-utmpx Disable manipulating the utmp/utmpx database via the related POSIX functions Build variables: Note: build variables can be passed in the environment, or as $0 argument (as "var=VALUE"). Note: CXXFLAGS, TEST_CXXFLAGS, LDFLAGS and TEST_LDFLAGS by default will be set to options considered suitable for the platform, filtered to remove any options not supported by the compiler/linker. To disable this, specify the values explicitly (an empty string is accepted). To add options without removing the defaults, set the variable with _EXTRA appended to the name (eg CXXFLAGS_EXTRA). CXX C++ compiler CXX_FOR_BUILD C++ compiler generating code for the build system (for cross-compiles). CXXFLAGS_FOR_BUILD Flags to use when generating code for the build system. Defaults to the value of CXXFLAGS. CPPFLAGS_FOR_BUILD Preprocessor flags to use when generating code for the build system. Defaults to the value of CPPFLAGS. LDFLAGS_FOR_BUILD Link flags to use when generating code for the build system. Defaults to the value of LDFLAGS. CXXFLAGS Flags to use when compiling C++ code. CXXFLAGS_EXTRA Additional flags to use when compiling C++ code. TEST_CXXFLAGS Flags to use when compiling C++ code in tests. TEST_CXXFLAGS_EXTRA Additional flags to use when compiling C++ code in tests. CPPFLAGS Preprocessor flags to use when compiling C++ code. LDFLAGS Link flags. LDFLAGS_EXTRA Additional link flags. TEST_LDFLAGS Links flags when building test executables. TEST_LDFLAGS_EXTRA Additional link flags when building test executables. Note: paths specified via --prefix/--exec-prefix/--sbindir/--mandir, and build variable values, must be escaped for use in a makefile and in shell commands. If there are spaces in paths it is recommended to prepend a backslash (\) to them. For example: ./configure --prefix="/home/my\ home" See BUILD file for more information. _EOF exit 0 } ## Don't take values from environment for these variables: for var in PREFIX \ EPREFIX \ SBINDIR \ MANDIR \ NO_SANITIZE \ SHUTDOWN_PREFIX \ BUILD_SHUTDOWN \ SUPPORT_CGROUPS \ SYSCONTROLSOCKET do unset $var done ## Flag parser for arg in "$@"; do case "$arg" in --help) usage ;; --quiet) info() { true; } sub_info() { true; } warning() { true; } sub_warning() { true; } ;; --clean) rm -f test* & rm -f mconfig && exit 0 ;; --platform=*) PLATFORM="${arg#*=}" && shift ;; --prefix=*) PREFIX="${arg#*=}" && shift ;; --exec-prefix=*) EPREFIX="${arg#*=}" && shift;; --sbindir=*) SBINDIR="${arg#*=}" && shift ;; --mandir=*) MANDIR="${arg#*=}" && shift ;; --syscontrolsocket=*) SYSCONTROLSOCKET="${arg#*=}" && shift ;; --shutdown-prefix=*) SHUTDOWN_PREFIX="${arg#*=}" && shift ;; --enable-shutdown|--enable-shutdown=yes) BUILD_SHUTDOWN=yes ;; --disable-shutdown|--enable-shutdown=no) BUILD_SHUTDOWN=no ;; --enable-cgroups|--enable-cgroups=yes) SUPPORT_CGROUPS=1 ;; --disable-cgroups|--enable-cgroups=no) SUPPORT_CGROUPS=0 ;; --enable-utmpx|--enable-utmpx=yes) USE_UTMPX=1 ;; --disable-utmpx|--enable-utmpx=no) USE_UTMPX=0 ;; CXX=*|CXX_FOR_BUILD=*|CXXFLAGS_FOR_BUILD=*|CPPFLAGS_FOR_BUILD=*\ |LDFLAGS_FOR_BUILD=*|CXXFLAGS=*|CXXFLAGS_EXTRA=*|TEST_CXXFLAGS=*\ |TEST_CXXFLAGS_EXTRA|LDFLAGS=*|LDFLAGS_EXTRA=*|TEST_LDFLAGS=*\ |TEST_LDFLAGS_EXTRA=*|CPPFLAGS=*) eval "${arg%%=*}=\${arg#*=}" ;; *=*) warning Unknown variable: "${arg%%=*}" ;; *) warning Unknown argument: "$arg" ;; esac done ## Defaults for variables not specified by user : "${PLATFORM:=$(uname)}" : "${PREFIX:="/usr"}" : "${EPREFIX:="/"}" : "${SBINDIR:="${EPREFIX%%/}/sbin"}" : "${MANDIR:="${PREFIX%%/}/share/man"}" : "${NO_SANITIZE:="auto"}" : "${SHUTDOWN_PREFIX:=""}" : "${CXXFLAGS_EXTRA:=""}" : "${TEST_CXXFLAGS_EXTRA:=""}" : "${CPPFLAGS:=""}" : "${LDFLAGS_EXTRA:=""}" : "${TEST_LDFLAGS_EXTRA:=""}" if [ "$PLATFORM" = "Linux" ]; then : "${BUILD_SHUTDOWN:="yes"}" : "${SUPPORT_CGROUPS:="1"}" : "${SYSCONTROLSOCKET:="/run/dinitctl"}" else : "${BUILD_SHUTDOWN:="no"}" : "${SUPPORT_CGROUPS:="0"}" : "${SYSCONTROLSOCKET:="/var/run/dinitctl"}" fi ## Finalize $CXXFLAGS, $TEST_CXXFLAGS, $LDFLAGS, $TEST_LDFLAGS if [ -z "${CXXFLAGS+IS_SET}" ]; then CXXFLAGS="" AUTO_CXXFLAGS="true" else AUTO_CXXFLAGS="false" fi if [ -z "${TEST_CXXFLAGS+IS_SET}" ]; then TEST_CXXFLAGS="" AUTO_TEST_CXXFLAGS="true" else AUTO_TEST_CXXFLAGS="false" fi if [ -z "${LDFLAGS+IS_SET}" ]; then LDFLAGS="" AUTO_LDFLAGS="true" else AUTO_LDFLAGS="false" fi if [ -z "${TEST_LDFLAGS+IS_SET}" ]; then TEST_LDFLAGS="" AUTO_TEST_LDFLAGS="true" else AUTO_TEST_LDFLAGS="false" fi ## Verify PLATFORM value if [ "$PLATFORM" != "Linux" ] && [ "$PLATFORM" != "FreeBSD" ] && \ [ "$PLATFORM" != "OpenBSD" ] && [ "$PLATFORM" != "Darwin" ]; then warning "$PLATFORM" platform is unknown! sub_warning Known Platforms are: Linux, FreeBSD, OpenBSD, Darwin fi ## Create testfile.cc to test c++ compiler echo "int main(int argc, char **argv) { return 0; }" > testfile.cc || error Can\'t create temporary file ## Find and test C++ compiler if [ -z "${CXX:-}" ]; then info Checking C++ compiler... for guess in g++ clang++ c++; do if type "$guess" > /dev/null 2>&1; then CXX="$guess" sub_info "$CXX" break # Found fi done if [ -z "${CXX:-}" ]; then sub_error No C++ compiler found! # Not found fi fi cxx_works "$CXX" if [ -n "${CXX_FOR_BUILD:-}" ]; then cxx_works "$CXX_FOR_BUILD" fi ## Test compiler/linker supported arguments if [ "$AUTO_CXXFLAGS" = "true" ]; then for argument in -std=c++11 \ -Wall \ -Os \ -fno-plt do try_cxx_argument CXXFLAGS $argument done if [ "$PLATFORM" != "Darwin" ]; then try_cxx_argument CXXFLAGS -fno-rtti fi fi if [ "$AUTO_LDFLAGS" = "true" ] && [ "$AUTO_CXXFLAGS" = "true" ]; then try_both_argument CXXFLAGS LDFLAGS -flto fi if [ "$AUTO_LDFLAGS" = "true" ] && [ "$PLATFORM" = "FreeBSD" ]; then try_ld_argument LDFLAGS -lrt fi # Add $CXXFLAGS and $LDFLAGS to $TEST_{LD,CXX}FLAGS when AUTO_TEST vars are true if [ "$AUTO_TEST_CXXFLAGS" = "true" ]; then TEST_CXXFLAGS="$CXXFLAGS" fi if [ "$AUTO_TEST_LDFLAGS" = "true" ]; then TEST_LDFLAGS="$LDFLAGS" fi if [ "$AUTO_TEST_LDFLAGS" = "true" ] && [ "$AUTO_TEST_CXXFLAGS" = "true" ]; then try_both_argument TEST_CXXFLAGS TEST_LDFLAGS -fsanitize=address,undefined fi ## Create mconfig rm -f testfile* info Creating mconfig... cat << _EOF > mconfig ## Auto-generated by "$0" for "$PLATFORM" # All changes will be lost if "$0" is re-run. # See BUILD for help on all variables. # Installation path options. SBINDIR=$SBINDIR MANDIR=$MANDIR SYSCONTROLSOCKET=$SYSCONTROLSOCKET # General build options. CXX=$CXX CXXFLAGS=$CXXFLAGS CXXFLAGS_EXTRA=$CXXFLAGS_EXTRA TEST_CXXFLAGS=$TEST_CXXFLAGS TEST_CXXFLAGS_EXTRA=$TEST_CXXFLAGS_EXTRA CPPFLAGS=$CPPFLAGS LDFLAGS=$LDFLAGS LDFLAGS_EXTRA=$LDFLAGS_EXTRA TEST_LDFLAGS=$TEST_LDFLAGS TEST_LDFLAGS_EXTRA=$TEST_LDFLAGS_EXTRA BUILD_SHUTDOWN=$BUILD_SHUTDOWN # Feature settings SUPPORT_CGROUPS=$SUPPORT_CGROUPS # Optional settings SHUTDOWN_PREFIX=${SHUTDOWN_PREFIX:-} _EOF if [ -n "${USE_UTMPX:-}" ]; then echo "USE_UTMPX=$USE_UTMPX" >> mconfig fi if [ -n "${CXX_FOR_BUILD:-}" ]; then { echo "" echo "# For cross-compiling" echo "CXX_FOR_BUILD=$CXX_FOR_BUILD" } >> mconfig fi if [ -n "${CXXFLAGS_FOR_BUILD:-}" ]; then echo "CXXFLAGS_FOR_BUILD=$CXXFLAGS_FOR_BUILD" >> mconfig fi if [ -n "${CPPFLAGS_FOR_BUILD:-}" ]; then echo "CPPFLAGS_FOR_BUILD=$CPPFLAGS_FOR_BUILD" >> mconfig fi if [ -n "${LDFLAGS_FOR_BUILD:-}" ]; then echo "LDFLAGS_FOR_BUILD=$LDFLAGS_FOR_BUILD" >> mconfig fi sub_info done. info Done! exit 0