diff --git a/Makefile.am b/Makefile.am index d5bb7880f3..f581165d83 100644 --- a/Makefile.am +++ b/Makefile.am @@ -68,13 +68,14 @@ endif # tweak paths not using ${prefix} so `make distcheck` fails for it as # it does not play with a `DESTDIR` either. -DISTCHECK_FLAGS = --with-all --with-ssl --with-doc=auto --with-pynut=app --with-nut_monitor=force -DISTCHECK_LIGHT_FLAGS = --with-all=auto --with-ssl=auto --with-doc=auto --with-pynut=app --with-nut_monitor=force -DISTCHECK_LIGHT_MAN_FLAGS = --with-all=auto --with-ssl=auto --with-doc=man --with-pynut=app --with-nut_monitor=force -DISTCHECK_VALGRIND_FLAGS = --with-all=auto --with-ssl=auto --with-doc=skip --with-valgrind CXXFLAGS='$(CXXFLAGS) -g' CFLAGS='$(CFLAGS) -g' --with-pynut=app --with-nut_monitor=force +DISTCHECK_FLAGS = --with-all --with-ssl --with-doc=auto --with-pynut=app --with-nut_monitor=force CXXFLAGS='@NUT_CONFIG_CXXFLAGS@' CFLAGS='@NUT_CONFIG_CFLAGS@' CPPFLAGS='@NUT_CONFIG_CPPFLAGS@' LDFLAGS='@NUT_CONFIG_LDFLAGS@' +DISTCHECK_LIGHT_FLAGS = --with-all=auto --with-ssl=auto --with-doc=auto --with-pynut=app --with-nut_monitor=force CXXFLAGS='@NUT_CONFIG_CXXFLAGS@' CFLAGS='@NUT_CONFIG_CFLAGS@' CPPFLAGS='@NUT_CONFIG_CPPFLAGS@' LDFLAGS='@NUT_CONFIG_LDFLAGS@' +DISTCHECK_LIGHT_MAN_FLAGS = --with-all=auto --with-ssl=auto --with-doc=man --with-pynut=app --with-nut_monitor=force CXXFLAGS='@NUT_CONFIG_CXXFLAGS@' CFLAGS='@NUT_CONFIG_CFLAGS@' CPPFLAGS='@NUT_CONFIG_CPPFLAGS@' LDFLAGS='@NUT_CONFIG_LDFLAGS@' +DISTCHECK_VALGRIND_FLAGS = --with-all=auto --with-ssl=auto --with-doc=skip --with-valgrind CXXFLAGS='@NUT_CONFIG_CXXFLAGS@ -g' CFLAGS='@NUT_CONFIG_CFLAGS@ -g' CPPFLAGS='@NUT_CONFIG_CPPFLAGS@' LDFLAGS='@NUT_CONFIG_LDFLAGS@' --with-pynut=app --with-nut_monitor=force # Note: this rule uses envvar DISTCHECK_FLAGS expanded at run-time DISTCHECK_CONFIGURE_FLAGS = ${DISTCHECK_FLAGS} \ + PKG_CONFIG_PATH='@PKG_CONFIG_PATH@' \ --with-systemdsystemunitdir='$${prefix}/lib/systemd/system' \ --with-systemdsystempresetdir='$${prefix}/usr/lib/systemd/system-preset' \ --with-systemdshutdowndir='$${prefix}/lib/systemd/system-shutdown' \ @@ -90,15 +91,26 @@ DISTCHECK_CONFIGURE_FLAGS = ${DISTCHECK_FLAGS} \ # that is meaningful for sub-make program (gets stripped away # otherwise and breaks custom distchecks). distcheck-light: - +prefix='$${prefix}'; $(MAKE) $(AM_MAKEFLAGS) DISTCHECK_CONFIGURE_FLAGS="$(DISTCHECK_CONFIGURE_FLAGS)" DISTCHECK_FLAGS="$(DISTCHECK_LIGHT_FLAGS)" distcheck + +prefix='$${prefix}'; $(MAKE) $(AM_MAKEFLAGS) DISTCHECK_FLAGS="$(DISTCHECK_LIGHT_FLAGS)" distcheck distcheck-light-man: - +prefix='$${prefix}'; $(MAKE) $(AM_MAKEFLAGS) DISTCHECK_CONFIGURE_FLAGS="$(DISTCHECK_CONFIGURE_FLAGS)" DISTCHECK_FLAGS="$(DISTCHECK_LIGHT_MAN_FLAGS)" distcheck + +prefix='$${prefix}'; $(MAKE) $(AM_MAKEFLAGS) DISTCHECK_FLAGS="$(DISTCHECK_LIGHT_MAN_FLAGS)" distcheck + +if HAVE_VALGRIND +# Make the check in current build, if possible +memcheck: + @echo "See also scripts/valgrind in NUT sources for a helper tool" + +@cd $(builddir)/tests && $(MAKE) $(AM_MAKEFLAGS) -s $@ # Make a distcheck (and check in particular) with enabled valgrind and debug info +distcheck-valgrind: + @echo "See also scripts/valgrind in NUT sources for a helper tool" + +prefix='$${prefix}'; $(MAKE) $(AM_MAKEFLAGS) DISTCHECK_FLAGS="$(DISTCHECK_VALGRIND_FLAGS)" distcheck +else !HAVE_VALGRIND memcheck distcheck-valgrind: @echo "See also scripts/valgrind in NUT sources for a helper tool" - +prefix='$${prefix}'; $(MAKE) $(AM_MAKEFLAGS) DISTCHECK_CONFIGURE_FLAGS="$(DISTCHECK_CONFIGURE_FLAGS)" DISTCHECK_FLAGS="$(DISTCHECK_VALGRIND_FLAGS)" distcheck + @echo "SKIPPED $@ : valgrind was not detected on this system by configure script" >&2 +endif !HAVE_VALGRIND # workaround the dist generated files that are also part of the distribution # Note that distcleancheck is disabled for now, while waiting for a proper diff --git a/ci_build.sh b/ci_build.sh index bd05cb7a6e..9b3f88802f 100755 --- a/ci_build.sh +++ b/ci_build.sh @@ -189,11 +189,30 @@ fi [ -n "$MAKE_FLAGS_VERBOSE" ] || MAKE_FLAGS_VERBOSE="VERBOSE=1 V=1 -s" [ -n "$MAKE_FLAGS_CLEAN" ] || MAKE_FLAGS_CLEAN="${MAKE_FLAGS_QUIET}" -# This is where many symlinks like "gcc -> ../bin/ccache" reside -# (note: a "-" value requests to NOT use a CI_CCACHE_SYMLINKDIR; -# ccache may still be used via prefixing if the tool is found in -# the PATH, unless you export CI_CCACHE_USE=no also): +normalize_path() { + # STDIN->STDOUT: strip duplicate "/" and extra ":" if present, + # leave first copy of duplicates in (preferred) place + sed -e 's,:::*,:,g' -e 's,^:*,,' -e 's,:*$,,' -e 's,///*,/,g' \ + | tr ':' '\n' \ + | ( P="" + while IFS='' read D ; do + case "${D}" in + "") continue ;; + /) ;; + */) D="`echo "${D}" | sed 's,/*$,,'`" ;; + esac + case "${P}" in + "${D}"|*":${D}"|"${D}:"*|*":${D}:"*) ;; + "") P="${D}" ;; + *) P="${P}:${D}" ;; + esac + done + echo "${P}" + ) +} + propose_CI_CCACHE_SYMLINKDIR() { + # This is where many symlinks like "gcc -> ../bin/ccache" reside: echo \ "/usr/lib/ccache" \ "/mingw64/lib/ccache/bin" \ @@ -207,30 +226,270 @@ propose_CI_CCACHE_SYMLINKDIR() { echo "${HOMEBREW_PREFIX}/opt/ccache/libexec" fi } -if [ -z "${CI_CCACHE_SYMLINKDIR-}" ] ; then - for D in `propose_CI_CCACHE_SYMLINKDIR` ; do - if [ -d "$D" ] ; then - if ( ls -la "$D" | grep -e ' -> .*ccache' >/dev/null) \ - || ( test -n "`find "$D" -maxdepth 1 -type f -exec grep -li ccache '{}' \;`" ) \ - ; then - CI_CCACHE_SYMLINKDIR="$D" && break - else - echo "WARNING: Found potential CI_CCACHE_SYMLINKDIR='$D' but it did not host expected symlink patterns, skipped" >&2 + +ensure_CI_CCACHE_SYMLINKDIR_envvar() { + # Populate CI_CCACHE_SYMLINKDIR envvar (if not yet populated e.g. by caller) + # with location of symlinks like "gcc -> ../bin/ccache" to use + # NOTE: a caller-provided value of "-" requests the script to NOT use + # a CI_CCACHE_SYMLINKDIR; however ccache may still be used via prefixing + # to compiler command, if the tool is found in the PATH, e.g. by calling + # optional_ensure_ccache(), unless you export CI_CCACHE_USE=no also. + + if [ -z "${CI_CCACHE_SYMLINKDIR-}" ] ; then + for D in `propose_CI_CCACHE_SYMLINKDIR` ; do + if [ -d "$D" ] ; then + if ( ls -la "$D" | grep -e ' -> .*ccache' >/dev/null) \ + || ( test -n "`find "$D" -maxdepth 1 -type f -exec grep -li ccache '{}' \;`" ) \ + ; then + CI_CCACHE_SYMLINKDIR="$D" && break + else + echo "WARNING: Found potential CI_CCACHE_SYMLINKDIR='$D' but it did not host expected symlink patterns, skipped" >&2 + fi fi - fi - done + done - if [ -n "${CI_CCACHE_SYMLINKDIR-}" ] ; then - echo "INFO: Detected CI_CCACHE_SYMLINKDIR='$CI_CCACHE_SYMLINKDIR'; specify another explicitly if desired" >&2 + if [ -n "${CI_CCACHE_SYMLINKDIR-}" ] ; then + echo "INFO: Detected CI_CCACHE_SYMLINKDIR='$CI_CCACHE_SYMLINKDIR'; specify another explicitly if desired" >&2 + else + echo "WARNING: Did not find any CI_CCACHE_SYMLINKDIR; specify one explicitly if desired" >&2 + fi else - echo "WARNING: Did not find any CI_CCACHE_SYMLINKDIR; specify one explicitly if desired" >&2 + if [ x"${CI_CCACHE_SYMLINKDIR-}" = x- ] ; then + echo "INFO: Empty CI_CCACHE_SYMLINKDIR was explicitly requested" >&2 + CI_CCACHE_SYMLINKDIR="" + fi + fi +} + +optional_prepare_ccache() { + # Prepare CCACHE_* variables and directories, determine if we HAVE_CCACHE + # See also optional_ensure_ccache(), optional_prepare_compiler_family(), + # ensure_CI_CCACHE_SYMLINKDIR_envvar() + echo "PATH='$PATH' before possibly applying CCACHE into the mix" + ( echo "$PATH" | grep ccache ) >/dev/null && echo "WARNING: ccache is already in PATH" + if [ -n "$CC" ]; then + echo "CC='$CC' before possibly applying CCACHE into the mix" + $CC --version $CFLAGS || \ + $CC --version || true fi -else - if [ x"${CI_CCACHE_SYMLINKDIR-}" = x- ] ; then - echo "INFO: Empty CI_CCACHE_SYMLINKDIR was explicitly requested" >&2 + + if [ -n "$CXX" ]; then + echo "CXX='$CXX' before possibly applying CCACHE into the mix" + $CXX --version $CXXFLAGS || \ + $CXX --version || true + fi + + if [ x"${CI_CCACHE_USE-}" = xno ]; then + HAVE_CCACHE=no CI_CCACHE_SYMLINKDIR="" + echo "WARNING: Caller required to not use ccache even if available" >&2 + else + if [ -n "${CI_CCACHE_SYMLINKDIR}" ]; then + # Tell ccache the PATH without itself in it, to avoid loops processing + PATH="`echo "$PATH" | sed -e 's,^'"${CI_CCACHE_SYMLINKDIR}"'/?:,,' -e 's,:'"${CI_CCACHE_SYMLINKDIR}"'/?:,,' -e 's,:'"${CI_CCACHE_SYMLINKDIR}"'/?$,,' -e 's,^'"${CI_CCACHE_SYMLINKDIR}"'/?$,,'`" + fi + CCACHE_PATH="$PATH" + CCACHE_DIR="${HOME}/.ccache" + export CCACHE_PATH CCACHE_DIR PATH + HAVE_CCACHE=no + if (command -v ccache || which ccache) \ + && ( [ -z "${CI_CCACHE_SYMLINKDIR}" ] || ls -la "${CI_CCACHE_SYMLINKDIR}" ) \ + ; then + HAVE_CCACHE=yes + fi + mkdir -p "${CCACHE_DIR}"/ || HAVE_CCACHE=no fi -fi +} + +is_gnucc() { + if [ -n "$1" ] && LANG=C "$1" --version 2>&1 | grep 'Free Software Foundation' > /dev/null ; then true ; else false ; fi +} + +is_clang() { + if [ -n "$1" ] && LANG=C "$1" --version 2>&1 | grep 'clang version' > /dev/null ; then true ; else false ; fi +} + +filter_version() { + # Starting with number like "6.0.0" or "7.5.0-il-0" is fair game, + # but a "gcc-4.4.4-il-4" (starting with "gcc") is not + sed -e 's,^.* \([0-9][0-9]*\.[0-9][^ ),]*\).*$,\1,' -e 's, .*$,,' | grep -E '^[0-9]' | head -1 +} + +ver_gnucc() { + [ -n "$1" ] && LANG=C "$1" --version 2>&1 | grep -i gcc | filter_version +} + +ver_clang() { + [ -n "$1" ] && LANG=C "$1" --version 2>&1 | grep -i 'clang' | filter_version +} + +optional_prepare_compiler_family() { + # Populate CC, CXX, CPP envvars according to actual tools used/requested + # Remember them as COMPILER_FAMILY + # See also: optional_prepare_ccache(), ensure_CI_CCACHE_SYMLINKDIR_envvar(), + # optional_prepare_compiler_family() + COMPILER_FAMILY="" + if [ -n "$CC" -a -n "$CXX" ]; then + if is_gnucc "$CC" && is_gnucc "$CXX" ; then + COMPILER_FAMILY="GCC" + export CC CXX + elif is_clang "$CC" && is_clang "$CXX" ; then + COMPILER_FAMILY="CLANG" + export CC CXX + fi + else + # Generally we prefer GCC unless it is very old so we can't impact + # its warnings and complaints. + if is_gnucc "gcc" && is_gnucc "g++" ; then + # Autoconf would pick this by default + COMPILER_FAMILY="GCC" + [ -n "$CC" ] || CC=gcc + [ -n "$CXX" ] || CXX=g++ + export CC CXX + elif is_gnucc "cc" && is_gnucc "c++" ; then + COMPILER_FAMILY="GCC" + [ -n "$CC" ] || CC=cc + [ -n "$CXX" ] || CXX=c++ + export CC CXX + fi + + if ( [ "$COMPILER_FAMILY" = "GCC" ] && \ + case "`ver_gnucc "$CC"`" in + [123].*) true ;; + 4.[0123][.,-]*) true ;; + 4.[0123]) true ;; + *) false ;; + esac && \ + case "`ver_gnucc "$CXX"`" in + [123].*) true ;; + 4.[0123][.,-]*) true ;; + 4.[0123]) true ;; + *) false ;; + esac + ) ; then + echo "NOTE: default GCC here is very old, do we have a CLANG instead?.." >&2 + COMPILER_FAMILY="GCC_OLD" + fi + + if [ -z "$COMPILER_FAMILY" ] || [ "$COMPILER_FAMILY" = "GCC_OLD" ]; then + if is_clang "clang" && is_clang "clang++" ; then + # Autoconf would pick this by default + [ "$COMPILER_FAMILY" = "GCC_OLD" ] && CC="" && CXX="" + COMPILER_FAMILY="CLANG" + [ -n "$CC" ] || CC=clang + [ -n "$CXX" ] || CXX=clang++ + export CC CXX + elif is_clang "cc" && is_clang "c++" ; then + [ "$COMPILER_FAMILY" = "GCC_OLD" ] && CC="" && CXX="" + COMPILER_FAMILY="CLANG" + [ -n "$CC" ] || CC=cc + [ -n "$CXX" ] || CXX=c++ + export CC CXX + fi + fi + + if [ "$COMPILER_FAMILY" = "GCC_OLD" ]; then + COMPILER_FAMILY="GCC" + fi + fi + + if [ -n "$CPP" ] ; then + # Note: can be a multi-token name like "clang -E" or just not a full pathname + ( [ -x "$CPP" ] || $CPP --help >/dev/null 2>/dev/null ) && export CPP + else + # Avoid "cpp" directly as it may be too "traditional" + case "$COMPILER_FAMILY" in + CLANG*|GCC*) CPP="$CC -E" && export CPP ;; + *) if is_gnucc "cpp" ; then + CPP=cpp && export CPP + fi ;; + esac + fi +} + +optional_ensure_ccache() { + # Prepare PATH, CC, CXX envvars to use ccache (if enabled, applicable and available) + # See also optional_prepare_ccache() + if [ "$HAVE_CCACHE" = yes ] && [ "${COMPILER_FAMILY}" = GCC -o "${COMPILER_FAMILY}" = CLANG ]; then + if [ -n "${CI_CCACHE_SYMLINKDIR}" ]; then + echo "INFO: Using ccache via PATH preferring tool names in ${CI_CCACHE_SYMLINKDIR}" >&2 + PATH="${CI_CCACHE_SYMLINKDIR}:$PATH" + export PATH + else + case "$CC" in + "") ;; # skip + *ccache*) ;; # already requested to use ccache + *) CC="ccache $CC" ;; + esac + case "$CXX" in + "") ;; # skip + *ccache*) ;; # already requested to use ccache + *) CXX="ccache $CXX" ;; + esac + # No-op for CPP currently + fi + if [ -n "$CC" ] && [ -n "${CI_CCACHE_SYMLINKDIR}" ]; then + if [ -x "${CI_CCACHE_SYMLINKDIR}/`basename "$CC"`" ]; then + case "$CC" in + *ccache*) ;; + */*) DIR_CC="`dirname "$CC"`" && [ -n "$DIR_CC" ] && DIR_CC="`cd "$DIR_CC" && pwd `" && [ -n "$DIR_CC" ] && [ -d "$DIR_CC" ] || DIR_CC="" + [ -z "$CCACHE_PATH" ] && CCACHE_PATH="$DIR_CC" || \ + if echo "$CCACHE_PATH" | grep -E '(^'"$DIR_CC"':.*|^'"$DIR_CC"'$|:'"$DIR_CC"':|:'"$DIR_CC"'$)' ; then + CCACHE_PATH="$DIR_CC:$CCACHE_PATH" + fi + ;; + esac + CC="${CI_CCACHE_SYMLINKDIR}/`basename "$CC"`" + else + CC="ccache $CC" + fi + fi + if [ -n "$CXX" ] && [ -n "${CI_CCACHE_SYMLINKDIR}" ]; then + if [ -x "${CI_CCACHE_SYMLINKDIR}/`basename "$CXX"`" ]; then + case "$CXX" in + *ccache*) ;; + */*) DIR_CXX="`dirname "$CXX"`" && [ -n "$DIR_CXX" ] && DIR_CXX="`cd "$DIR_CXX" && pwd `" && [ -n "$DIR_CXX" ] && [ -d "$DIR_CXX" ] || DIR_CXX="" + [ -z "$CCACHE_PATH" ] && CCACHE_PATH="$DIR_CXX" || \ + if echo "$CCACHE_PATH" | grep -E '(^'"$DIR_CXX"':.*|^'"$DIR_CXX"'$|:'"$DIR_CXX"':|:'"$DIR_CXX"'$)' ; then + CCACHE_PATH="$DIR_CXX:$CCACHE_PATH" + fi + ;; + esac + CXX="${CI_CCACHE_SYMLINKDIR}/`basename "$CXX"`" + else + CXX="ccache $CXX" + fi + fi + if [ -n "$CPP" ] && [ -n "${CI_CCACHE_SYMLINKDIR}" ] \ + && [ -x "${CI_CCACHE_SYMLINKDIR}/`basename "$CPP"`" ]; then + case "$CPP" in + *ccache*) ;; + */*) DIR_CPP="`dirname "$CPP"`" && [ -n "$DIR_CPP" ] && DIR_CPP="`cd "$DIR_CPP" && pwd `" && [ -n "$DIR_CPP" ] && [ -d "$DIR_CPP" ] || DIR_CPP="" + [ -z "$CCACHE_PATH" ] && CCACHE_PATH="$DIR_CPP" || \ + if echo "$CCACHE_PATH" | grep -E '(^'"$DIR_CPP"':.*|^'"$DIR_CPP"'$|:'"$DIR_CPP"':|:'"$DIR_CPP"'$)' ; then + CCACHE_PATH="$DIR_CPP:$CCACHE_PATH" + fi + ;; + esac + CPP="${CI_CCACHE_SYMLINKDIR}/`basename "$CPP"`" + else + : # CPP="ccache $CPP" + fi + + CCACHE_BASEDIR="${PWD}" + export CCACHE_BASEDIR + + return 0 + fi + + # Not enabled or incompatible compiler + # Still, if ccache somehow gets used, let it + # know the correct BASEDIR of the built project + CCACHE_BASEDIR="${PWD}" + export CCACHE_BASEDIR + + return 1 +} if [ -z "$TMPDIR" ]; then echo "WARNING: TMPDIR not set, trying to guess" @@ -429,38 +688,43 @@ fi [ -n "$CI_OS_NAME" ] || CI_OS_NAME="$TRAVIS_OS_NAME" case "${CI_OS_NAME}" in - windows*) - # At the moment WIN32 builds are quite particular in their - # desires, for headers to declare what is needed, and yet - # there is currently not much real variation in supportable - # build environment (mingw variants). Lest we hardcode - # stuff in configure script, define some here: - case "$CFLAGS" in - *-D_POSIX=*) ;; - *) CFLAGS="$CFLAGS -D_POSIX=1" ;; - esac - case "$CFLAGS" in - *-D_POSIX_C_SOURCE=*) ;; - *) CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=200112L" ;; - esac - case "$CFLAGS" in - *-D_WIN32_WINNT=*) ;; - *) CFLAGS="$CFLAGS -D_WIN32_WINNT=0xffff" ;; - esac - - case "$CXXFLAGS" in - *-D_POSIX=*) ;; - *) CXXFLAGS="$CXXFLAGS -D_POSIX=1" ;; - esac - case "$CXXFLAGS" in - *-D_POSIX_C_SOURCE=*) ;; - *) CXXFLAGS="$CXXFLAGS -D_POSIX_C_SOURCE=200112L" ;; - esac - case "$CXXFLAGS" in - *-D_WIN32_WINNT=*) ;; - *) CXXFLAGS="$CXXFLAGS -D_WIN32_WINNT=0xffff" ;; - esac - ;; + windows-msys2) + # No-op: we seem to pass builds on MSYS2 anyway even without + # these flags, and a populated CFLAGS happens to be toxic to + # ccache builds in that distribution (as of 2022-2025 at least) + ;; + windows*) + # At the moment WIN32 builds are quite particular in their + # desires, for headers to declare what is needed, and yet + # there is currently not much real variation in supportable + # build environment (mingw variants). Lest we hardcode + # stuff in configure script, define some here: + case "$CFLAGS" in + *-D_POSIX=*) ;; + *) CFLAGS="$CFLAGS -D_POSIX=1" ;; + esac + case "$CFLAGS" in + *-D_POSIX_C_SOURCE=*) ;; + *) CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=200112L" ;; + esac + case "$CFLAGS" in + *-D_WIN32_WINNT=*) ;; + *) CFLAGS="$CFLAGS -D_WIN32_WINNT=0xffff" ;; + esac + + case "$CXXFLAGS" in + *-D_POSIX=*) ;; + *) CXXFLAGS="$CXXFLAGS -D_POSIX=1" ;; + esac + case "$CXXFLAGS" in + *-D_POSIX_C_SOURCE=*) ;; + *) CXXFLAGS="$CXXFLAGS -D_POSIX_C_SOURCE=200112L" ;; + esac + case "$CXXFLAGS" in + *-D_WIN32_WINNT=*) ;; + *) CXXFLAGS="$CXXFLAGS -D_WIN32_WINNT=0xffff" ;; + esac + ;; esac # Analyze some environmental choices @@ -475,37 +739,287 @@ if [ -z "${CANBUILD_LIBGD_CGI-}" ]; then # See also below for some compiler-dependent decisions fi -if [ -z "${PKG_CONFIG-}" ]; then - # Default to using one from PATH, if any - mostly for config tuning done - # below in this script - # DO NOT "export" it here so configure script can find one for the build - PKG_CONFIG="pkg-config" -fi - -# Would hold full path to the CONFIGURE_SCRIPT="${SCRIPTDIR}/${CONFIGURE_SCRIPT_FILENAME}" -CONFIGURE_SCRIPT="" -autogen_get_CONFIGURE_SCRIPT() { - # Autogen once (delete the file if some scenario ever requires to re-autogen) - if [ -n "${CONFIGURE_SCRIPT}" -a -s "${CONFIGURE_SCRIPT}" ] ; then return 0 ; fi - - pushd "${SCRIPTDIR}" || exit - - if [[ "$CI_OS_NAME" == "windows" ]] ; then - # Debug once - [ -n "$CONFIGURE_SCRIPT" ] || find . -ls - CONFIGURE_SCRIPT="configure.bat" - else - CONFIGURE_SCRIPT="configure" - fi - - if [ ! -s "./$CONFIGURE_SCRIPT" ]; then - # Note: modern auto(re)conf requires pkg-config to generate the configure - # script, so to stage the situation of building without one (as if on an - # older system) we have to remove it when we already have the script. - # This matches the use-case of distro-building from release tarballs that - # include all needed pre-generated files to rely less on OS facilities. - if [ "$CI_OS_NAME" = "windows" ] ; then - $CI_TIME ./autogen.sh || true +detect_platform_CANBUILD_LIBGD_CGI() { + # Call after optional_prepare_compiler_family()! + if [ -z "${CANBUILD_LIBGD_CGI-}" ]; then + if [[ "$CI_OS_NAME" = "openindiana" ]] ; then + # For some reason, here gcc-4.x (4.4.4, 4.9) have a problem with + # configure-time checks of libgd; newer compilers fare okay. + # Feel free to revise this if the distro packages are fixed + # (or the way configure script and further build uses them). + # UPDATE: Per https://github.com/networkupstools/nut/pull/1089 + # This is a systems issue (in current OpenIndiana 2021.04 built + # with a newer GCC version, the older GCC is not ABI compatible + # with the libgd shared object file). Maybe this warrants later + # caring about not just the CI_OS_NAME but also CI_OS_RELEASE... + if [[ "$COMPILER_FAMILY" = "GCC" ]]; then + case "`LANG=C $CC --version | head -1`" in + *[\ -][01234].*) + echo "WARNING: Seems we are running with gcc-4.x or older on $CI_OS_NAME, which last had known issues with libgd; disabling CGI for this build" + CANBUILD_LIBGD_CGI=no + ;; + *) + case "${ARCH}${BITS}${ARCH_BITS}" in + *64*|*sparcv9*) ;; + *) + # GCC-7 (maybe other older compilers) could default + # to 32-bit builds, and the 32-bit libfontconfig.so + # and libfreetype.so are absent for some years now + # (while libgd.so still claims to exist). + echo "WARNING: Seems we are running with gcc on $CI_OS_NAME, which last had known issues with libgd on non-64-bit builds; making CGI optional for this build" + CANBUILD_LIBGD_CGI=auto + ;; + esac + ;; + esac + else + case "${ARCH}${BITS}${ARCH_BITS}" in + *64*|*sparcv9*) ;; + *) + echo "WARNING: Seems we are running with $COMPILER_FAMILY on $CI_OS_NAME, which last had known issues with libgd on non-64-bit builds; making CGI optional for this build" + CANBUILD_LIBGD_CGI=auto + ;; + esac + fi + fi + fi +} + +if [ -z "${PKG_CONFIG-}" ]; then + # Default to using one from PATH, if any - mostly for config tuning done + # below in this script + # DO NOT "export" it here so configure script can find one for the build + PKG_CONFIG="pkg-config" +fi + +detect_platform_PKG_CONFIG_PATH_and_FLAGS() { + # Some systems want a custom PKG_CONFIG_PATH which would be prepended + # to whatever the callers might have provided as their PKG_CONFIG_PATH. + # Optionally provided by some CI build scenarios: DEFAULT_PKG_CONFIG_PATH + # On some platforms also barges in to CONFIG_OPTS[] (should exist!), + # PATH, CFLAGS, CXXFLAGS, LDFLAGS, XML_CATALOG_FILES et al. + # + # Caller can override by OVERRIDE_PKG_CONFIG_PATH (ignore other values + # then, including a PKG_CONFIG_PATH), where a "-" value leaves it empty. + SYS_PKG_CONFIG_PATH="" # Let the OS guess... usually + BUILTIN_PKG_CONFIG_PATH="`pkg-config --variable pc_path pkg-config`" || BUILTIN_PKG_CONFIG_PATH="" + case "`echo "$CI_OS_NAME" | tr 'A-Z' 'a-z'`" in + *openindiana*|*omnios*|*solaris*|*illumos*|*sunos*) + _ARCHES="${ARCH-}" + _BITS="${BITS-}" + _ISA1="" + + [ -n "${_BITS}" ] || \ + case "${CC}${CXX}${CFLAGS}${CXXFLAGS}${LDFLAGS}" in + *-m64*) _BITS=64 ;; + *-m32*) _BITS=32 ;; + *) case "${ARCH-}${ARCH_BITS-}" in + *64*|*sparcv9*) _BITS=64 ;; + *32*|*86*|*sparcv7*|*sparc) _BITS=32 ;; + *) _ISA1="`isainfo | awk '{print $1}'`" + case "${_ISA1}" in + *64*|*sparcv9*) _BITS=64 ;; + *32*|*86*|*sparcv7*|*sparc) _BITS=32 ;; + esac + ;; + esac + ;; + esac + + # Consider also `gcc -v`/`clang -v`: their "Target:" line exposes the + # triplet compiler was built to run on, e.g. "x86_64-pc-solaris2.11" + case "${_ARCHES}${ARCH_BITS-}" in + *amd64*|*x86_64*) _ARCHES="amd64" ;; + *sparcv9*) _ARCHES="sparcv9" ;; + *86*) _ARCHES="i86pc i386" ;; + *sparcv7*|*sparc) _ARCHES="sparcv7 sparc" ;; + *) [ -n "${_ISA1}" ] || _ISA1="`isainfo | awk '{print $1}'`" + case "${_ISA1}" in + *amd64*|*x86_64*) _ARCHES="amd64" ;; + *sparcv9*) _ARCHES="sparcv9" ;; + *86*) _ARCHES="i86pc i386" ;; + *sparcv7*|*sparc) _ARCHES="sparcv7 sparc" ;; + esac + ;; + esac + + # Pile it on, strip extra ":" and dedup entries later + for D in \ + "/opt/ooce/lib" \ + "/usr/lib" \ + ; do + if [ -d "$D" ] ; then + _ADDSHORT=false + if [ -n "${_BITS}" ] ; then + if [ -d "${D}/${_BITS}/pkgconfig" ] ; then + SYS_PKG_CONFIG_PATH="${SYS_PKG_CONFIG_PATH}:${D}/${_BITS}/pkgconfig" + # Here and below: hot-fix for https://github.com/networkupstools/nut/issues/2782 + # situation on OmniOS with Extra repository, + # assumed only useful if we use it via pkgconfig + case "${D}" in + /usr/lib) ;; + *) LDFLAGS="${LDFLAGS} -R${D}/${_BITS}" ;; + esac + else + if [ -d "${D}/pkgconfig" ] ; then + case "`LANG=C LC_ALL=C file $(ls -1 $D/*.so | head -1)`" in + *"ELF ${_BITS}-bit"*) _ADDSHORT=true ;; + esac + fi + fi + fi + for _ARCH in $_ARCHES ; do + if [ -d "${D}/${_ARCH}/pkgconfig" ] ; then + SYS_PKG_CONFIG_PATH="${SYS_PKG_CONFIG_PATH}:${D}/${_ARCH}/pkgconfig" + case "${D}" in + /usr/lib) ;; + *) LDFLAGS="${LDFLAGS} -R${D}/${_ARCH}" ;; + esac + else + if [ -d "${D}/pkgconfig" ] ; then + case "`LANG=C LC_ALL=C file $(ls -1 $D/*.so | head -1)`" in + *"ELF 32-bit"*" SPARC "*) + case "${_ARCH}" in + sparc|sparcv7) _ADDSHORT=true ;; + esac + ;; + *"ELF 64-bit"*" SPARCV9 "*) + case "${_ARCH}" in + sparcv9) _ADDSHORT=true ;; + esac + ;; + *"ELF 32-bit"*" 80386 "*) + case "${_ARCH}" in + i386|i86pc) _ADDSHORT=true ;; + esac + ;; + *"ELF 64-bit"*" AMD64 "*) + case "${_ARCH}" in + amd64) _ADDSHORT=true ;; + esac + ;; + esac + fi + fi + done + if [ "${_ADDSHORT}" = true ] ; then + SYS_PKG_CONFIG_PATH="${SYS_PKG_CONFIG_PATH}:${D}/pkgconfig" + case "${D}" in + /usr/lib) ;; + *) LDFLAGS="${LDFLAGS} -R${D}" ;; + esac + fi + fi + done + + # Last option if others are lacking + if [ -d /usr/lib/pkgconfig ] ; then + SYS_PKG_CONFIG_PATH="${SYS_PKG_CONFIG_PATH}:/usr/lib/pkgconfig" + fi + unset _ADDSHORT _BITS _ARCH _ARCHES D + + # OmniOS CE "Extra" repository + case "$PATH" in + /opt/ooce/bin|*:/opt/ooce/bin|/opt/ooce/bin:*|*:/opt/ooce/bin:*) ;; + *) if [ -d "/opt/ooce/bin" ] ; then PATH="/opt/ooce/bin:${PATH}" ; fi ;; + esac + ;; + *darwin*|*macos*|*osx*) + # Architecture-dependent base dir, e.g. + # * /usr/local on macos x86 + # * /opt/homebrew on macos Apple Silicon + if [ -n "${HOMEBREW_PREFIX-}" -a -d "${HOMEBREW_PREFIX-}" ]; then + echo "Homebrew: export general pkg-config location and C/C++/LD flags for the platform" + SYS_PKG_CONFIG_PATH="${HOMEBREW_PREFIX}/lib/pkgconfig" + CFLAGS="${CFLAGS-} -Wno-poison-system-directories -Wno-deprecated-declarations -isystem ${HOMEBREW_PREFIX}/include -I${HOMEBREW_PREFIX}/include" + #CPPFLAGS="${CPPFLAGS-} -Wno-poison-system-directories -Wno-deprecated-declarations -isystem ${HOMEBREW_PREFIX}/include -I${HOMEBREW_PREFIX}/include" + CXXFLAGS="${CXXFLAGS-} -Wno-poison-system-directories -isystem ${HOMEBREW_PREFIX}/include -I${HOMEBREW_PREFIX}/include" + LDFLAGS="${LDFLAGS-} -L${HOMEBREW_PREFIX}/lib" + + # Net-SNMP "clashes" with system-provided tools (but no header/lib) + # so explicit args are needed + checkFSobj="${HOMEBREW_PREFIX}/opt/net-snmp/lib/pkgconfig" + if [ -d "$checkFSobj" -a ! -e "${HOMEBREW_PREFIX}/lib/pkgconfig/netsnmp.pc" ] ; then + echo "Homebrew: export pkg-config location for Net-SNMP" + SYS_PKG_CONFIG_PATH="$SYS_PKG_CONFIG_PATH:$checkFSobj" + #echo "Homebrew: export flags for Net-SNMP" + #CONFIG_OPTS+=("--with-snmp-includes=-isystem ${HOMEBREW_PREFIX}/opt/net-snmp/include -I${HOMEBREW_PREFIX}/opt/net-snmp/include") + #CONFIG_OPTS+=("--with-snmp-libs=-L${HOMEBREW_PREFIX}/opt/net-snmp/lib") + fi + + if [ -d "${HOMEBREW_PREFIX}/opt/net-snmp/include" -a -d "${HOMEBREW_PREFIX}/include/openssl" ]; then + # TODO? Check netsnmp.pc for Libs.private with + # -L/opt/homebrew/opt/openssl@1.1/lib + # or + # -L/usr/local/opt/openssl@3/lib + # among other options to derive the exact version + # it wants, and serve that include path here + echo "Homebrew: export configure options for Net-SNMP with default OpenSSL headers (too intimate on Homebrew)" + CONFIG_OPTS+=("--with-snmp-includes=-isystem ${HOMEBREW_PREFIX}/opt/net-snmp/include -I${HOMEBREW_PREFIX}/opt/net-snmp/include -isystem ${HOMEBREW_PREFIX}/include -I${HOMEBREW_PREFIX}/include") + CONFIG_OPTS+=("--with-snmp-libs=-L${HOMEBREW_PREFIX}/opt/net-snmp/lib -lnetsnmp") + fi + + # A bit hackish to check this outside `configure`, but... + if [ -s "${HOMEBREW_PREFIX-}/include/ltdl.h" ] ; then + echo "Homebrew: export flags for LibLTDL" + # The m4 script clear default CFLAGS/LIBS so benefit from new ones + CONFIG_OPTS+=("--with-libltdl-includes=-isystem ${HOMEBREW_PREFIX}/include -I${HOMEBREW_PREFIX}/include") + CONFIG_OPTS+=("--with-libltdl-libs=-L${HOMEBREW_PREFIX}/lib -lltdl") + fi + + if [ -z "${XML_CATALOG_FILES-}" ] ; then + checkFSobj="${HOMEBREW_PREFIX}/etc/xml/catalog" + if [ -e "$checkFSobj" ] ; then + echo "Homebrew: export XML_CATALOG_FILES='$checkFSobj' for asciidoc et al" + XML_CATALOG_FILES="$checkFSobj" + export XML_CATALOG_FILES + fi + fi + else + echo "WARNING: It seems you are building on MacOS, but HOMEBREW_PREFIX is not set or valid." + echo 'If you do use this build system, try running eval "$(brew shellenv)"' + echo "in your terminal or shell profile, it can help with auto-detection of some features!" + fi + ;; + esac + + if [ -n "${OVERRIDE_PKG_CONFIG_PATH-}" ] ; then + if [ x"${OVERRIDE_PKG_CONFIG_PATH}" = x- ] ; then + PKG_CONFIG_PATH="" + else + PKG_CONFIG_PATH="${OVERRIDE_PKG_CONFIG_PATH}" + fi + return + fi + + # Do not check for existence of non-trivial values, we normalize the mess (if any) + PKG_CONFIG_PATH="`echo "${DEFAULT_PKG_CONFIG_PATH-}:${SYS_PKG_CONFIG_PATH-}:${PKG_CONFIG_PATH-}:${BUILTIN_PKG_CONFIG_PATH-}" | normalize_path`" +} + +# Would hold full path to the CONFIGURE_SCRIPT="${SCRIPTDIR}/${CONFIGURE_SCRIPT_FILENAME}" +CONFIGURE_SCRIPT="" +autogen_get_CONFIGURE_SCRIPT() { + # Autogen once (delete the file if some scenario ever requires to re-autogen) + if [ -n "${CONFIGURE_SCRIPT}" -a -s "${CONFIGURE_SCRIPT}" ] ; then return 0 ; fi + + pushd "${SCRIPTDIR}" || exit + + if [[ "$CI_OS_NAME" == "windows" ]] ; then + # Debug once + [ -n "$CONFIGURE_SCRIPT" ] || find . -ls + CONFIGURE_SCRIPT="configure.bat" + else + CONFIGURE_SCRIPT="configure" + fi + + if [ ! -s "./$CONFIGURE_SCRIPT" ]; then + # Note: modern auto(re)conf requires pkg-config to generate the configure + # script, so to stage the situation of building without one (as if on an + # older system) we have to remove it when we already have the script. + # This matches the use-case of distro-building from release tarballs that + # include all needed pre-generated files to rely less on OS facilities. + if [ "$CI_OS_NAME" = "windows" ] ; then + $CI_TIME ./autogen.sh || true else $CI_TIME ./autogen.sh ### 2>/dev/null fi || exit @@ -786,383 +1300,127 @@ optional_maintainer_clean_check() { GIT_ARGS="--ignored" check_gitignore "maintainer-clean" || return fi - - return 0 -} - -optional_dist_clean_check() { - if [ ! -e .git ]; then - echo "Skipping distclean check because there is no .git" >&2 - return 0 - fi - - if [ ! -e Makefile ]; then - echo "WARNING: Skipping distclean check because there is no Makefile (did we clean in a loop earlier?)" >&2 - return 0 - fi - - if [ "${DO_CLEAN_CHECK-}" = "no" ] || [ "${DO_DIST_CLEAN_CHECK-}" = "no" ] ; then - echo "Skipping distclean check because recipe/developer said so" - else - [ -z "$CI_TIME" ] || echo "`date`: Starting dist-clean check of currently tested project..." - - # Note: currently Makefile.am has just a dummy "distcleancheck" rule - $CI_TIME $MAKE DISTCHECK_FLAGS="$DISTCHECK_FLAGS" $PARMAKE_FLAGS $MAKE_FLAGS_CLEAN distclean || return - - check_gitignore "distclean" || return - fi - return 0 -} - -if [ "$1" = inplace ] && [ -z "$BUILD_TYPE" ] ; then - shift - BUILD_TYPE="inplace" -fi - -if [ "$1" = spellcheck -o "$1" = spellcheck-interactive ] && [ -z "$BUILD_TYPE" ] ; then - # Note: this is a little hack to reduce typing - # and scrolling in (docs) developer iterations. - case "$CI_OS_NAME" in - windows-msys2) - # https://github.com/msys2/MSYS2-packages/issues/2088 - echo "==========================================================================" - echo "WARNING: some MSYS2 builds of aspell are broken with 'tex' support" - echo "Are you sure you run this in a functional build environment? Ctrl+C if not" - echo "==========================================================================" - sleep 5 - ;; - *) if ! (command -v aspell) 2>/dev/null >/dev/null ; then - echo "==========================================================================" - echo "WARNING: Seems you do not have 'aspell' in PATH (but maybe NUT configure" - echo "script would find the spellchecking toolkit elsewhere)" - echo "Are you sure you run this in a functional build environment? Ctrl+C if not" - echo "==========================================================================" - sleep 5 - fi - ;; - esac >&2 - if [ -s Makefile ] && [ -s docs/Makefile ]; then - echo "Processing quick and quiet spellcheck with already existing recipe files, will only report errors if any ..." - build_to_only_catch_errors_target $1 ; exit - else - # TODO: Actually do it (default-spellcheck-interactive)? - if [ "$1" = spellcheck-interactive ] ; then - echo "Only CI-building 'spellcheck', please do the interactive part manually if needed" >&2 - fi - BUILD_TYPE="default-spellcheck" - shift - fi -fi - -echo "Processing BUILD_TYPE='${BUILD_TYPE}' ..." - -echo "Build host settings:" -set | grep -E '^(PATH|[^ ]*CCACHE[^ ]*|CI_[^ ]*|OS_[^ ]*|CANBUILD_[^ ]*|NODE_LABELS|MAKE|C[^ ]*FLAGS|LDFLAGS|ARCH[^ ]*|BITS[^ ]*|CC|CXX|CPP|DO_[^ ]*|BUILD_[^ ]*)=' || true -uname -a -echo "LONG_BIT:`getconf LONG_BIT` WORD_BIT:`getconf WORD_BIT`" || true -if command -v xxd >/dev/null ; then xxd -c 1 -l 6 | tail -1; else if command -v od >/dev/null; then od -N 1 -j 5 -b | head -1 ; else hexdump -s 5 -n 1 -C | head -1; fi; fi < /bin/ls 2>/dev/null | awk '($2 == 1){print "Endianness: LE"}; ($2 == 2){print "Endianness: BE"}' || true - -case "$BUILD_TYPE" in -default|default-alldrv|default-alldrv:no-distcheck|default-all-errors|default-spellcheck|default-shellcheck|default-nodoc|default-withdoc|default-withdoc:man|"default-tgt:"*) - LANG=C - LC_ALL=C - export LANG LC_ALL - - if [ -d "./tmp/" ]; then - rm -rf ./tmp/ - fi - if [ -d "./.inst/" ]; then - rm -rf ./.inst/ - fi - - # Pre-create locations; tmp/lib in particular to avoid (on MacOS xcode): - # ld: warning: directory not found for option '-L/Users/distiller/project/tmp/lib' - # Note that maintainer-clean checks can remove these directory trees, - # so we re-create them just in case in the configure_nut() method too. - mkdir -p tmp/lib .inst/ - BUILD_PREFIX="$PWD/tmp" - INST_PREFIX="$PWD/.inst" - - echo "PATH='$PATH' before possibly applying CCACHE into the mix" - ( echo "$PATH" | grep ccache ) >/dev/null && echo "WARNING: ccache is already in PATH" - if [ -n "$CC" ]; then - echo "CC='$CC' before possibly applying CCACHE into the mix" - $CC --version $CFLAGS || \ - $CC --version || true - fi - - if [ -n "$CXX" ]; then - echo "CXX='$CXX' before possibly applying CCACHE into the mix" - $CXX --version $CXXFLAGS || \ - $CXX --version || true - fi - - if [ x"${CI_CCACHE_USE-}" = xno ]; then - HAVE_CCACHE=no - CI_CCACHE_SYMLINKDIR="" - echo "WARNING: Caller required to not use ccache even if available" >&2 - else - if [ -n "${CI_CCACHE_SYMLINKDIR}" ]; then - # Tell ccache the PATH without itself in it, to avoid loops processing - PATH="`echo "$PATH" | sed -e 's,^'"${CI_CCACHE_SYMLINKDIR}"'/?:,,' -e 's,:'"${CI_CCACHE_SYMLINKDIR}"'/?:,,' -e 's,:'"${CI_CCACHE_SYMLINKDIR}"'/?$,,' -e 's,^'"${CI_CCACHE_SYMLINKDIR}"'/?$,,'`" - fi - CCACHE_PATH="$PATH" - CCACHE_DIR="${HOME}/.ccache" - export CCACHE_PATH CCACHE_DIR PATH - HAVE_CCACHE=no - if (command -v ccache || which ccache) \ - && ( [ -z "${CI_CCACHE_SYMLINKDIR}" ] || ls -la "${CI_CCACHE_SYMLINKDIR}" ) \ - ; then - HAVE_CCACHE=yes - fi - mkdir -p "${CCACHE_DIR}"/ || HAVE_CCACHE=no - fi - - ccache_stats "before" - - CONFIG_OPTS=() - COMMON_CFLAGS="" - EXTRA_CFLAGS="" - EXTRA_CPPFLAGS="" - EXTRA_CXXFLAGS="" - - is_gnucc() { - if [ -n "$1" ] && LANG=C "$1" --version 2>&1 | grep 'Free Software Foundation' > /dev/null ; then true ; else false ; fi - } - - is_clang() { - if [ -n "$1" ] && LANG=C "$1" --version 2>&1 | grep 'clang version' > /dev/null ; then true ; else false ; fi - } - - filter_version() { - # Starting with number like "6.0.0" or "7.5.0-il-0" is fair game, - # but a "gcc-4.4.4-il-4" (starting with "gcc") is not - sed -e 's,^.* \([0-9][0-9]*\.[0-9][^ ),]*\).*$,\1,' -e 's, .*$,,' | grep -E '^[0-9]' | head -1 - } - - ver_gnucc() { - [ -n "$1" ] && LANG=C "$1" --version 2>&1 | grep -i gcc | filter_version - } - - ver_clang() { - [ -n "$1" ] && LANG=C "$1" --version 2>&1 | grep -i 'clang' | filter_version - } - - COMPILER_FAMILY="" - if [ -n "$CC" -a -n "$CXX" ]; then - if is_gnucc "$CC" && is_gnucc "$CXX" ; then - COMPILER_FAMILY="GCC" - export CC CXX - elif is_clang "$CC" && is_clang "$CXX" ; then - COMPILER_FAMILY="CLANG" - export CC CXX - fi - else - # Generally we prefer GCC unless it is very old so we can't impact - # its warnings and complaints. - if is_gnucc "gcc" && is_gnucc "g++" ; then - # Autoconf would pick this by default - COMPILER_FAMILY="GCC" - [ -n "$CC" ] || CC=gcc - [ -n "$CXX" ] || CXX=g++ - export CC CXX - elif is_gnucc "cc" && is_gnucc "c++" ; then - COMPILER_FAMILY="GCC" - [ -n "$CC" ] || CC=cc - [ -n "$CXX" ] || CXX=c++ - export CC CXX - fi - - if ( [ "$COMPILER_FAMILY" = "GCC" ] && \ - case "`ver_gnucc "$CC"`" in - [123].*) true ;; - 4.[0123][.,-]*) true ;; - 4.[0123]) true ;; - *) false ;; - esac && \ - case "`ver_gnucc "$CXX"`" in - [123].*) true ;; - 4.[0123][.,-]*) true ;; - 4.[0123]) true ;; - *) false ;; - esac - ) ; then - echo "NOTE: default GCC here is very old, do we have a CLANG instead?.." >&2 - COMPILER_FAMILY="GCC_OLD" - fi - - if [ -z "$COMPILER_FAMILY" ] || [ "$COMPILER_FAMILY" = "GCC_OLD" ]; then - if is_clang "clang" && is_clang "clang++" ; then - # Autoconf would pick this by default - [ "$COMPILER_FAMILY" = "GCC_OLD" ] && CC="" && CXX="" - COMPILER_FAMILY="CLANG" - [ -n "$CC" ] || CC=clang - [ -n "$CXX" ] || CXX=clang++ - export CC CXX - elif is_clang "cc" && is_clang "c++" ; then - [ "$COMPILER_FAMILY" = "GCC_OLD" ] && CC="" && CXX="" - COMPILER_FAMILY="CLANG" - [ -n "$CC" ] || CC=cc - [ -n "$CXX" ] || CXX=c++ - export CC CXX - fi - fi - - if [ "$COMPILER_FAMILY" = "GCC_OLD" ]; then - COMPILER_FAMILY="GCC" - fi - fi - - if [ -n "$CPP" ] ; then - # Note: can be a multi-token name like "clang -E" or just not a full pathname - ( [ -x "$CPP" ] || $CPP --help >/dev/null 2>/dev/null ) && export CPP - else - # Avoid "cpp" directly as it may be too "traditional" - case "$COMPILER_FAMILY" in - CLANG*|GCC*) CPP="$CC -E" && export CPP ;; - *) if is_gnucc "cpp" ; then - CPP=cpp && export CPP - fi ;; - esac - fi - - if [ -z "${CANBUILD_LIBGD_CGI-}" ]; then - if [[ "$CI_OS_NAME" = "openindiana" ]] ; then - # For some reason, here gcc-4.x (4.4.4, 4.9) have a problem with - # configure-time checks of libgd; newer compilers fare okay. - # Feel free to revise this if the distro packages are fixed - # (or the way configure script and further build uses them). - # UPDATE: Per https://github.com/networkupstools/nut/pull/1089 - # This is a systems issue (in current OpenIndiana 2021.04 built - # with a newer GCC version, the older GCC is not ABI compatible - # with the libgd shared object file). Maybe this warrants later - # caring about not just the CI_OS_NAME but also CI_OS_RELEASE... - if [[ "$COMPILER_FAMILY" = "GCC" ]]; then - case "`LANG=C $CC --version | head -1`" in - *[\ -][01234].*) - echo "WARNING: Seems we are running with gcc-4.x or older on $CI_OS_NAME, which last had known issues with libgd; disabling CGI for this build" - CANBUILD_LIBGD_CGI=no - ;; - *) - case "${ARCH}${BITS}${ARCH_BITS}" in - *64*|*sparcv9*) ;; - *) - # GCC-7 (maybe other older compilers) could default - # to 32-bit builds, and the 32-bit libfontconfig.so - # and libfreetype.so are absent for some years now - # (while libgd.so still claims to exist). - echo "WARNING: Seems we are running with gcc on $CI_OS_NAME, which last had known issues with libgd on non-64-bit builds; making CGI optional for this build" - CANBUILD_LIBGD_CGI=auto - ;; - esac - ;; - esac - else - case "${ARCH}${BITS}${ARCH_BITS}" in - *64*|*sparcv9*) ;; - *) - echo "WARNING: Seems we are running with $COMPILER_FAMILY on $CI_OS_NAME, which last had known issues with libgd on non-64-bit builds; making CGI optional for this build" - CANBUILD_LIBGD_CGI=auto - ;; - esac - fi - fi + + return 0 +} + +optional_dist_clean_check() { + if [ ! -e .git ]; then + echo "Skipping distclean check because there is no .git" >&2 + return 0 fi - DEFAULT_PKG_CONFIG_PATH="${BUILD_PREFIX}/lib/pkgconfig" - SYSPKG_CONFIG_PATH="" # Let the OS guess... usually - case "`echo "$CI_OS_NAME" | tr 'A-Z' 'a-z'`" in - *openindiana*|*omnios*|*solaris*|*illumos*|*sunos*) - case "$CC$CXX$CFLAGS$CXXFLAGS$LDFLAGS" in - *-m64*) - SYS_PKG_CONFIG_PATH="/usr/lib/64/pkgconfig:/usr/lib/amd64/pkgconfig:/usr/lib/sparcv9/pkgconfig:/usr/lib/pkgconfig" - ;; - *-m32*) - SYS_PKG_CONFIG_PATH="/usr/lib/32/pkgconfig:/usr/lib/pkgconfig:/usr/lib/i86pc/pkgconfig:/usr/lib/i386/pkgconfig:/usr/lib/sparcv7/pkgconfig" - ;; - *) - case "${ARCH}${BITS}${ARCH_BITS}" in - *64*) - SYS_PKG_CONFIG_PATH="/usr/lib/64/pkgconfig:/usr/lib/amd64/pkgconfig:/usr/lib/sparcv9/pkgconfig:/usr/lib/pkgconfig" - ;; - *32*) - SYS_PKG_CONFIG_PATH="/usr/lib/32/pkgconfig:/usr/lib/pkgconfig:/usr/lib/i86pc/pkgconfig:/usr/lib/i386/pkgconfig:/usr/lib/sparcv7/pkgconfig" - ;; - esac - ;; - esac - ;; - *darwin*|*macos*|*osx*) - # Architecture-dependent base dir, e.g. - # * /usr/local on macos x86 - # * /opt/homebrew on macos Apple Silicon - if [ -n "${HOMEBREW_PREFIX-}" -a -d "${HOMEBREW_PREFIX-}" ]; then - echo "Homebrew: export general pkg-config location and C/C++/LD flags for the platform" - SYS_PKG_CONFIG_PATH="${HOMEBREW_PREFIX}/lib/pkgconfig" - CFLAGS="${CFLAGS-} -Wno-poison-system-directories -Wno-deprecated-declarations -isystem ${HOMEBREW_PREFIX}/include -I${HOMEBREW_PREFIX}/include" - #CPPFLAGS="${CPPFLAGS-} -Wno-poison-system-directories -Wno-deprecated-declarations -isystem ${HOMEBREW_PREFIX}/include -I${HOMEBREW_PREFIX}/include" - CXXFLAGS="${CXXFLAGS-} -Wno-poison-system-directories -isystem ${HOMEBREW_PREFIX}/include -I${HOMEBREW_PREFIX}/include" - LDFLAGS="${LDFLAGS-} -L${HOMEBREW_PREFIX}/lib" + if [ ! -e Makefile ]; then + echo "WARNING: Skipping distclean check because there is no Makefile (did we clean in a loop earlier?)" >&2 + return 0 + fi - # Net-SNMP "clashes" with system-provided tools (but no header/lib) - # so explicit args are needed - checkFSobj="${HOMEBREW_PREFIX}/opt/net-snmp/lib/pkgconfig" - if [ -d "$checkFSobj" -a ! -e "${HOMEBREW_PREFIX}/lib/pkgconfig/netsnmp.pc" ] ; then - echo "Homebrew: export pkg-config location for Net-SNMP" - SYS_PKG_CONFIG_PATH="$SYS_PKG_CONFIG_PATH:$checkFSobj" - #echo "Homebrew: export flags for Net-SNMP" - #CONFIG_OPTS+=("--with-snmp-includes=-isystem ${HOMEBREW_PREFIX}/opt/net-snmp/include -I${HOMEBREW_PREFIX}/opt/net-snmp/include") - #CONFIG_OPTS+=("--with-snmp-libs=-L${HOMEBREW_PREFIX}/opt/net-snmp/lib") - fi + if [ "${DO_CLEAN_CHECK-}" = "no" ] || [ "${DO_DIST_CLEAN_CHECK-}" = "no" ] ; then + echo "Skipping distclean check because recipe/developer said so" + else + [ -z "$CI_TIME" ] || echo "`date`: Starting dist-clean check of currently tested project..." - if [ -d "${HOMEBREW_PREFIX}/opt/net-snmp/include" -a -d "${HOMEBREW_PREFIX}/include/openssl" ]; then - # TODO? Check netsnmp.pc for Libs.private with - # -L/opt/homebrew/opt/openssl@1.1/lib - # or - # -L/usr/local/opt/openssl@3/lib - # among other options to derive the exact version - # it wants, and serve that include path here - echo "Homebrew: export configure options for Net-SNMP with default OpenSSL headers (too intimate on Homebrew)" - CONFIG_OPTS+=("--with-snmp-includes=-isystem ${HOMEBREW_PREFIX}/opt/net-snmp/include -I${HOMEBREW_PREFIX}/opt/net-snmp/include -isystem ${HOMEBREW_PREFIX}/include -I${HOMEBREW_PREFIX}/include") - CONFIG_OPTS+=("--with-snmp-libs=-L${HOMEBREW_PREFIX}/opt/net-snmp/lib -lnetsnmp") - fi + # Note: currently Makefile.am has just a dummy "distcleancheck" rule + $CI_TIME $MAKE DISTCHECK_FLAGS="$DISTCHECK_FLAGS" $PARMAKE_FLAGS $MAKE_FLAGS_CLEAN distclean || return - # A bit hackish to check this outside `configure`, but... - if [ -s "${HOMEBREW_PREFIX-}/include/ltdl.h" ] ; then - echo "Homebrew: export flags for LibLTDL" - # The m4 script clear default CFLAGS/LIBS so benefit from new ones - CONFIG_OPTS+=("--with-libltdl-includes=-isystem ${HOMEBREW_PREFIX}/include -I${HOMEBREW_PREFIX}/include") - CONFIG_OPTS+=("--with-libltdl-libs=-L${HOMEBREW_PREFIX}/lib -lltdl") - fi + check_gitignore "distclean" || return + fi + return 0 +} - if [ -z "${XML_CATALOG_FILES-}" ] ; then - checkFSobj="${HOMEBREW_PREFIX}/etc/xml/catalog" - if [ -e "$checkFSobj" ] ; then - echo "Homebrew: export XML_CATALOG_FILES='$checkFSobj' for asciidoc et al" - XML_CATALOG_FILES="$checkFSobj" - export XML_CATALOG_FILES - fi - fi - else - echo "WARNING: It seems you are building on MacOS, but HOMEBREW_PREFIX is not set or valid." - echo 'If you do use this build system, try running eval "$(brew shellenv)"' - echo "in your terminal or shell profile, it can help with auto-detection of some features!" +if [ "$1" = inplace ] && [ -z "$BUILD_TYPE" ] ; then + shift + BUILD_TYPE="inplace" +fi + +if [ "$1" = spellcheck -o "$1" = spellcheck-interactive ] && [ -z "$BUILD_TYPE" ] ; then + # Note: this is a little hack to reduce typing + # and scrolling in (docs) developer iterations. + case "$CI_OS_NAME" in + windows-msys2) + # https://github.com/msys2/MSYS2-packages/issues/2088 + echo "==========================================================================" + echo "WARNING: some MSYS2 builds of aspell are broken with 'tex' support" + echo "Are you sure you run this in a functional build environment? Ctrl+C if not" + echo "==========================================================================" + sleep 5 + ;; + *) if ! (command -v aspell) 2>/dev/null >/dev/null ; then + echo "==========================================================================" + echo "WARNING: Seems you do not have 'aspell' in PATH (but maybe NUT configure" + echo "script would find the spellchecking toolkit elsewhere)" + echo "Are you sure you run this in a functional build environment? Ctrl+C if not" + echo "==========================================================================" + sleep 5 fi ;; - esac - if [ -n "$SYS_PKG_CONFIG_PATH" ] ; then - if [ -n "$PKG_CONFIG_PATH" ] ; then - PKG_CONFIG_PATH="$SYS_PKG_CONFIG_PATH:$PKG_CONFIG_PATH" - else - PKG_CONFIG_PATH="$SYS_PKG_CONFIG_PATH" + esac >&2 + if [ -s Makefile ] && [ -s docs/Makefile ]; then + echo "Processing quick and quiet spellcheck with already existing recipe files, will only report errors if any ..." + build_to_only_catch_errors_target $1 ; exit + else + # TODO: Actually do it (default-spellcheck-interactive)? + if [ "$1" = spellcheck-interactive ] ; then + echo "Only CI-building 'spellcheck', please do the interactive part manually if needed" >&2 fi + BUILD_TYPE="default-spellcheck" + shift + fi +fi + +echo "Processing BUILD_TYPE='${BUILD_TYPE}' ..." + +ensure_CI_CCACHE_SYMLINKDIR_envvar +echo "Build host settings:" +set | grep -E '^(PATH|[^ ]*CCACHE[^ ]*|CI_[^ ]*|OS_[^ ]*|CANBUILD_[^ ]*|NODE_LABELS|MAKE|C[^ ]*FLAGS|LDFLAGS|ARCH[^ ]*|BITS[^ ]*|CC|CXX|CPP|DO_[^ ]*|BUILD_[^ ]*)=' || true +uname -a +echo "LONG_BIT:`getconf LONG_BIT` WORD_BIT:`getconf WORD_BIT`" || true +if command -v xxd >/dev/null ; then xxd -c 1 -l 6 | tail -1; else if command -v od >/dev/null; then od -N 1 -j 5 -b | head -1 ; else hexdump -s 5 -n 1 -C | head -1; fi; fi < /bin/ls 2>/dev/null | awk '($2 == 1){print "Endianness: LE"}; ($2 == 2){print "Endianness: BE"}' || true + +case "$BUILD_TYPE" in +default|default-alldrv|default-alldrv:no-distcheck|default-all-errors|default-spellcheck|default-shellcheck|default-nodoc|default-withdoc|default-withdoc:man|"default-tgt:"*) + LANG=C + LC_ALL=C + export LANG LC_ALL + + if [ -d "./tmp/" ]; then + rm -rf ./tmp/ fi + if [ -d "./.inst/" ]; then + rm -rf ./.inst/ + fi + + # Pre-create locations; tmp/lib in particular to avoid (on MacOS xcode): + # ld: warning: directory not found for option '-L/Users/distiller/project/tmp/lib' + # Note that maintainer-clean checks can remove these directory trees, + # so we re-create them just in case in the configure_nut() method too. + mkdir -p tmp/lib .inst/ + BUILD_PREFIX="$PWD/tmp" + INST_PREFIX="$PWD/.inst" + + optional_prepare_ccache + ccache_stats "before" + + optional_prepare_compiler_family + + CONFIG_OPTS=() + COMMON_CFLAGS="" + EXTRA_CFLAGS="" + EXTRA_CPPFLAGS="" + EXTRA_CXXFLAGS="" + + detect_platform_CANBUILD_LIBGD_CGI + + # Prepend or use this build's preferred artifacts, if any + DEFAULT_PKG_CONFIG_PATH="${BUILD_PREFIX}/lib/pkgconfig" + detect_platform_PKG_CONFIG_PATH_and_FLAGS if [ -n "$PKG_CONFIG_PATH" ] ; then - CONFIG_OPTS+=("PKG_CONFIG_PATH=${DEFAULT_PKG_CONFIG_PATH}:${PKG_CONFIG_PATH}") - else - CONFIG_OPTS+=("PKG_CONFIG_PATH=${DEFAULT_PKG_CONFIG_PATH}") + CONFIG_OPTS+=("PKG_CONFIG_PATH=${PKG_CONFIG_PATH}") fi + PATH="`echo "${PATH}" | normalize_path`" + CCACHE_PATH="`echo "${CCACHE_PATH}" | normalize_path`" + # Note: Potentially there can be spaces in entries for multiple # *FLAGS here; this should be okay as long as entry expands to # one token when calling shell (may not be the case for distcheck) @@ -1351,7 +1609,7 @@ default|default-alldrv|default-alldrv:no-distcheck|default-all-errors|default-sp # Currently --with-all implies this, but better be sure to # really build everything we can to be certain it builds: if [ "${CANBUILD_LIBGD_CGI-}" != "auto" ] && ( - $PKG_CONFIG --exists libgd || $PKG_CONFIG --exists libgd2 || $PKG_CONFIG --exists libgd3 || $PKG_CONFIG --exists gdlib || $PKG_CONFIG --exists gd + $PKG_CONFIG --exists libgd || $PKG_CONFIG --exists libgd2 || $PKG_CONFIG --exists libgd3 || $PKG_CONFIG --exists gdlib || $PKG_CONFIG --exists gd ) ; then CONFIG_OPTS+=("--with-cgi=yes") else @@ -1408,72 +1666,7 @@ default|default-alldrv|default-alldrv:no-distcheck|default-all-errors|default-sp # NOTE: The case "$BUILD_TYPE" above was about setting CONFIG_OPTS. # There is another below for running actual scenarios. - if [ "$HAVE_CCACHE" = yes ] && [ "${COMPILER_FAMILY}" = GCC -o "${COMPILER_FAMILY}" = CLANG ]; then - if [ -n "${CI_CCACHE_SYMLINKDIR}" ]; then - echo "INFO: Using ccache via PATH preferring tool names in ${CI_CCACHE_SYMLINKDIR}" >&2 - PATH="${CI_CCACHE_SYMLINKDIR}:$PATH" - export PATH - else - case "$CC" in - "") ;; # skip - *ccache*) ;; # already requested to use ccache - *) CC="ccache $CC" ;; - esac - case "$CXX" in - "") ;; # skip - *ccache*) ;; # already requested to use ccache - *) CXX="ccache $CXX" ;; - esac - # No-op for CPP currently - fi - if [ -n "$CC" ] && [ -n "${CI_CCACHE_SYMLINKDIR}" ]; then - if [ -x "${CI_CCACHE_SYMLINKDIR}/`basename "$CC"`" ]; then - case "$CC" in - *ccache*) ;; - */*) DIR_CC="`dirname "$CC"`" && [ -n "$DIR_CC" ] && DIR_CC="`cd "$DIR_CC" && pwd `" && [ -n "$DIR_CC" ] && [ -d "$DIR_CC" ] || DIR_CC="" - [ -z "$CCACHE_PATH" ] && CCACHE_PATH="$DIR_CC" || \ - if echo "$CCACHE_PATH" | grep -E '(^'"$DIR_CC"':.*|^'"$DIR_CC"'$|:'"$DIR_CC"':|:'"$DIR_CC"'$)' ; then - CCACHE_PATH="$DIR_CC:$CCACHE_PATH" - fi - ;; - esac - CC="${CI_CCACHE_SYMLINKDIR}/`basename "$CC"`" - else - CC="ccache $CC" - fi - fi - if [ -n "$CXX" ] && [ -n "${CI_CCACHE_SYMLINKDIR}" ]; then - if [ -x "${CI_CCACHE_SYMLINKDIR}/`basename "$CXX"`" ]; then - case "$CXX" in - *ccache*) ;; - */*) DIR_CXX="`dirname "$CXX"`" && [ -n "$DIR_CXX" ] && DIR_CXX="`cd "$DIR_CXX" && pwd `" && [ -n "$DIR_CXX" ] && [ -d "$DIR_CXX" ] || DIR_CXX="" - [ -z "$CCACHE_PATH" ] && CCACHE_PATH="$DIR_CXX" || \ - if echo "$CCACHE_PATH" | grep -E '(^'"$DIR_CXX"':.*|^'"$DIR_CXX"'$|:'"$DIR_CXX"':|:'"$DIR_CXX"'$)' ; then - CCACHE_PATH="$DIR_CXX:$CCACHE_PATH" - fi - ;; - esac - CXX="${CI_CCACHE_SYMLINKDIR}/`basename "$CXX"`" - else - CXX="ccache $CXX" - fi - fi - if [ -n "$CPP" ] && [ -n "${CI_CCACHE_SYMLINKDIR}" ] \ - && [ -x "${CI_CCACHE_SYMLINKDIR}/`basename "$CPP"`" ]; then - case "$CPP" in - *ccache*) ;; - */*) DIR_CPP="`dirname "$CPP"`" && [ -n "$DIR_CPP" ] && DIR_CPP="`cd "$DIR_CPP" && pwd `" && [ -n "$DIR_CPP" ] && [ -d "$DIR_CPP" ] || DIR_CPP="" - [ -z "$CCACHE_PATH" ] && CCACHE_PATH="$DIR_CPP" || \ - if echo "$CCACHE_PATH" | grep -E '(^'"$DIR_CPP"':.*|^'"$DIR_CPP"'$|:'"$DIR_CPP"':|:'"$DIR_CPP"'$)' ; then - CCACHE_PATH="$DIR_CPP:$CCACHE_PATH" - fi - ;; - esac - CPP="${CI_CCACHE_SYMLINKDIR}/`basename "$CPP"`" - else - : # CPP="ccache $CPP" - fi - + if optional_ensure_ccache ; then # Note: Potentially there can be spaces in entries for multiword # "ccache gcc" here; this should be okay as long as entry expands to # one token when calling shell (may not be the case for distcheck) @@ -1484,8 +1677,6 @@ default|default-alldrv|default-alldrv:no-distcheck|default-all-errors|default-sp # Build and check this project; note that zprojects always have an autogen.sh [ -z "$CI_TIME" ] || echo "`date`: Starting build of currently tested project..." - CCACHE_BASEDIR="${PWD}" - export CCACHE_BASEDIR # Numerous per-compiler variants defined in configure.ac, including # aliases "minimal", "medium", "hard", "all" @@ -2099,6 +2290,8 @@ bindings) fi echo "" + # NOTE: Alternative to optional_prepare_ccache() + # FIXME: Can these be united and de-duplicated? if [ -n "${CI_CCACHE_SYMLINKDIR}" ] && [ -d "${CI_CCACHE_SYMLINKDIR}" ] ; then PATH="`echo "$PATH" | sed -e 's,^'"${CI_CCACHE_SYMLINKDIR}"'/?:,,' -e 's,:'"${CI_CCACHE_SYMLINKDIR}"'/?:,,' -e 's,:'"${CI_CCACHE_SYMLINKDIR}"'/?$,,' -e 's,^'"${CI_CCACHE_SYMLINKDIR}"'/?$,,'`" CCACHE_PATH="$PATH" @@ -2107,9 +2300,15 @@ bindings) echo "INFO: Using ccache via PATH preferring tool names in ${CI_CCACHE_SYMLINKDIR}" >&2 PATH="${CI_CCACHE_SYMLINKDIR}:$PATH" export CCACHE_PATH CCACHE_DIR PATH + HAVE_CCACHE=yes + mkdir -p "${CCACHE_DIR}"/ || HAVE_CCACHE=no + else + HAVE_CCACHE=no fi fi + optional_prepare_compiler_family + cd "${SCRIPTDIR}" consider_cleanup_shortcut @@ -2138,6 +2337,11 @@ bindings) --disable-force-nut-version-header \ --enable-check-NIT --enable-maintainer-mode) + detect_platform_PKG_CONFIG_PATH_and_FLAGS + if [ -n "$PKG_CONFIG_PATH" ] ; then + CONFIG_OPTS+=("PKG_CONFIG_PATH=${PKG_CONFIG_PATH}") + fi + # Primarily here to ensure libusb-1.0 use on MSYS2/mingw # when 0.1 is available too if [ "${CANBUILD_WITH_LIBMODBUS_USB-}" = yes ] ; then @@ -2164,6 +2368,47 @@ bindings) CONFIG_OPTS+=("--with-python=${PYTHON}") fi + if optional_ensure_ccache ; then + # Note: Potentially there can be spaces in entries for multiword + # "ccache gcc" here; this should be okay as long as entry expands to + # one token when calling shell (may not be the case for distcheck) + CONFIG_OPTS+=("CC=${CC}") + CONFIG_OPTS+=("CXX=${CXX}") + CONFIG_OPTS+=("CPP=${CPP}") + fi + + # If detect_platform_PKG_CONFIG_PATH_and_FLAGS() customized anything here, + # let configure script know + _EXPORT_FLAGS=true + case "${CI_OS_NAME}" in + windows-msys2) + if [ "$HAVE_CCACHE" = yes ] ; then + # NO-OP: Its ccache gets confused, apparently parsing the flags as one parameter + # configure:6064: checking whether the C compiler works + # configure:6086: /mingw64/lib/ccache/bin/gcc -D_POSIX=1 -D_POSIX_C_SOURCE=200112L -D_WIN32_WINNT=0xffff conftest.c >&5 + # Cannot create temporary file in C:\msys64\home\abuild\nut-win\ -D_POSIX=1 -D_POSIX_C_SOURCE=200112L -D_WIN32_WINNT=0xffff\: No such file or directory + # FIXME: Detect better if this bites us on the current system? + _EXPORT_FLAGS=false + fi + ;; + esac + + if [ "${_EXPORT_FLAGS}" = true ] ; then + [ -z "${CFLAGS}" ] || export CFLAGS + [ -z "${CXXFLAGS}" ] || export CXXFLAGS + [ -z "${CPPFLAGS}" ] || export CPPFLAGS + [ -z "${LDFLAGS}" ] || export LDFLAGS + else + # NOTE: Passing via CONFIG_OPTS also fails + [ -z "${CFLAGS}" ] || echo "WARNING: SKIP: On '${CI_OS_NAME}' with ccache used, can not export CFLAGS='${CFLAGS}'" >&2 + [ -z "${CXXFLAGS}" ] || echo "WARNING: SKIP: On '${CI_OS_NAME}' with ccache used, can not export CXXFLAGS='${CXXFLAGS}'" >&2 + [ -z "${CPPFLAGS}" ] || echo "WARNING: SKIP: On '${CI_OS_NAME}' with ccache used, can not export CPPFLAGS='${CPPFLAGS}'" >&2 + [ -z "${LDFLAGS}" ] || echo "WARNING: SKIP: On '${CI_OS_NAME}' with ccache used, can not export LDFLAGS='${LDFLAGS}'" >&2 + fi + + PATH="`echo "${PATH}" | normalize_path`" + CCACHE_PATH="`echo "${CCACHE_PATH}" | normalize_path`" + RES_CFG=0 ${CONFIGURE_SCRIPT} "${CONFIG_OPTS[@]}" \ || RES_CFG=$? diff --git a/configure.ac b/configure.ac index 01b262a864..1b6f8a330c 100644 --- a/configure.ac +++ b/configure.ac @@ -131,6 +131,27 @@ AS_IF([test x"${NUT_SOURCE_GITREV}" = x], ]) AC_CANONICAL_TARGET NUT_CHECK_OS + +dnl Further below we shuffle variants of these values possibly stripped of +dnl warnings or with added further values. Here we save the most-original copy +dnl so it can be passed e.g. to "make distcheck" the way the caller intended. +NUT_CONFIG_CFLAGS="" +NUT_CONFIG_CPPFLAGS="" +NUT_CONFIG_CXXFLAGS="" +NUT_CONFIG_LDFLAGS="" +AS_IF([test -n "${CFLAGS-}" -a x"${CFLAGS-}" != x" "], + [NUT_CONFIG_CFLAGS="${CFLAGS-}"]) +AS_IF([test -n "${CXXFLAGS-}" -a x"${CXXFLAGS-}" != x" "], + [NUT_CONFIG_CXXFLAGS="${CXXFLAGS-}"]) +AS_IF([test -n "${CPPFLAGS-}" -a x"${CPPFLAGS-}" != x" "], + [NUT_CONFIG_CPPFLAGS="${CPPFLAGS-}"]) +AS_IF([test -n "${LDFLAGS-}" -a x"${LDFLAGS-}" != x" "], + [NUT_CONFIG_LDFLAGS="${LDFLAGS-}"]) +AC_SUBST([NUT_CONFIG_CFLAGS]) +AC_SUBST([NUT_CONFIG_CXXFLAGS]) +AC_SUBST([NUT_CONFIG_CPPFLAGS]) +AC_SUBST([NUT_CONFIG_LDFLAGS]) + NUT_STASH_WARNINGS AC_CONFIG_HEADERS([include/config.h]) AC_PREFIX_DEFAULT(/usr/local/ups) @@ -158,8 +179,14 @@ dnl experimentation, we do not want to actually mangle the flags provided dnl by autoconf - for GCC at least, the rightmost mentions of conflicting dnl flags on command line win. We just want to know when it is okay to add dnl ours. They may be inherited from "in-place" build setup though. -test -n "${CONFIG_CFLAGS-}" || CONFIG_CFLAGS="${CFLAGS-}" +test -n "${CONFIG_CFLAGS-}" || CONFIG_CFLAGS="${CFLAGS-}" test -n "${CONFIG_CXXFLAGS-}" || CONFIG_CXXFLAGS="${CXXFLAGS-}" +test -n "${CONFIG_CPPFLAGS-}" || CONFIG_CPPFLAGS="${CPPFLAGS-}" +test -n "${CONFIG_LDFLAGS-}" || CONFIG_LDFLAGS="${LDFLAGS-}" +AC_SUBST([CONFIG_CFLAGS]) +AC_SUBST([CONFIG_CXXFLAGS]) +AC_SUBST([CONFIG_CPPFLAGS]) +AC_SUBST([CONFIG_LDFLAGS]) dnl +------------------------------------------------------------------- dnl Default to `configure --enable-silent-rules` or `make V=1` for details? @@ -735,10 +762,14 @@ AS_IF([test x"$nut_enable_inplace_runtime" = xyes -a x"${NUT_VERSION_DEPLOYED-}" ]) export NUT_VERSION_DEPLOYED dnl # Avoid replacement after re-entering: - test -n "${CONFIG_CFLAGS-}" || CONFIG_CFLAGS=" " + test -n "${CONFIG_CFLAGS-}" || CONFIG_CFLAGS=" " test -n "${CONFIG_CXXFLAGS-}" || CONFIG_CXXFLAGS=" " + test -n "${CONFIG_CPPFLAGS-}" || CONFIG_CPPFLAGS=" " + test -n "${CONFIG_LDFLAGS-}" || CONFIG_LDFLAGS=" " export CONFIG_CFLAGS export CONFIG_CXXFLAGS + export CONFIG_CPPFLAGS + export CONFIG_LDFLAGS AC_MSG_NOTICE([Moving config.log of the original invocation to config.log.inplace-outer just before exec...]) mv -f config.log config.log.inplace-outer || true @@ -749,10 +780,14 @@ AS_IF([test x"$nut_enable_inplace_runtime" = xyes -a x"${NUT_VERSION_DEPLOYED-}" NUT_VERSION_DEPLOYED="" export NUT_VERSION_DEPLOYED dnl # Avoid replacement after re-entering: - test -n "${CONFIG_CFLAGS-}" || CONFIG_CFLAGS=" " + test -n "${CONFIG_CFLAGS-}" || CONFIG_CFLAGS=" " test -n "${CONFIG_CXXFLAGS-}" || CONFIG_CXXFLAGS=" " + test -n "${CONFIG_CPPFLAGS-}" || CONFIG_CPPFLAGS=" " + test -n "${CONFIG_LDFLAGS-}" || CONFIG_LDFLAGS=" " export CONFIG_CFLAGS export CONFIG_CXXFLAGS + export CONFIG_CPPFLAGS + export CONFIG_LDFLAGS AC_MSG_NOTICE([Moving config.log of the original invocation to config.log.inplace-outer just before exec...]) mv -f config.log config.log.inplace-outer || true @@ -5590,6 +5625,8 @@ dnl We might wipe their specific options below if consistently applying dnl debug-friendly options to everything AC_MSG_NOTICE([CONFIG_CFLAGS='${CONFIG_CFLAGS}']) AC_MSG_NOTICE([CONFIG_CXXFLAGS='${CONFIG_CXXFLAGS}']) +AC_MSG_NOTICE([CONFIG_CPPFLAGS='${CONFIG_CPPFLAGS}']) +AC_MSG_NOTICE([CONFIG_LDFLAGS='${CONFIG_LDFLAGS}']) AC_MSG_CHECKING([whether to enable debug info in all NUT binaries]) nut_with_debuginfo_C="${nut_with_debuginfo}" nut_with_debuginfo_CXX="${nut_with_debuginfo}" diff --git a/docs/config-prereqs.txt b/docs/config-prereqs.txt index 07fa83d02c..7d83e6dae6 100644 --- a/docs/config-prereqs.txt +++ b/docs/config-prereqs.txt @@ -1278,11 +1278,18 @@ happen that you would need to roll and install your own builds in accordance with that project's design goals. Note you may need not just the "Core" IPS package publisher, but also the -"Extra" one. See OmniOS CE web site for setup details. +"Extra" one. As of release 151052, it can be attached right in the installer; +otherwise the `pkg (set-)publisher` commands can be used. See OmniOS CE web +site for setup details. ------ +# Optionally, make the environment comfortable, e.g.: +:; pkg install sudo bash application/mc wget rsync pigz pbzip2 p7zip top + +# NOTE: OmniOS currently does not deliver clang in its Core/Extra repositories :; pkg install \ - developer/build/autoconf developer/build/automake developer/build/libtool \ + developer/build/autoconf developer/build/automake \ + developer/build/libtool library/libtool/libltdl \ build-essential ccache git developer/pkg-config \ runtime/perl \ asciidoc \ @@ -1317,39 +1324,53 @@ and the library+symlinks for all architectures you would need). NOTE: As of July 2022, a `libusb-1` package recipe was proposed for the `omnios-extra` repository (NUT itself and further dependencies may also appear there, per -link:https://github.com/networkupstools/nut/issues/1498[issue #1498]). +link:https://github.com/networkupstools/nut/issues/1498[issue #1498]), +and is available as of release 151046: +------ +:; pkg install \ + libusb-1 +------ You may need to set up `ccache` with the same `/usr/lib/ccache` dir used -in other OS recipes. Assuming your Build Essentials pulled GCC 9 version, +in other OS recipes. Assuming your Build Essentials pulled GCC 11 version, and ccache is under `/opt/ooce` namespace, that would be like: ------ +:; GCCVER=11 :; mkdir -p /usr/lib/ccache :; cd /usr/lib/ccache :; ln -fs ../../../opt/ooce/bin/ccache gcc :; ln -fs ../../../opt/ooce/bin/ccache g++ :; ln -fs ../../../opt/ooce/bin/ccache gcpp -:; ln -fs ../../../opt/ooce/bin/ccache gcc-9 -:; ln -fs ../../../opt/ooce/bin/ccache g++-9 -:; ln -fs ../../../opt/ooce/bin/ccache gcpp-9 +:; ln -fs ../../../opt/ooce/bin/ccache gcc-${GCCVER} +:; ln -fs ../../../opt/ooce/bin/ccache g++-${GCCVER} +:; ln -fs ../../../opt/ooce/bin/ccache gcpp-${GCCVER} ------ Given that many of the dependencies can get installed into that namespace, you may have to specify where `pkg-config` will look for them (note that -library and binary paths can be architecture bitness-dependent): +library and binary paths can be architecture bitness-dependent; the +`ci_build.sh` script should take care of this for many scenarios): ------ :; ./configure PKG_CONFIG_PATH="/opt/ooce/lib/amd64/pkgconfig" --with-cgi ------ +You may also have to fiddle with either `LD_LIBRARY_PATH`, `crle (-c)` or +`./configure --with-something-libs` options to compensate for lack of `-R` +linker options in the `pkg-config` information provided by that repository: +by default the NUT programs can build with the information they get, but +fail to find the needed shared objects at run-time. More about this situation +is tracked at https://github.com/networkupstools/nut/issues/2782 + Note also that the minimal footprint nature of OmniOS CE precludes building any large scope easily, so avoid docs and "all drivers" unless you provide whatever they need to happen. -NOTE: For Jenkins agents, also need to `pkg install runtime/java/openjdk17` +NOTE: For Jenkins agents, also need to `pkg install runtime/java/openjdk21` for JRE/JDK 17. Java 17 or 21 is required to run Jenkins agents after autumn 2024. If updating from older releases, you may need to update default implementation, e.g.: ---- -:; pkg set-mediator -V 17 java +:; pkg set-mediator -V 21 java ---- diff --git a/docs/nut.dict b/docs/nut.dict index d4af2f1dd4..ba26d35391 100644 --- a/docs/nut.dict +++ b/docs/nut.dict @@ -1,4 +1,4 @@ -personal_ws-1.1 en 3278 utf-8 +personal_ws-1.1 en 3279 utf-8 AAC AAS ABI @@ -1725,6 +1725,7 @@ cr crestfactor crit criticality +crle crlf cron crontab diff --git a/m4/nut_check_libltdl.m4 b/m4/nut_check_libltdl.m4 index eb6273651a..6f3afe261c 100644 --- a/m4/nut_check_libltdl.m4 +++ b/m4/nut_check_libltdl.m4 @@ -71,6 +71,7 @@ if test -z "${nut_have_libltdl_seen}"; then depCFLAGS="$myCFLAGS" dnl No ltdl-7 here, this codepath is unlikely on Windows where that matters: CFLAGS="${CFLAGS_ORIG} ${depCFLAGS}" + unset ac_cv_search_lt_dlinit AC_SEARCH_LIBS(lt_dlinit, ltdl, [nut_have_libltdl=yes], []) ]) ]) diff --git a/tests/Makefile.am b/tests/Makefile.am index 47531ba8ce..48beeac5fd 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -145,11 +145,6 @@ TESTS += $(TESTS_CXX11) # Note: we only build it, but do not run directly (NIT prepares the sandbox) check_PROGRAMS += cppnit -if WITH_VALGRIND -check-local: $(check_PROGRAMS) - RES=0; for P in $? ; do $(VALGRIND) ./$$P || { RES=$$? ; echo "FAILED: $(VALGRIND) ./$$P" >&2; }; done; exit $$RES -endif WITH_VALGRIND - cppunittest_CXXFLAGS = $(AM_CXXFLAGS) $(CPPUNIT_CFLAGS) $(CPPUNIT_CXXFLAGS) $(CPPUNIT_NUT_CXXFLAGS) $(CXXFLAGS) ###cppunittest_CXXFLAGS += -I$(top_srcdir)/include -DTOP_SRCDIR="\"$(top_srcdir)\"" cppunittest_LDFLAGS = $(CPPUNIT_LDFLAGS) $(CPPUNIT_LIBS) @@ -195,6 +190,24 @@ cppnit: endif !HAVE_CXX11 +if HAVE_VALGRIND +# NOTE: "cppnit", if built, requires running from NIT (with NUT_PORT, etc.) +memcheck: $(check_PROGRAMS) + RES=0; for P in $? ; do \ + case "$$P" in \ + cppnit|cppnit$(EXEEXT)) if [ "$${NUT_PORT-}" -gt 0 ] 2>/dev/null ; then : ; else echo "SKIPPED: $(VALGRIND) ./$$P : NUT_PORT not prepared" ; continue ; fi ;; \ + esac ; \ + $(VALGRIND) ./$$P || { RES=$$? ; echo "FAILED: $(VALGRIND) ./$$P" >&2; } ; \ + done; exit $$RES +else !HAVE_VALGRIND +memcheck: + @echo "SKIPPED $@ : valgrind was not detected on this system by configure script" >&2 +endif !HAVE_VALGRIND + +if WITH_VALGRIND +check-local: memcheck +endif WITH_VALGRIND + dummy: BUILT_SOURCES = $(LINKED_SOURCE_FILES) diff --git a/tools/gitlog2version.sh b/tools/gitlog2version.sh index 5f0a834b4f..261580bf5d 100755 --- a/tools/gitlog2version.sh +++ b/tools/gitlog2version.sh @@ -204,7 +204,7 @@ getver_default() { NUT_VERSION_DEFAULT3_DOTS="`expr $NUT_VERSION_DEFAULT3_DOTS + 1`" done while [ "${NUT_VERSION_DEFAULT3_DOTS}" -gt 2 ] ; do - NUT_VERSION_DEFAULT3="`echo "${NUT_VERSION_DEFAULT3}" | sed 's,\.[0-9][0-9]*$,,'`" + NUT_VERSION_DEFAULT3="`echo "${NUT_VERSION_DEFAULT3}" | sed 's,\.[0-9][0-9]*[^.]*$,,'`" NUT_VERSION_DEFAULT3_DOTS="`expr $NUT_VERSION_DEFAULT3_DOTS - 1`" done