scripts: Add general-purpose utilities for continuous integration

Currently, libpng supports three different types of build automation:
the GNU autotools, CMake, and a legacy of hand-made makefiles.

In order to simplify the continous integration of all of the above
build options, we introduce the following scripts:
 * ci_autotools.sh: CI utility for the Autotools build
 * ci_cmake.sh: CI utility for the CMake build
 * ci_legacy.sh: CI utility for the legacy makefiles
This commit is contained in:
Cosmin Truta 2020-03-29 00:41:33 -04:00
parent 2c0aee56a0
commit b9155ce3fd
4 changed files with 276 additions and 1 deletions

View File

@ -75,5 +75,9 @@ Other supporting scripts:
macro.lst => Used by autoconf tools
prefix.dfn => Used by autoconf tools
ci_autotools.sh => Continuous integration utility for the Autotools build
ci_cmake.sh => Continuous integration utility for the CMake build
ci_legacy.sh => Continuous integration utility for the legacy makefiles
Further information can be found in comments in the individual makefiles.
Further information can be found in comments in the individual scripts and
makefiles.

76
scripts/ci_autotools.sh Executable file
View File

@ -0,0 +1,76 @@
#!/usr/bin/env bash
set -e
# ci_autotools.sh
# Continuously integrate libpng using the GNU Autotools.
#
# Copyright (c) 2019-2020 Cosmin Truta.
#
# This software is released under the libpng license.
# For conditions of distribution and use, see the disclaimer and license
# in png.h.
CI_SCRIPTNAME="$(basename "$0")"
CI_SCRIPTDIR="$(cd "$(dirname "$0")" && pwd)"
CI_SRCDIR="$(dirname "$CI_SCRIPTDIR")"
CI_BUILDDIR="$CI_SRCDIR/out/autotools.build"
function ci_info {
printf >&2 "%s: %s\\n" "$CI_SCRIPTNAME" "$*"
}
function ci_err {
printf >&2 "%s: error: %s\\n" "$CI_SCRIPTNAME" "$*"
exit 2
}
function ci_spawn {
printf >&2 "%s: executing:" "$CI_SCRIPTNAME"
printf >&2 " %q" "$@"
printf >&2 "\\n"
"$@"
}
function ci_init_autotools {
# Initialize the CI_ variables with default values, where applicable.
CI_MAKE="${CI_MAKE:-make}"
[[ $(uname -s || echo unknown) == Darwin ]] && CI_CC="${CI_CC:-clang}"
# Print the CI_ variables.
ci_info "source directory: $CI_SRCDIR"
ci_info "build directory: $CI_BUILDDIR"
ci_info "environment option: \$CI_CONFIGURE_FLAGS='$CI_CONFIGURE_FLAGS'"
ci_info "environment option: \$CI_MAKE='$CI_MAKE'"
ci_info "environment option: \$CI_MAKE_FLAGS='$CI_MAKE_FLAGS'"
ci_info "environment option: \$CI_CC='$CI_CC'"
ci_info "environment option: \$CI_CC_FLAGS='$CI_CC_FLAGS'"
ci_info "environment option: \$CI_SANITIZERS='$CI_SANITIZERS'"
ci_info "environment option: \$CI_NO_TEST='$CI_NO_TEST'"
ci_info "environment option: \$CI_NO_CLEAN='$CI_NO_CLEAN'"
# Avoid using the CI_ variables that cannot be customized reliably.
[[ ! $CI_CONFIGURE_VARS ]] || ci_err "unexpected: \$CI_CONFIGURE_VARS='$CI_CONFIGURE_VARS'"
[[ ! $CI_MAKE_VARS ]] || ci_err "unexpected: \$CI_MAKE_VARS='$CI_MAKE_VARS'"
}
function ci_build_autotools {
# Initialize the configure environment.
[[ $CI_CC ]] && export CC="$CI_CC"
[[ $CI_CC_FLAGS ]] && export CFLAGS="$CI_CC_FLAGS"
[[ $CI_SANITIZERS ]] && export CFLAGS="-fsanitize=$CI_SANITIZERS -O2 $CFLAGS"
# Build.
ci_spawn rm -fr "$CI_BUILDDIR"
ci_spawn mkdir -p "$CI_BUILDDIR"
ci_spawn cd "$CI_BUILDDIR"
ci_spawn "$CI_SRCDIR/configure" $CI_CONFIGURE_FLAGS
ci_spawn "$CI_MAKE" $CI_MAKE_FLAGS
[[ $CI_NO_TEST ]] || ci_spawn "$CI_MAKE" $CI_MAKE_FLAGS test
[[ $CI_NO_CLEAN ]] || ci_spawn "$CI_MAKE" $CI_MAKE_FLAGS clean
[[ $CI_NO_CLEAN ]] || ci_spawn "$CI_MAKE" $CI_MAKE_FLAGS distclean
ci_info "success!"
}
ci_init_autotools
[[ ! $* ]] || {
ci_info "note: this program accepts environment options only"
ci_err "unexpected command arguments: '$*'"
}
ci_build_autotools

