Fri, 23 May 2025 12:44:24 +0200
make test-compile depend on both static and shared
the shared lib is not needed for the tests,
but when run with coverage, gcov will be confused
when outdated line information is available from
a previous shared build
#!/bin/sh #set( $D = '$' ) #[[ # some utility functions isplatform() { for p in $PLATFORM do if [ "$p" = "$1" ]; then return 0 fi done return 1 } notisplatform() { for p in $PLATFORM do if [ "$p" = "$1" ]; then return 1 fi done return 0 } istoolchain() { for t in $TOOLCHAIN do if [ "$t" = "$1" ]; then return 0 fi done return 1 } notistoolchain() { for t in $TOOLCHAIN do if [ "$t" = "$1" ]; then return 1 fi done return 0 } # clean abort abort_configure() { rm -Rf "$TEMP_DIR" exit 1 } # Test for availability of pkg-config PKG_CONFIG=`command -v pkg-config` : ${PKG_CONFIG:="false"} # Simple uname based platform detection # $PLATFORM is used for platform dependent dependency selection OS=`uname -s` OS_VERSION=`uname -r` printf "detect platform... " if [ "$OS" = "SunOS" ]; then PLATFORM="solaris sunos unix svr4" elif [ "$OS" = "Linux" ]; then PLATFORM="linux unix" elif [ "$OS" = "FreeBSD" ]; then PLATFORM="freebsd bsd unix" elif [ "$OS" = "OpenBSD" ]; then PLATFORM="openbsd bsd unix" elif [ "$OS" = "NetBSD" ]; then PLATFORM="netbsd bsd unix" elif [ "$OS" = "Darwin" ]; then PLATFORM="macos osx bsd unix" elif echo "$OS" | grep -i "MINGW" > /dev/null; then PLATFORM="windows mingw" fi : ${PLATFORM:="unix"} PLATFORM_NAME=`echo "$PLATFORM" | cut -f1 -d' ' -` echo "$PLATFORM_NAME" ]]# # help text printhelp() { echo "Usage: $0 [OPTIONS]..." cat << __EOF__ Installation directories: --prefix=PREFIX path prefix for architecture-independent files [${D}prefix] --exec-prefix=EPREFIX path prefix for architecture-dependent files [PREFIX] --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR system configuration files [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR run-time variable data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --mandir=DIR man documentation [DATAROOTDIR/man] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] Build Types: --debug add extra compile flags for debug builds --release add extra compile flags for release builds #if( $options.size() > 0 ) Options: #foreach( $opt in $options ) --${opt.argument}=${opt.valuesString} #end #end #if( $features.size() > 0 ) Optional Features: #foreach( $feature in $features ) ${feature.helpText} #end #end __EOF__ } # create temporary directory TEMP_DIR=".tmp-`uname -n`" rm -Rf "$TEMP_DIR" if mkdir -p "$TEMP_DIR"; then : else echo "Cannot create tmp dir $TEMP_DIR" echo "Abort" exit 1 fi touch "$TEMP_DIR/options" touch "$TEMP_DIR/features" # define standard variables # also define standard prefix (this is where we will search for config.site) prefix=/usr exec_prefix= bindir= sbindir= libdir= libexecdir= datarootdir= datadir= sysconfdir= sharedstatedir= localstatedir= runstatedir= includedir= infodir= localedir= mandir= # custom variables #foreach( $cfg in $config ) if true \ #if( $cfg.platform ) && isplatform "${cfg.platform}" \ #end #foreach( $np in $cfg.notList ) && notisplatform "${np}" \ #end ; then #foreach( $var in $cfg.vars ) #if( $var.exec ) ${var.varName}=`${var.value}` #else ${var.varName}="${var.value}" #end #end fi #end # features #foreach( $feature in $features ) #if( ${feature.auto} ) ${feature.varName}=auto #end #end # # parse arguments # BUILD_TYPE="default" for ARG in "$@" do case "$ARG" in "--prefix="*) prefix=${D}{ARG#--prefix=} ;; "--exec-prefix="*) exec_prefix=${D}{ARG#--exec-prefix=} ;; "--bindir="*) bindir=${D}{ARG#----bindir=} ;; "--sbindir="*) sbindir=${D}{ARG#--sbindir=} ;; "--libdir="*) libdir=${D}{ARG#--libdir=} ;; "--libexecdir="*) libexecdir=${D}{ARG#--libexecdir=} ;; "--datarootdir="*) datarootdir=${D}{ARG#--datarootdir=} ;; "--datadir="*) datadir=${D}{ARG#--datadir=} ;; "--sysconfdir="*) sysconfdir=${D}{ARG#--sysconfdir=} ;; "--sharedstatedir="*) sharedstatedir=${D}{ARG#--sharedstatedir=} ;; "--localstatedir="*) localstatedir=${D}{ARG#--localstatedir=} ;; "--includedir="*) includedir=${D}{ARG#--includedir=} ;; "--infodir="*) infodir=${D}{ARG#--infodir=} ;; "--mandir"*) mandir=${D}{ARG#--mandir} ;; "--localedir"*) localedir=${D}{ARG#--localedir} ;; "--help"*) printhelp; abort_configure ;; "--debug") BUILD_TYPE="debug" ;; "--release") BUILD_TYPE="release" ;; #foreach( $opt in $options ) "--${opt.argument}="*) ${opt.varName}=${D}{ARG#--${opt.argument}=} ;; "--${opt.argument}") echo "option '$ARG' needs a value:"; echo " $ARG=${opt.valuesString}"; abort_configure ;; #end #foreach( $feature in $features ) "--enable-${feature.arg}") ${feature.varName}=on ;; "--disable-${feature.arg}") unset ${feature.varName} ;; #end "-"*) echo "unknown option: $ARG"; abort_configure ;; esac done ## Begin unparsed content. ** #[[ # set defaults for dir variables : ${exec_prefix:="$prefix"} : ${bindir:='${exec_prefix}/bin'} : ${sbindir:='${exec_prefix}/sbin'} : ${libdir:='${exec_prefix}/lib'} : ${libexecdir:='${exec_prefix}/libexec'} : ${datarootdir:='${prefix}/share'} : ${datadir:='${datarootdir}'} : ${sysconfdir:='${prefix}/etc'} : ${sharedstatedir:='${prefix}/com'} : ${localstatedir:='${prefix}/var'} : ${runstatedir:='${localstatedir}/run'} : ${includedir:='${prefix}/include'} : ${infodir:='${datarootdir}/info'} : ${mandir:='${datarootdir}/man'} : ${localedir:='${datarootdir}/locale'} # remember the above values and compare them later orig_bindir="$bindir" orig_sbindir="$sbindir" orig_libdir="$libdir" orig_libexecdir="$libexecdir" orig_datarootdir="$datarootdir" orig_datadir="$datadir" orig_sysconfdir="$sysconfdir" orig_sharedstatedir="$sharedstatedir" orig_localstatedir="$localstatedir" orig_runstatedir="$runstatedir" orig_includedir="$includedir" orig_infodir="$infodir" orig_mandir="$mandir" orig_localedir="$localedir" # check if a config.site exists and load it if [ -n "$CONFIG_SITE" ]; then # CONFIG_SITE may contain space separated file names for cs in $CONFIG_SITE; do printf "loading defaults from $cs... " . "$cs" echo ok done elif [ -f "$prefix/share/config.site" ]; then printf "loading site defaults... " . "$prefix/share/config.site" echo ok elif [ -f "$prefix/etc/config.site" ]; then printf "loading site defaults... " . "$prefix/etc/config.site" echo ok fi ]]# ## End of unparsed content ** # generate vars.mk cat > "$TEMP_DIR/vars.mk" << __EOF__ prefix=$prefix exec_prefix=$exec_prefix bindir=$bindir sbindir=$sbindir libdir=$libdir libexecdir=$libexecdir datarootdir=$datarootdir datadir=$datadir sysconfdir=$sysconfdir sharedstatedir=$sharedstatedir localstatedir=$localstatedir runstatedir=$runstatedir includedir=$includedir infodir=$infodir mandir=$mandir localedir=$localedir #foreach( $var in $vars ) ${var.varName}=${D}${var.varName} #end __EOF__ # toolchain detection utilities . make/toolchain.sh # # DEPENDENCIES # # check languages lang_c= lang_cpp= #foreach( $lang in $languages ) if detect_${lang}_compiler ; then lang_${lang}=1 fi #end # create buffer for make variables required by dependencies echo > "$TEMP_DIR/make.mk" test_pkg_config() { if "$PKG_CONFIG" --exists "$1" ; then : else return 1 ; fi if [ -z "$2" ] || "$PKG_CONFIG" --atleast-version="$2" "$1" ; then : else return 1 ; fi if [ -z "$3" ] || "$PKG_CONFIG" --exact-version="$3" "$1" ; then : else return 1 ; fi if [ -z "$4" ] || "$PKG_CONFIG" --max-version="$4" "$1" ; then : else return 1 ; fi return 0 } print_check_msg() { if [ -z "$1" ]; then shift printf "$@" fi } #foreach( $dependency in $namedDependencies ) dependency_error_${dependency.id}() { print_check_msg "${D}dep_checked_${dependency.id}" "checking for ${dependency.name}... " #foreach( $sub in $dependency.subdependencies ) # dependency $sub.fullName while true do #if( $sub.platform ) if notisplatform "${sub.platform}"; then break fi #end #if( $sub.toolchain ) if notistoolchain "${sub.toolchain}"; then break fi #end #foreach( $np in $sub.notList ) if isplatform "${np}" || istoolchain "${np}"; then break fi #end #foreach( $lang in $sub.lang ) if [ -z "$lang_${lang}" ] ; then break fi #end #if( $sub.pkgconfig.size() > 0 ) if [ -z "$PKG_CONFIG" ]; then break fi #end #foreach( $test in $sub.tests ) if $test > /dev/null ; then : else break fi #end #foreach( $pkg in $sub.pkgconfig ) if test_pkg_config "$pkg.name" "$pkg.atleast" "$pkg.exact" "$pkg.max" ; then TEMP_CFLAGS="$TEMP_CFLAGS `"$PKG_CONFIG" --cflags $pkg.name`" TEMP_LDFLAGS="$TEMP_LDFLAGS `"$PKG_CONFIG" --libs $pkg.name`" else break fi #end #foreach( $flags in $sub.flags ) #if( $flags.exec ) if tmp_flags=`$flags.value` ; then TEMP_$flags.varName="$TEMP_$flags.varName $tmp_flags" else break fi #else TEMP_$flags.varName="$TEMP_$flags.varName $flags.value" #end #end #if ( $sub.make.length() > 0 ) cat >> $TEMP_DIR/make.mk << __EOF__ # Dependency: $dependency.name $sub.make __EOF__ #end print_check_msg "${D}dep_checked_${dependency.id}" "yes\n" dep_checked_${dependency.id}=1 return 1 done #end print_check_msg "${D}dep_checked_${dependency.id}" "no\n" dep_checked_${dependency.id}=1 return 0 } #end # start collecting dependency information echo > "$TEMP_DIR/flags.mk" DEPENDENCIES_FAILED= ERROR=0 #if( $dependencies.size() > 0 ) # unnamed dependencies TEMP_CFLAGS="$CFLAGS" TEMP_CXXFLAGS="$CXXFLAGS" TEMP_LDFLAGS="$LDFLAGS" #foreach( $dependency in $dependencies ) while true do #if( $dependency.platform ) if notisplatform "${dependency.platform}"; then break fi #end #if( $dependency.toolchain ) if notistoolchain "${dependency.toolchain}"; then break fi #end #foreach( $np in $dependency.notList ) if isplatform "${np}" || istoolchain "${np}"; then break fi #end while true do #foreach( $lang in $dependency.lang ) if [ -z "$lang_${lang}" ] ; then ERROR=1 break fi #end #if( $dependency.pkgconfig.size() > 0 ) if [ -z "$PKG_CONFIG" ]; then ERROR=1 break fi #end #foreach( $pkg in $dependency.pkgconfig ) print_check_msg "${D}dep_pkgconfig_checked_${pkg.id}" "checking for pkg-config package $pkg.name... " if test_pkg_config "$pkg.name" "$pkg.atleast" "$pkg.exact" "$pkg.max" ; then print_check_msg "${D}dep_pkgconfig_checked_${pkg.id}" "yes\n" dep_pkgconfig_checked_${pkg.id}=1 TEMP_CFLAGS="$TEMP_CFLAGS `"$PKG_CONFIG" --cflags $pkg.name`" TEMP_LDFLAGS="$TEMP_LDFLAGS `"$PKG_CONFIG" --libs $pkg.name`" else print_check_msg "${D}dep_pkgconfig_checked_${pkg.id}" "no\n" dep_pkgconfig_checked_${pkg.id}=1 ERROR=1 break fi #end #foreach( $flags in $dependency.flags ) #if( $flags.exec ) $flags.value > /dev/null if tmp_flags=`$flags.value` ; then TEMP_$flags.varName="$TEMP_$flags.varName $tmp_flags" else ERROR=1 break fi #else TEMP_$flags.varName="$TEMP_$flags.varName $flags.value" #end #end #if ( $dependency.make.length() > 0 ) cat >> "$TEMP_DIR/make.mk" << __EOF__ $dependency.make __EOF__ #end break done break done #end # build type if [ "$BUILD_TYPE" = "debug" ]; then TEMP_CFLAGS="\${DEBUG_CFLAGS}$TEMP_CFLAGS" TEMP_CXXFLAGS="\${DEBUG_CXXFLAGS}$TEMP_CXXFLAGS" fi if [ "$BUILD_TYPE" = "release" ]; then TEMP_CFLAGS="\${RELEASE_CFLAGS}$TEMP_CFLAGS" TEMP_CXXFLAGS="\${RELEASE_CXXFLAGS}$TEMP_CXXFLAGS" fi # add general dependency flags to flags.mk echo "# general flags" >> "$TEMP_DIR/flags.mk" if [ -n "${TEMP_CFLAGS}" ] && [ -n "$lang_c" ]; then echo "CFLAGS += $TEMP_CFLAGS" >> "$TEMP_DIR/flags.mk" fi if [ -n "${TEMP_CXXFLAGS}" ] && [ -n "$lang_cpp" ]; then echo "CXXFLAGS += $TEMP_CXXFLAGS" >> "$TEMP_DIR/flags.mk" fi if [ -n "${TEMP_LDFLAGS}" ]; then echo "LDFLAGS += $TEMP_LDFLAGS" >> "$TEMP_DIR/flags.mk" fi #end # # OPTION VALUES # #foreach( $opt in $options ) #foreach( $val in $opt.values ) ${val.func}() { VERR=0 #foreach( $dep in $val.dependencies ) if dependency_error_$dep ; then VERR=1 fi #end if [ $VERR -ne 0 ]; then return 1 fi #foreach( $def in $val.defines ) TEMP_CFLAGS="$TEMP_CFLAGS ${def.toFlags()}" TEMP_CXXFLAGS="$TEMP_CXXFLAGS ${def.toFlags()}" #end #if( $val.hasMake() ) cat >> "$TEMP_DIR/make.mk" << __EOF__ $val.make __EOF__ #end return 0 } #end #end # # TARGETS # #foreach( $target in $targets ) echo >> "$TEMP_DIR/flags.mk" #if ( $target.name ) echo "configuring target: $target.name" echo "# flags for target $target.name" >> "$TEMP_DIR/flags.mk" #else echo "configuring global target" echo "# flags for unnamed target" >> "$TEMP_DIR/flags.mk" #end TEMP_CFLAGS= TEMP_CXXFLAGS= TEMP_LDFLAGS= #foreach( $dependency in $target.dependencies ) if dependency_error_$dependency; then DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED ${dependency} " ERROR=1 fi #end # Features #foreach( $feature in $target.features ) if [ -n "${D}${feature.varName}" ]; then #foreach( $dependency in $feature.dependencies ) # check dependency if dependency_error_$dependency ; then # "auto" features can fail and are just disabled in this case if [ "${D}${feature.varName}" = "auto" ]; then DISABLE_${feature.varName}=1 else DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED ${dependency} " ERROR=1 fi fi #end if [ -n "$DISABLE_${feature.varName}" ]; then unset ${feature.varName} fi fi if [ -n "${D}${feature.varName}" ]; then : #foreach( $def in $feature.defines ) TEMP_CFLAGS="$TEMP_CFLAGS ${def.toFlags()}" TEMP_CXXFLAGS="$TEMP_CXXFLAGS ${def.toFlags()}" #end #if( $feature.hasMake() ) cat >> "$TEMP_DIR/make.mk" << __EOF__ $feature.make __EOF__ #end else : #foreach( $def in $feature.disabled.defines ) TEMP_CFLAGS="$TEMP_CFLAGS ${def.toFlags()}" TEMP_CXXFLAGS="$TEMP_CXXFLAGS ${def.toFlags()}" #end #if( $feature.disabled.hasMake() ) cat >> "$TEMP_DIR/make.mk" << __EOF__ $feature.disabled.make __EOF__ #end #foreach( $dependency in $feature.disabled.dependencies ) if dependency_error_$dependency ; then DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED ${dependency} " ERROR=1 fi #end fi #end #foreach( $opt in $target.options ) # Option: --${opt.argument} if [ -z "${D}${opt.varName}" ]; then echo "auto-detecting option '${opt.argument}'" SAVED_ERROR="$ERROR" SAVED_DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED" ERROR=1 while true do #foreach( $optdef in $opt.defaults ) #if( $optdef.platform ) if isplatform "$optdef.platform"; then #end if $optdef.func ; then echo " ${opt.argument}: ${optdef.valueName}" >> "$TEMP_DIR/options" ERROR=0 break fi #if( $optdef.platform ) fi #end #end break done if [ $ERROR -ne 0 ]; then SAVED_ERROR=1 SAVED_DEPENDENCIES_FAILED="option '${opt.argument}' $SAVED_DEPENDENCIES_FAILED" fi ERROR="$SAVED_ERROR" DEPENDENCIES_FAILED="$SAVED_DEPENDENCIES_FAILED" else echo "checking option ${opt.argument} = ${D}${opt.varName}" if false; then false #foreach( $optval in $opt.values ) elif [ "${D}${opt.varName}" = "${optval.value}" ]; then echo " ${opt.argument}: ${D}${opt.varName}" >> $TEMP_DIR/options if $optval.func ; then : else ERROR=1 DEPENDENCIES_FAILED="option '${opt.argument}' $DEPENDENCIES_FAILED" fi #end else echo echo "Invalid option value - usage:" echo " --${opt.argument}=${opt.valuesString}" abort_configure fi fi #end if [ -n "${TEMP_CFLAGS}" ] && [ -n "$lang_c" ]; then echo "${target.cFlags} += $TEMP_CFLAGS" >> "$TEMP_DIR/flags.mk" fi if [ -n "${TEMP_CXXFLAGS}" ] && [ -n "$lang_cpp" ]; then echo "${target.cxxFlags} += $TEMP_CXXFLAGS" >> "$TEMP_DIR/flags.mk" fi if [ -n "${TEMP_LDFLAGS}" ]; then echo "${target.ldFlags} += $TEMP_LDFLAGS" >> "$TEMP_DIR/flags.mk" fi #end # final result if [ $ERROR -ne 0 ]; then echo echo "Error: Unresolved dependencies" echo "$DEPENDENCIES_FAILED" abort_configure fi echo "configure finished" echo echo "Toolchain" echo " name: $TOOLCHAIN_NAME" if [ -n "$TOOLCHAIN_CC" ]; then echo " cc: $TOOLCHAIN_CC" fi if [ -n "$TOOLCHAIN_CXX" ]; then echo " cxx: $TOOLCHAIN_CXX" fi if [ -n "$TOOLCHAIN_WSIZE" ]; then echo " word size: $TOOLCHAIN_WSIZE bit" fi if [ -n "$TOOLCHAIN_CSTD" ]; then echo " default C std: $TOOLCHAIN_CSTD" fi echo echo "Build Config:" echo " prefix: $prefix" echo " exec_prefix: $exec_prefix" if [ "$orig_bindir" != "$bindir" ]; then echo " bindir: $bindir" fi if [ "$orig_sbindir" != "$sbindir" ]; then echo " sbindir: $sbindir" fi if [ "$orig_libdir" != "$libdir" ]; then echo " libdir: $libdir" fi if [ "$orig_libexecdir" != "$libexecdir" ]; then echo " libexecdir: $libexecdir" fi if [ "$orig_datarootdir" != "$datarootdir" ]; then echo " datarootdir: $datarootdir" fi if [ "$orig_datadir" != "$datadir" ]; then echo " datadir: $datadir" fi if [ "$orig_sysconfdir" != "$sysconfdir" ]; then echo " sysconfdir: $sysconfdir" fi if [ "$orig_sharedstatedir" != "$sharedstatedir" ]; then echo " sharedstatedir: $sharedstatedir" fi if [ "$orig_localstatedir" != "$localstatedir" ]; then echo " localstatedir: $localstatedir" fi if [ "$orig_runstatedir" != "$runstatedir" ]; then echo " runstatedir: $runstatedir" fi if [ "$orig_includedir" != "$includedir" ]; then echo " includedir: $includedir" fi if [ "$orig_infodir" != "$infodir" ]; then echo " infodir: $infodir" fi if [ "$orig_mandir" != "$mandir" ]; then echo " mandir: $mandir" fi if [ "$orig_localedir" != "$localedir" ]; then echo " localedir: $localedir" fi #if ( $options.size() > 0 ) echo echo "Options:" cat "$TEMP_DIR/options" #end #if ( $features.size() > 0 ) echo echo "Features:" #foreach( $feature in $features ) if [ -n "${D}${feature.varName}" ]; then echo " $feature.name: on" else echo " $feature.name: off" fi #end #end echo # generate the config.mk file pwd=`pwd` cat > "$TEMP_DIR/config.mk" << __EOF__ # # config.mk generated by: # pwd: $pwd # $0 $@ # __EOF__ write_toolchain_defaults "$TEMP_DIR/toolchain.mk" cat "$TEMP_DIR/config.mk" "$TEMP_DIR/vars.mk" "$TEMP_DIR/toolchain.mk" "$TEMP_DIR/flags.mk" "$TEMP_DIR/make.mk" > config.mk rm -Rf "$TEMP_DIR"