diff --git a/.circleci/config.yml b/.circleci/config.yml index ead6ed4142..7dbd3b0c1f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -53,6 +53,12 @@ jobs: #type: string #default: "/opt/homebrew" # since July 2024 CircleCI only serves Apple Silicon instances #default: "/usr/local" # was when CircleCI builders had x86 + DO_CLEAN_AUTOCONF_CACHE: + type: string + default: "no" + DO_USE_AUTOCONF_CACHE: + type: string + default: "yes" environment: CC: << parameters.CC >> @@ -64,6 +70,8 @@ jobs: CI_BUILDDIR: << parameters.CI_BUILDDIR >> BREW_MORE: << parameters.BREW_MORE >> #HOMEBREW_PREFIX: << parameters.HOMEBREW_PREFIX >> + DO_CLEAN_AUTOCONF_CACHE: << parameters.DO_CLEAN_AUTOCONF_CACHE >> + DO_USE_AUTOCONF_CACHE: << parameters.DO_USE_AUTOCONF_CACHE >> # Specify the execution environment. You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub. # See: https://circleci.com/docs/2.0/configuration-reference/#docker-machine-macos-windows-executor @@ -126,6 +134,7 @@ jobs: keys: - ccache-{{ .Branch }}-{{ arch }}-{{ .Environment.CIRCLE_JOB }} - ccache-master-{{ arch }}-{{ .Environment.CIRCLE_JOB }} + - config-cache-{{ .Branch }}-{{ arch }}-{{ .Environment.CIRCLE_JOB }} # Help SEMVER look right (optionally) - run: @@ -194,10 +203,17 @@ jobs: # be beneficial to instead share the cache between jobs; more so # while we are on free CircleCI tier and run them sequentially. - save_cache: + name: Save .ccache for later runs paths: - ~/.ccache key: ccache-{{ .Branch }}-{{ arch }}-{{ .Environment.CIRCLE_JOB }} + - save_cache: + name: Save config.cache for later runs + paths: + - config.cache + key: config-cache-{{ .Branch }}-{{ arch }}-{{ .Environment.CIRCLE_JOB }} + - store_artifacts: path: config.log diff --git a/NEWS.adoc b/NEWS.adoc index d62589886f..d367b357f6 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -150,6 +150,9 @@ https://github.com/networkupstools/nut/milestone/12 syntax is not supported everywhere (or the `!` operator generally). [#3099, #1660] + - Introduced `ci_build.sh` settings and respective CI workflow settings + to optionally re-use a `config.cache` file from older runs. [#3108] + Release notes for NUT 2.8.4 - what's new since 2.8.3 ---------------------------------------------------- diff --git a/appveyor.yml b/appveyor.yml index 2c3672b8ee..580966281a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -27,6 +27,8 @@ environment: APPVEYOR_SAVE_CACHE_ON_ERROR: true APPVEYOR_CACHE_ENTRY_ZIP_ARGS: -t7z -m0=lzma -mx=6 CCACHE_DIR: /home/appveyor/.ccache + DO_CLEAN_AUTOCONF_CACHE: no + DO_USE_AUTOCONF_CACHE: yes # https://github.com/networkupstools/nut/blob/Windows-v2.8.0-1/docs/config-prereqs.txt#L951 # or look for the chapter in nearby lines in later (current) revisions. @@ -163,6 +165,7 @@ artifacts: # Example optional cache (depends on file change): # - C:\msys64 -> appveyor.yml cache: + - C:\projects\nut\config.cache - C:\msys64\home\appveyor\nut-win-deps - C:\msys64\home\appveyor\.ccache - C:\msys64\home\appveyor\ccache # likely missing, no problem - but the name is reported in ccache status diff --git a/ci_build.sh b/ci_build.sh index b23de73e1b..8831a468f4 100755 --- a/ci_build.sh +++ b/ci_build.sh @@ -55,7 +55,7 @@ case "$BUILD_TYPE" in echo "SKIPPING BUILD_TYPE=fightwarn-clang: compiler not found" >&2 fi if $TRIED_BUILD ; then true - else + else echo "FAILED to run: no default-named compilers were found" >&2 exit 1 fi @@ -1151,6 +1151,16 @@ configure_nut() { echo "=== CONFIGURING NUT: $CONFIGURE_SCRIPT ${CONFIG_OPTS_STR}" echo "=== CC='$CC' CXX='$CXX' CPP='$CPP'" [ -z "${CI_SHELL_IS_FLAKY-}" ] || echo "=== CI_SHELL_IS_FLAKY='$CI_SHELL_IS_FLAKY'" + if [ x"${DO_USE_AUTOCONF_CACHE}" = xyes ] && [ -s config.cache ]; then + echo "$0: using existing config.cache" >&2 + else + if [ x"${DO_USE_AUTOCONF_CACHE}" = xyes ]; then + echo "$0: NOT using config.cache because it did not exist" >&2 + else if [ -s config.cache ]; then + echo "$0: NOT using existing config.cache because DO_USE_AUTOCONF_CACHE=$DO_USE_AUTOCONF_CACHE" >&2 + fi; fi + fi + $CI_TIME $CONFIGURE_SCRIPT "${CONFIG_OPTS[@]}" \ && echo "$0: configure phase complete (0)" >&2 \ && return 0 \ @@ -1283,6 +1293,9 @@ check_gitignore() { [ -n "${FILE_GLOB-}" ] || FILE_GLOB="'*'" # Always filter these names away: FILE_GLOB_EXCLUDE="':!.ci*.log*' ':!VERSION_DEFAULT' ':!VERSION_FORCED*'" + if [ x"${DO_CLEAN_AUTOCONF_CACHE}" = xno ] ; then + FILE_GLOB_EXCLUDE="$FILE_GLOB_EXCLUDE ':!config.cache*'" + fi [ -n "${GIT_ARGS-}" ] || GIT_ARGS='' # e.g. GIT_ARGS="--ignored" # Display contents of the diff? # (Helps copy-paste from CI logs to source to amend quickly) @@ -1349,12 +1362,20 @@ consider_cleanup_shortcut() { fi fi + if [ x"${DO_CLEAN_AUTOCONF_CACHE}" = xyes ]; then + rm -f config.cache* + fi + # When iterating configure.ac or m4 sources, we can end up with an # existing but useless script file - nuke it and restart from scratch! if [ -s "${CI_BUILDDIR}"/configure ] ; then # FIXME: Consider CONFIG_SHELL, maybe from script shebang, # here - like autogen.sh does - if sh -n "${CI_BUILDDIR}"/configure 2>/dev/null ; then + USE_CONFIG_SHELL=sh + if [ -n "${CONFIG_SHELL-}" ]; then + USE_CONFIG_SHELL="${CONFIG_SHELL}" + fi + if ${USE_CONFIG_SHELL} -n "${CI_BUILDDIR}"/configure 2>/dev/null ; then true else echo "=== Starting initial clean-up (from old build products): TAKING SHORTCUT because current configure script syntax is broken" @@ -1399,15 +1420,30 @@ optional_maintainer_clean_check() { else [ -z "$CI_TIME" ] || echo "`date`: Starting maintainer-clean check of currently tested project..." + rm -f config.cache.tmp || true + if [ x"${DO_CLEAN_AUTOCONF_CACHE}" = xno ] && [ -s config.cache ]; then + echo "=== Keeping old config.cache as asked by BUILD_TYPE default or caller request" + cp -f config.cache config.cache.tmp + fi + # Note: currently Makefile.am has just a dummy "distcleancheck" rule + MAKE_RES=0 case "$MAKE_FLAGS $DISTCHECK_FLAGS $PARMAKE_FLAGS $MAKE_FLAGS_CLEAN" in *V=0*) - $CI_TIME $MAKE DISTCHECK_FLAGS="$DISTCHECK_FLAGS" $PARMAKE_FLAGS $MAKE_FLAGS_CLEAN maintainer-clean > /dev/null || return + $CI_TIME $MAKE DISTCHECK_FLAGS="$DISTCHECK_FLAGS" $PARMAKE_FLAGS $MAKE_FLAGS_CLEAN maintainer-clean > /dev/null || MAKE_RES=$? ;; *) - $CI_TIME $MAKE DISTCHECK_FLAGS="$DISTCHECK_FLAGS" $PARMAKE_FLAGS $MAKE_FLAGS_CLEAN maintainer-clean || return + $CI_TIME $MAKE DISTCHECK_FLAGS="$DISTCHECK_FLAGS" $PARMAKE_FLAGS $MAKE_FLAGS_CLEAN maintainer-clean || MAKE_RES=$? esac + if [ x"${DO_CLEAN_AUTOCONF_CACHE}" = xno ] && [ -s config.cache.tmp ]; then + mv -f config.cache.tmp config.cache || true + fi + + if [ x"$MAKE_RES" != x0 ]; then + return $MAKE_RES + fi + GIT_ARGS="--ignored" check_gitignore "maintainer-clean" || return fi @@ -1434,8 +1470,23 @@ optional_dist_clean_check() { else [ -z "$CI_TIME" ] || echo "`date`: Starting dist-clean check of currently tested project..." + rm -f config.cache.tmp || true + if [ x"${DO_CLEAN_AUTOCONF_CACHE}" = xno ] && [ -s config.cache ]; then + echo "=== Keeping old config.cache as asked by BUILD_TYPE default or caller request" + cp -f config.cache config.cache.tmp + 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 + MAKE_RES=0 + $CI_TIME $MAKE DISTCHECK_FLAGS="$DISTCHECK_FLAGS" $PARMAKE_FLAGS $MAKE_FLAGS_CLEAN distclean || MAKE_RES=$? + + if [ x"${DO_CLEAN_AUTOCONF_CACHE}" = xno ] && [ -s config.cache.tmp ]; then + mv -f config.cache.tmp config.cache || true + fi + + if [ x"$MAKE_RES" != x0 ]; then + return $MAKE_RES + fi check_gitignore "distclean" || return fi @@ -1508,13 +1559,70 @@ if [ -z "$BUILD_TYPE" ] ; then fi ;; - *) echo "WARNING: Command-line argument '$1' wsa not recognized as a BUILD_TYPE alias" >&2 ;; + *) echo "WARNING: Command-line argument '$1' was not recognized as a BUILD_TYPE alias" >&2 ;; esac fi # Default follows autotools: [ -n "${DISTCHECK_TGT-}" ] || DISTCHECK_TGT="distcheck" +# https://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Cache-Files.html +# By default, we clean up the config.cache between jobs (before start, +# after finish), but do want to use (and retain) it between loop runs +# of BUILD_TYPE="default-all-errors*". +# FIXME: Currently disabled for the loops; we want to only cache the +# common system findings but forget the details we vary (implementations +# of libusb, ssl...) because this knowledge about "lack" of some methods +# breaks those very re-runs. The approach can still be used for runs of +# same configurations from one iteration to another on CI systems though. +# Note that autotools automatically removes such file name during the +# "make distclean" and stronger goals, so on our side we can only +# stash and restore the file around such operations. +[ -n "$DO_CLEAN_AUTOCONF_CACHE" ] || DO_CLEAN_AUTOCONF_CACHE="auto" +[ -n "$DO_USE_AUTOCONF_CACHE" ] || DO_USE_AUTOCONF_CACHE="auto" +# What about after tests (e.g. loops?) +[ -n "$DO_CLEAN_AUTOCONF_CACHE_BEFORE" ] || DO_CLEAN_AUTOCONF_CACHE_BEFORE="$DO_CLEAN_AUTOCONF_CACHE" +[ -n "$DO_CLEAN_AUTOCONF_CACHE_FINAL" ] || DO_CLEAN_AUTOCONF_CACHE_FINAL="$DO_CLEAN_AUTOCONF_CACHE" + +if [ x"${DO_CLEAN_AUTOCONF_CACHE}" = xauto ]; then + case "$BUILD_TYPE" in + #default-all-errors*) DO_CLEAN_AUTOCONF_CACHE="no" ;; + *) DO_CLEAN_AUTOCONF_CACHE="yes" ;; + esac +fi +export DO_CLEAN_AUTOCONF_CACHE + +if [ x"${DO_USE_AUTOCONF_CACHE}" = xauto ]; then + case "$BUILD_TYPE" in + #default-all-errors*) DO_USE_AUTOCONF_CACHE="yes" ;; + *) DO_USE_AUTOCONF_CACHE="no" ;; + esac +fi +export DO_USE_AUTOCONF_CACHE + +if [ x"${DO_CLEAN_AUTOCONF_CACHE_BEFORE}" = xauto ]; then + DO_CLEAN_AUTOCONF_CACHE_BEFORE="yes" +fi +if [ x"${DO_CLEAN_AUTOCONF_CACHE_FINAL}" = xauto ]; then + DO_CLEAN_AUTOCONF_CACHE_FINAL="yes" +fi +export DO_CLEAN_AUTOCONF_CACHE_BEFORE +export DO_CLEAN_AUTOCONF_CACHE_FINAL + +if [ x"${DO_CLEAN_AUTOCONF_CACHE_BEFORE}" = xyes ]; then + rm -f config.cache* +fi + +cleanup_exit() { + FINAL_RES=$? + if [ x"${DO_CLEAN_AUTOCONF_CACHE_FINAL}" = xyes ]; then + rm -f config.cache* + fi + return $FINAL_RES +} + +trap 'cleanup_exit' 2 3 15 + echo "Processing BUILD_TYPE='${BUILD_TYPE}' ..." ensure_CI_CCACHE_SYMLINKDIR_envvar @@ -1560,6 +1668,10 @@ default|default-alldrv|default-alldrv:no-distcheck|default-all-errors|default-al detect_platform_CANBUILD_LIBGD_CGI + if [ x"${DO_USE_AUTOCONF_CACHE}" = xyes ] ; then + CONFIG_OPTS+=("-C") + fi + # 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 @@ -1901,6 +2013,12 @@ default|default-alldrv|default-alldrv:no-distcheck|default-all-errors|default-al trap 'echo "!!! If clean-up looped remaking the configure script for maintainer-clean, try to:"; echo " rm -f Makefile configure include/config.h* ; $0 $SCRIPT_ARGS"' 2 echo "=== Starting initial clean-up (from old build products)" + rm -f config.cache.tmp || true + if [ x"${DO_CLEAN_AUTOCONF_CACHE}" = xno ] && [ -s config.cache ]; then + echo "=== Keeping old config.cache as asked by BUILD_TYPE default or caller request" + cp -f config.cache config.cache.tmp + fi + case "$MAKE_FLAGS $MAKE_FLAGS_CLEAN" in *V=0*) ${MAKE} maintainer-clean $MAKE_FLAGS_CLEAN -k > /dev/null \ @@ -1913,7 +2031,12 @@ default|default-alldrv|default-alldrv:no-distcheck|default-all-errors|default-al || true echo "=== Finished initial clean-up" + if [ x"${DO_CLEAN_AUTOCONF_CACHE}" = xno ] && [ -s config.cache.tmp ]; then + mv -f config.cache.tmp config.cache || true + fi + trap - 2 + trap 'cleanup_exit' 2 3 15 fi # Just prepare `configure` script; we run it at different points @@ -2498,8 +2621,19 @@ default|default-alldrv|default-alldrv:no-distcheck|default-all-errors|default-al echo "=== Completed sandbox cleanup-check after TESTCOMBO=${TESTCOMBO}, $BUILDSTODO build variants remaining" else if [ "$BUILDSTODO" -gt 0 ] && [ "${DO_CLEAN_CHECK-}" != no ]; then + rm -f config.cache.tmp || true + if [ x"${DO_CLEAN_AUTOCONF_CACHE}" = xno ] && [ -s config.cache ]; then + echo "=== Keeping old config.cache as asked by BUILD_TYPE default or caller request" + cp -f config.cache config.cache.tmp + fi + $MAKE distclean $MAKE_FLAGS_CLEAN -k \ || echo "WARNING: 'make distclean' FAILED: $? ... proceeding" >&2 + + if [ x"${DO_CLEAN_AUTOCONF_CACHE}" = xno ] && [ -s config.cache.tmp ]; then + mv -f config.cache.tmp config.cache || true + fi + echo "=== Completed sandbox cleanup after TESTCOMBO=${TESTCOMBO}, $BUILDSTODO build variants remaining" else echo "=== SKIPPED sandbox cleanup because DO_CLEAN_CHECK=$DO_CLEAN_CHECK and $BUILDSTODO build variants remaining" @@ -2640,7 +2774,19 @@ bindings) # Help developers debug: # Let initial clean-up be at default verbosity echo "=== Starting initial clean-up (from old build products)" + + rm -f config.cache.tmp || true + if [ x"${DO_CLEAN_AUTOCONF_CACHE}" = xno ] && [ -s config.cache ]; then + echo "=== Keeping old config.cache as asked by BUILD_TYPE default or caller request" + cp -f config.cache config.cache.tmp + fi + ${MAKE} realclean -k || true + + if [ x"${DO_CLEAN_AUTOCONF_CACHE}" = xno ] && [ -s config.cache.tmp ]; then + mv -f config.cache.tmp config.cache || true + fi + echo "=== Finished initial clean-up" fi @@ -2661,6 +2807,10 @@ bindings) --disable-force-nut-version-header \ --enable-check-NIT --enable-maintainer-mode) + if [ x"${DO_USE_AUTOCONF_CACHE}" = xyes ] ; then + CONFIG_OPTS+=("-C") + fi + case x"${BUILD_TYPE}" in xdoc*) CONFIG_OPTS+=("--with-${BUILD_TYPE}") ;; *) CONFIG_OPTS+=("--with-doc=skip") ;; @@ -2754,16 +2904,16 @@ bindings) esac if [ "${_EXPORT_FLAGS}" = true ] ; then - [ -z "${CFLAGS}" ] || export CFLAGS - [ -z "${CXXFLAGS}" ] || export CXXFLAGS - [ -z "${CPPFLAGS}" ] || export CPPFLAGS - [ -z "${LDFLAGS}" ] || export LDFLAGS + [ -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 + # 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`" diff --git a/configure.ac b/configure.ac index 3ff098a667..8260a582a6 100644 --- a/configure.ac +++ b/configure.ac @@ -1918,7 +1918,9 @@ AS_IF([test x"${ac_cv_struct_pollfd}" = xyes], ] ) -NETLIBS_GETADDRS="" +dnl May be cached or not +NETLIBS_GETADDRS="${nut_cv_var_NETLIBS_GETADDRS}" + dnl For `nut-scanner -m auto` modes, see also: dnl https://stackoverflow.com/a/41151132/4715872 dnl https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses (since ~Windows Vista) @@ -1965,7 +1967,7 @@ printf("%ld ", GetAdaptersAddresses(AF_INET6, GAA_FLAG_SKIP_ANYCAST, NULL, buf, dnl e.g. add "-lws2_32" for mingw builds, maybe "-liphlpapi" dnl the NETLIBS are set by NUT_CHECK_SOCKETLIB above SAVED_LIBS="$LIBS" - LIBS="$LIBS $NETLIBS" + LIBS="$LIBS $NETLIBS $NETLIBS_GETADDRS" AX_RUN_OR_LINK_IFELSE( [AC_LANG_PROGRAM( [${myIPHLPAPI_TEST_HEADERS}], @@ -2058,7 +2060,7 @@ printf("%ld ", GetAdaptersInfo(buf, &bufsz)) )] ) AC_SUBST([NETLIBS_GETADDRS]) - +AC_CACHE_VAL([nut_cv_var_NETLIBS_GETADDRS], [nut_cv_var_NETLIBS_GETADDRS="${NETLIBS_GETADDRS}"]) dnl ---------------------------------------------------------------------- dnl First remember if caller wants a custom Python package location? diff --git a/scripts/Windows/build-mingw-nut.sh b/scripts/Windows/build-mingw-nut.sh index 040c352a15..986b08e8ff 100755 --- a/scripts/Windows/build-mingw-nut.sh +++ b/scripts/Windows/build-mingw-nut.sh @@ -133,6 +133,12 @@ do_build_mingw_nut() { export CXXFLAGS+=" -D_POSIX=1 -D_POSIX_C_SOURCE=200112L -D_POSIX_THREAD_SAFE_FUNCTIONS=200112L -I${ARCH_PREFIX}/include/ -D_WIN32_WINNT=0xffff" export LDFLAGS+=" -L${ARCH_PREFIX}/lib/" + # Can be set by e.g. ci_build.sh + USE_AUTOCONF_CACHE_FLAG="" + if [ x"${DO_USE_AUTOCONF_CACHE}" = xyes ] ; then + USE_AUTOCONF_CACHE_FLAG="-C" + fi + KEEP_NUT_REPORT_FEATURE_FLAG="" if [ x"${KEEP_NUT_REPORT_FEATURE-}" = xtrue ]; then KEEP_NUT_REPORT_FEATURE_FLAG="--enable-keep_nut_report_feature" @@ -143,6 +149,7 @@ do_build_mingw_nut() { # FIXME: Implement support for --without-pkg-config in m4 and use it RES_CFG=0 $CONFIGURE_SCRIPT $HOST_FLAG $BUILD_FLAG --prefix=/ \ + $USE_AUTOCONF_CACHE_FLAG \ $KEEP_NUT_REPORT_FEATURE_FLAG \ PKG_CONFIG_PATH="${ARCH_PREFIX}/lib/pkgconfig" \ --with-all=auto \