95
scripts/ci_cmake.sh Executable file
View File

@ -0,0 +1,95 @@
#!/usr/bin/env bash
set -e
# ci_cmake.sh
# Continuously integrate libpng using CMake.
#
# Copyright (c) 2019-2020 Cosmin Truta.
#
# This software is released under the libpng license.
# For conditions of distribution and use, see the disclaimer and license
# in png.h.
CI_SCRIPTNAME="$(basename "$0")"
CI_SCRIPTDIR="$(cd "$(dirname "$0")" && pwd)"
CI_SRCDIR="$(dirname "$CI_SCRIPTDIR")"
CI_BUILDDIR="$CI_SRCDIR/out/cmake.build"
function ci_info {
printf >&2 "%s: %s\\n" "$CI_SCRIPTNAME" "$*"
}
function ci_err {
printf >&2 "%s: error: %s\\n" "$CI_SCRIPTNAME" "$*"
exit 2
}
function ci_spawn {
printf >&2 "%s: executing:" "$CI_SCRIPTNAME"
printf >&2 " %q" "$@"
printf >&2 "\\n"
"$@"
}
function ci_init_cmake {
# Initialize the CI_ variables with default values, where applicable.
CI_CMAKE="${CI_CMAKE:-cmake}"
CI_CTEST="${CI_CTEST:-ctest}"
[[ $(uname -s || echo unknown) == Darwin ]] && CI_CC="${CI_CC:-clang}"
CI_CMAKE_BUILD_TYPE="${CI_CMAKE_BUILD_TYPE:-Release}"
# Print the CI_ variables.
ci_info "source directory: $CI_SRCDIR"
ci_info "build directory: $CI_BUILDDIR"
ci_info "environment option: \$CI_CMAKE='$CI_CMAKE'"
ci_info "environment option: \$CI_CMAKE_GENERATOR='$CI_CMAKE_GENERATOR'"
ci_info "environment option: \$CI_CMAKE_GENERATOR_PLATFORM='$CI_CMAKE_GENERATOR_PLATFORM'"
ci_info "environment option: \$CI_CMAKE_BUILD_TYPE='$CI_CMAKE_BUILD_TYPE'"
ci_info "environment option: \$CI_CMAKE_BUILD_FLAGS='$CI_CMAKE_BUILD_FLAGS'"
ci_info "environment option: \$CI_CMAKE_VARS='$CI_CMAKE_VARS'"
ci_info "environment option: \$CI_CTEST='$CI_CTEST'"
ci_info "environment option: \$CI_CTEST_FLAGS='$CI_CTEST_FLAGS'"
ci_info "environment option: \$CI_CC='$CI_CC'"
ci_info "environment option: \$CI_CC_FLAGS='$CI_CC_FLAGS'"
ci_info "environment option: \$CI_SANITIZERS='$CI_SANITIZERS'"
ci_info "environment option: \$CI_NO_TEST='$CI_NO_TEST'"
ci_info "environment option: \$CI_NO_CLEAN='$CI_NO_CLEAN'"
}
function ci_build_cmake {
# Initialize the CMake environment.
[[ $CI_CMAKE_GENERATOR ]] &&
export CMAKE_GENERATOR="$CI_CMAKE_GENERATOR"
[[ $CI_CMAKE_GENERATOR_PLATFORM ]] &&
export CMAKE_GENERATOR_PLATFORM="$CI_CMAKE_GENERATOR_PLATFORM"
# Initialize ALL_CC_FLAGS as a string.
local ALL_CC_FLAGS="$CI_CC_FLAGS"
[[ $CI_SANITIZERS ]] && ALL_CC_FLAGS="-fsanitize=$CI_SANITIZERS $ALL_CC_FLAGS"
# Initialize ALL_CMAKE_VARS as an array;
# expand CI_CMAKE_VARS at the end of ALL_CMAKE_VARS.
local -a ALL_CMAKE_VARS=()
[[ $CI_CC ]] && ALL_CMAKE_VARS+=("-DCMAKE_C_COMPILER=$CI_CC")
[[ $ALL_CC_FLAGS ]] && ALL_CMAKE_VARS+=("-DCMAKE_C_FLAGS=$ALL_CC_FLAGS")
ALL_CMAKE_VARS+=("-DCMAKE_BUILD_TYPE=$CI_CMAKE_BUILD_TYPE")
ALL_CMAKE_VARS+=("-DCMAKE_VERBOSE_MAKEFILE=ON")
ALL_CMAKE_VARS+=($CI_CMAKE_VARS)
# Build.
ci_spawn "$(command -v "$CI_CMAKE")" --version
ci_spawn "$(command -v "$CI_CTEST")" --version
ci_spawn "$CI_CMAKE" -E remove_directory "$CI_BUILDDIR"
ci_spawn "$CI_CMAKE" -E make_directory "$CI_BUILDDIR"
ci_spawn cd "$CI_BUILDDIR"
ci_spawn "$CI_CMAKE" "${ALL_CMAKE_VARS[@]}" "$CI_SRCDIR"
ci_spawn "$CI_CMAKE" --build . --config "$CI_CMAKE_BUILD_TYPE" $CI_CMAKE_BUILD_FLAGS
[[ $CI_NO_TEST ]] ||
ci_spawn "$CI_CTEST" --build-config "$CI_CMAKE_BUILD_TYPE" $CI_CTEST_FLAGS
[[ $CI_NO_CLEAN ]] ||
ci_spawn "$CI_CMAKE" --build . --config "$CI_CMAKE_BUILD_TYPE" $CI_CMAKE_BUILD_FLAGS --target clean
ci_info "success!"
}
ci_init_cmake
[[ ! $* ]] || {
ci_info "note: this program accepts environment options only"
ci_err "unexpected command arguments: '$*'"
}
ci_build_cmake

100
scripts/ci_legacy.sh Executable file
View File

@ -0,0 +1,100 @@
#!/usr/bin/env bash
set -e
# ci_legacy.sh
# Continuously integrate libpng using the legacy makefiles.
#
# Copyright (c) 2019-2020 Cosmin Truta.
#
# This software is released under the libpng license.
# For conditions of distribution and use, see the disclaimer and license
# in png.h.
CI_SCRIPTNAME="$(basename "$0")"
CI_SCRIPTDIR="$(cd "$(dirname "$0")" && pwd)"
CI_SRCDIR="$(dirname "$CI_SCRIPTDIR")"
CI_BUILDDIR="$CI_SRCDIR"
function ci_info {
printf >&2 "%s: %s\\n" "$CI_SCRIPTNAME" "$*"
}
function ci_err {
printf >&2 "%s: error: %s\\n" "$CI_SCRIPTNAME" "$*"
exit 2
}
function ci_spawn {
printf >&2 "%s: executing:" "$CI_SCRIPTNAME"
printf >&2 " %q" "$@"
printf >&2 "\\n"
"$@"
}
function ci_init_legacy {
# Initialize the CI_ variables with default values, where applicable.
CI_MAKE="${CI_MAKE:-make}"
[[ $(uname -s || echo unknown) == Darwin ]] && CI_CC="${CI_CC:-clang}"
[[ $CI_CC == *clang* ]] &&
CI_LEGACY_MAKEFILES="${CI_LEGACY_MAKEFILES:-scripts/makefile.clang}"
CI_LEGACY_MAKEFILES="${CI_LEGACY_MAKEFILES:-scripts/makefile.gcc}"
CI_LD="${CI_LD:-$CI_CC}"
CI_LIBS="${CI_LIBS:--lz -lm}"
# Print the CI_ variables.
ci_info "source directory: $CI_SRCDIR"
ci_info "build directory: $CI_BUILDDIR"
ci_info "environment option: \$CI_LEGACY_MAKEFILES='$CI_LEGACY_MAKEFILES'"
ci_info "environment option: \$CI_MAKE='$CI_MAKE'"
ci_info "environment option: \$CI_MAKE_FLAGS='$CI_MAKE_FLAGS'"
ci_info "environment option: \$CI_MAKE_VARS='$CI_MAKE_VARS'"
ci_info "environment option: \$CI_CC='$CI_CC'"
ci_info "environment option: \$CI_CC_FLAGS='$CI_CC_FLAGS'"
ci_info "environment option: \$CI_CPP='$CI_CPP'"
ci_info "environment option: \$CI_CPP_FLAGS='$CI_CPP_FLAGS'"
ci_info "environment option: \$CI_LD='$CI_LD'"
ci_info "environment option: \$CI_LD_FLAGS='$CI_LD_FLAGS'"
ci_info "environment option: \$CI_LIBS='$CI_LIBS'"
ci_info "environment option: \$CI_SANITIZERS='$CI_SANITIZERS'"
ci_info "environment option: \$CI_NO_TEST='$CI_NO_TEST'"
ci_info "environment option: \$CI_NO_CLEAN='$CI_NO_CLEAN'"
}
function ci_build_legacy {
# Initialize ALL_CC_FLAGS and ALL_LD_FLAGS as strings.
local ALL_CC_FLAGS="$CI_CC_FLAGS"
local ALL_LD_FLAGS="$CI_LD_FLAGS"
[[ $CI_SANITIZERS ]] && {
ALL_CC_FLAGS="-fsanitize=$CI_SANITIZERS -O2 $ALL_CC_FLAGS"
ALL_LD_FLAGS="-fsanitize=$CI_SANITIZERS $ALL_LD_FLAGS"
}
# Initialize ALL_MAKE_ARGS as an array;
# expand CI_MAKE_FLAGS at the beginning and CI_MAKE_VARS at the end.
local -a ALL_MAKE_ARGS=()
ALL_MAKE_ARGS+=($CI_MAKE_FLAGS)
[[ $CI_CC ]] && ALL_MAKE_ARGS+=("CC=$CI_CC")
[[ $ALL_CC_FLAGS ]] && ALL_MAKE_ARGS+=("CFLAGS=$ALL_CC_FLAGS")
[[ $CI_CPP ]] && ALL_MAKE_ARGS+=("CPP=$CI_CPP")
[[ $CI_CPP_FLAGS ]] && ALL_MAKE_ARGS+=("CPPFLAGS=$CI_CPP_FLAGS")
[[ $CI_LD ]] && ALL_MAKE_ARGS+=("LD=$CI_LD")
[[ $ALL_LD_FLAGS ]] && ALL_MAKE_ARGS+=("LDFLAGS=$ALL_LD_FLAGS")
ALL_MAKE_ARGS+=("LIBS=$CI_LIBS")
ALL_MAKE_ARGS+=($CI_MAKE_VARS)
# Build.
ci_spawn cd "$CI_SRCDIR"
[[ $CI_LEGACY_MAKEFILES ]] || ci_err "bad or missing: \$CI_LEGACY_MAKEFILES"
local MY_MAKEFILE
for MY_MAKEFILE in $CI_LEGACY_MAKEFILES
do
ci_spawn "$CI_MAKE" "${ALL_MAKE_ARGS[@]}" -f $MY_MAKEFILE
[[ $CI_NO_TEST ]] || ci_spawn "$CI_MAKE" "${ALL_MAKE_ARGS[@]}" -f $MY_MAKEFILE test
[[ $CI_NO_CLEAN ]] || ci_spawn "$CI_MAKE" "${ALL_MAKE_ARGS[@]}" -f $MY_MAKEFILE clean
done
ci_info "success!"
}
ci_init_legacy
[[ ! $* ]] || {
ci_info "note: this program accepts environment options only"
ci_err "unexpected command arguments: '$*'"
}
ci_build_legacy