From b557f84d04e7d36aa0db4b4c9cf6b2e2b77e2158 Mon Sep 17 00:00:00 2001 From: Timothy Poon Date: Fri, 5 Sep 2025 07:56:47 +0100 Subject: [PATCH 01/16] Add option to display version --- src/main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index a244ea0..dc2a62f 100644 --- a/src/main.c +++ b/src/main.c @@ -12,6 +12,7 @@ // long options structure for getopt_long static const struct option long_options[] = { {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'v'}, {"no-metadata", no_argument, NULL, 'N'}, {"with-metadata", no_argument, NULL, 'M'}, {"output-dir", required_argument, NULL, 'o'}, @@ -40,6 +41,7 @@ static void print_usage(const char *program_name) fprintf(stderr, " - NOT YET IMPLEMENTED\n"); fprintf(stderr, " -t, --timeout SECS Timeout in seconds\n"); fprintf(stderr, " - NOT YET IMPLEMENTED\n"); + fprintf(stderr, " -v, --version Display the version\n"); fprintf(stderr, " -h, --help Show this help message\n"); fprintf(stderr, "\nEnvironment variables:\n"); fprintf(stderr, " MIB2H5_SHUFFLE Shuffle level for Blosc compression (default: 2)\n"); @@ -61,7 +63,7 @@ int main(int argc, char *argv[]) // parse options int option_index = 0; - while ((opt = getopt_long(argc, argv, "o:d:k:r:t:cMNh", long_options, + while ((opt = getopt_long(argc, argv, "o:d:k:r:t:cMNvh", long_options, &option_index)) != -1) { switch (opt) { case 'o': @@ -94,6 +96,10 @@ int main(int argc, char *argv[]) case 'N': include_metadata = false; break; + case 'v': + printf("%d.%d.%d\n", MIB2H5_VERSION_MAJOR, MIB2H5_VERSION_MINOR, + MIB2H5_VERSION_PATCH); + return 0; case 'h': print_usage(argv[0]); return 0; From 378e7829ab743fa057b4896fb8e63e74f675fa98 Mon Sep 17 00:00:00 2001 From: Timothy Poon Date: Fri, 5 Sep 2025 09:18:31 +0100 Subject: [PATCH 02/16] Display the actual specified path to find hdf5 library --- configure.ac | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 8685105..d1bde56 100644 --- a/configure.ac +++ b/configure.ac @@ -28,7 +28,7 @@ AC_ARG_WITH([hdf5], HDF5_OK=no AS_IF([test -n "$HDFDIR"], [ - AC_MSG_NOTICE([Test HDFDIR provided]) + AC_MSG_NOTICE([Testing HDF5 at $HDFDIR]) CPPFLAGS="$CPPFLAGS -I$HDFDIR/include" LDFLAGS="$LDFLAGS -L$HDFDIR/lib" @@ -37,13 +37,13 @@ AS_IF([test -n "$HDFDIR"], [ AC_DEFINE([HAVE_HDF5], [1], [Define if HDF5 is available]) HDF5_OK=yes ], [ - AC_MSG_NOTICE([libhdf5 not found on HDFDIR]) + AC_MSG_NOTICE([libhdf5 not found at $HDFDIR/lib]) AS_VAR_SET([CPPFLAGS], [`echo "$CPPFLAGS" | sed "s|-I$HDFDIR/include||g"`]) AS_VAR_SET([LDFLAGS], [`echo "$LDFLAGS" | sed "s|-L$HDFDIR/lib||g"`]) HDF5_OK=no ]) ], [ - AC_MSG_NOTICE([hdf5.h not found on HDFDIR]) + AC_MSG_NOTICE([hdf5.h not found at $HDFDIR/include]) AS_VAR_SET([CPPFLAGS], [`echo "$CPPFLAGS" | sed "s|-I$HDFDIR/include||g"`]) AS_VAR_SET([LDFLAGS], [`echo "$LDFLAGS" | sed "s|-L$HDFDIR/lib||g"`]) HDF5_OK=no @@ -84,11 +84,13 @@ if test "x$HDF5_OK" != xyes; then HDFDIR="$dir" AC_MSG_NOTICE([HDF5 found in $HDFDIR]) ], [ + AC_MSG_NOTICE([libhdf5 not found at $dir/lib]) AS_VAR_SET([CPPFLAGS], [`echo "$CPPFLAGS" | sed "s|-I$dir/include||g"`]) AS_VAR_SET([LDFLAGS], [`echo "$LDFLAGS" | sed "s|-L$dir/lib||g; s|-Wl,-rpath,$dir/lib||g"`]) HDF5_OK=no ]) ], [ + AC_MSG_NOTICE([hdf5.h not found at $dir/include]) AS_VAR_SET([CPPFLAGS], [`echo "$CPPFLAGS" | sed "s|-I$dir/include||g"`]) AS_VAR_SET([LDFLAGS], [`echo "$LDFLAGS" | sed "s|-L$dir/lib||g; s|-Wl,-rpath,$dir/lib||g"`]) HDF5_OK=no From be60c4471608838ce13e69e5958fab185212901c Mon Sep 17 00:00:00 2001 From: Timothy Poon Date: Fri, 5 Sep 2025 23:31:48 +0100 Subject: [PATCH 03/16] Fail configuration when the explicit path specified is invalid --- configure.ac | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index d1bde56..76c92e6 100644 --- a/configure.ac +++ b/configure.ac @@ -37,16 +37,10 @@ AS_IF([test -n "$HDFDIR"], [ AC_DEFINE([HAVE_HDF5], [1], [Define if HDF5 is available]) HDF5_OK=yes ], [ - AC_MSG_NOTICE([libhdf5 not found at $HDFDIR/lib]) - AS_VAR_SET([CPPFLAGS], [`echo "$CPPFLAGS" | sed "s|-I$HDFDIR/include||g"`]) - AS_VAR_SET([LDFLAGS], [`echo "$LDFLAGS" | sed "s|-L$HDFDIR/lib||g"`]) - HDF5_OK=no + AC_MSG_ERROR([libhdf5 not found at $HDFDIR/lib]) ]) ], [ - AC_MSG_NOTICE([hdf5.h not found at $HDFDIR/include]) - AS_VAR_SET([CPPFLAGS], [`echo "$CPPFLAGS" | sed "s|-I$HDFDIR/include||g"`]) - AS_VAR_SET([LDFLAGS], [`echo "$LDFLAGS" | sed "s|-L$HDFDIR/lib||g"`]) - HDF5_OK=no + AC_MSG_ERROR([hdf5.h not found at $HDFDIR/include]) ]) ]) From e27eafb6456e0c41969e2901f52e5d83cf233b1f Mon Sep 17 00:00:00 2001 From: Timothy Poon Date: Fri, 5 Sep 2025 23:32:56 +0100 Subject: [PATCH 04/16] Remove redundant AC message --- configure.ac | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.ac b/configure.ac index 76c92e6..935950c 100644 --- a/configure.ac +++ b/configure.ac @@ -63,7 +63,6 @@ AS_IF([test "x$HDF5_OK" != xyes], [ ]) if test "x$HDF5_OK" != xyes; then - AC_MSG_NOTICE([--with-hdf5 not provided, checking common HDF5 environment variables...]) for var in HDF5_ROOT HDF5_HOME HDF5_DIR; do eval dir=\$$var if test -n "$dir"; then From 5b2b7343628cf5bc30c7c77f633dd707c6695303 Mon Sep 17 00:00:00 2001 From: Timothy Poon Date: Fri, 5 Sep 2025 23:33:49 +0100 Subject: [PATCH 05/16] Provide guidance for users with information about honoured paths --- configure.ac | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 935950c..98a7f42 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,8 @@ AC_ARG_ENABLE([asan], # --- Check for HDF5 --- AC_ARG_WITH([hdf5], - [AS_HELP_STRING([--with-hdf5=PATH], [Path to HDF5 installation])], + [AS_HELP_STRING([--with-hdf5=PATH], + [Path to HDF5 installation. If not specified, searches in order: system paths, $HDF5_ROOT, $HDF5_HOME, $HDF5_DIR])], [HDFDIR="$withval"], []) @@ -94,7 +95,7 @@ if test "x$HDF5_OK" != xyes; then fi AS_IF([test "x$HDF5_OK" != xyes], [ - AC_MSG_ERROR([HDF5 not found]) + AC_MSG_ERROR([HDF5 not found. Use --with-hdf5=/path or set HDF5_ROOT, HDF5_HOME, or HDF5_DIR]) ]) # ---------------- Compression Option ---------------- From e958ddb68802988e52ffb5073926120d84a54179 Mon Sep 17 00:00:00 2001 From: Timothy Poon Date: Fri, 5 Sep 2025 23:34:22 +0100 Subject: [PATCH 06/16] Add summary about where HDF5 is found for clarity --- configure.ac | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/configure.ac b/configure.ac index 98a7f42..b497bea 100644 --- a/configure.ac +++ b/configure.ac @@ -212,3 +212,12 @@ AS_IF([test "x$asan_build" = "xyes"], [ AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT + +# --- Configuration Summary --- +AS_IF([test "x$HDF5_OK" = xyes], [ + AS_IF([test -n "$HDFDIR"], [ + AC_MSG_NOTICE([HDF5 library found at: $HDFDIR]) + ], [ + AC_MSG_NOTICE([HDF5 library found in system paths]) + ]) +]) From 21dc1a1bb087e7b72eccdc0e0a6628d570cef208 Mon Sep 17 00:00:00 2001 From: Timothy Poon Date: Fri, 5 Sep 2025 23:35:04 +0100 Subject: [PATCH 07/16] Be more specific about the discovery of HDF5 library --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d37fe57..eea4de2 100644 --- a/README.md +++ b/README.md @@ -88,9 +88,13 @@ The configure script supports several options: ##### HDF5 Location -- `--with-hdf5=/path/to/hdf5` -- It also recognises the environment variables `HDF5_ROOT`, `HDF5_HOME` -and `HDF5_DIR` +- `--with-hdf5=/path/to/hdf5`: Specify HDF5 installation path +- If not specified, the configure script searches for HDF5 in the following +order: + 1. System paths (standard locations) + 2. `$HDF5_ROOT` + 3. `$HDF5_HOME` + 4. `$HDF5_DIR` ##### Compression Support From 1c672700171fa823fb611fdd4536074536a9839f Mon Sep 17 00:00:00 2001 From: Timothy Poon Date: Fri, 5 Sep 2025 23:45:45 +0100 Subject: [PATCH 08/16] Add initial test script for building with Autotool for C --- tests/test_build/test_build_c.sh | 338 +++++++++++++++++++++++++++++++ 1 file changed, 338 insertions(+) create mode 100755 tests/test_build/test_build_c.sh diff --git a/tests/test_build/test_build_c.sh b/tests/test_build/test_build_c.sh new file mode 100755 index 0000000..c5c1718 --- /dev/null +++ b/tests/test_build/test_build_c.sh @@ -0,0 +1,338 @@ +#!/usr/bin/env bash +set -euo pipefail + +# constants +readonly script_dir="$(dirname "$(readlink -f "$0")")" +readonly project_root="$(cd "$script_dir/../.." && pwd)" +readonly log_dir="$script_dir/logs" + +# version requirements +readonly min_gcc_version=7 +readonly min_autoconf_major=2 +readonly min_autoconf_minor=64 + +total_tests=0 +passed_tests=0 +skipped_tests=0 +failed_tests=0 +hdf5_test_path="${HDF5_TEST_PATH:-}" +test_filter="all" + +cleanup() { + cd "$project_root" 2>/dev/null || true + if [[ -f Makefile ]]; then + make distclean >/dev/null 2>&1 || true + fi +} + +# register cleanup on exit +trap cleanup EXIT + +check_prerequisites() { + local errors=0 + + # check gcc + if ! command -v gcc >/dev/null 2>&1; then + echo "ERROR: gcc not found" + errors=$((errors + 1)) + else + local gcc_version + gcc_version=$(gcc -dumpversion | cut -d. -f1) + if [[ "$gcc_version" -lt $min_gcc_version ]]; then + echo "ERROR: gcc version $gcc_version < $min_gcc_version" + errors=$((errors + 1)) + fi + fi + + # check autoconf + if ! command -v autoconf >/dev/null 2>&1; then + echo "ERROR: autoconf not found" + errors=$((errors + 1)) + else + local autoconf_version + autoconf_version=$(autoconf --version | head -n1 | grep -oE '[0-9]+\.[0-9]+' | head -n1) + local major minor + IFS='.' read -r major minor <<< "$autoconf_version" + if [[ "$major" -eq $min_autoconf_major && "$minor" -lt $min_autoconf_minor ]]; then + echo "ERROR: autoconf version $autoconf_version < $min_autoconf_major.$min_autoconf_minor" + errors=$((errors + 1)) + fi + fi + + # check automake + if ! command -v automake >/dev/null 2>&1; then + echo "ERROR: automake not found" + errors=$((errors + 1)) + fi + + # no error should return exit code 0 to indicate success + return "$errors" +} + +# check if test should be run based on filter +should_run_test() { + local test_name="$1" + local filter="$2" + [[ "$filter" == "all" ]] || [[ "$filter" == "$test_name" ]] +} + +# run test in an isolated environment +run_isolated_test() { + local test_name="$1" + local configure_cmd="$2" + local env_setup="${3:-}" + + total_tests=$((total_tests + 1)) + echo -n "Test: $test_name... " + + # run in subshell for complete isolation + if ( + # clear all HDF5 env vars first + unset HDF5_ROOT HDF5_HOME HDF5_DIR + # apply test-specific environment if provided + if [[ -n "$env_setup" ]]; then + # parse space-separated var=value pairs + local -a env_pairs + IFS=' ' read -ra env_pairs <<< "$env_setup" + for pair in "${env_pairs[@]}"; do + # strip 'export ' if present + pair="${pair#export }" + # only export valid var=value pairs + if [[ "$pair" == *=* ]]; then + export "$pair" + fi + done + fi + # run the actual test + run_test_internal "$test_name" "$configure_cmd" + ); then + passed_tests=$((passed_tests + 1)) + else + failed_tests=$((failed_tests + 1)) + fi +} + +# actual test runner +run_test_internal() { + local test_name="$1" + local configure_cmd="$2" + local log_file="$log_dir/${test_name}.log" + + # clean previous build + cleanup + + # parse the command into an array + local -a cmd_array + IFS=' ' read -ra cmd_array <<< "$configure_cmd" + + # run configure (from an array of arguments) + if ! (cd "$project_root" && "${cmd_array[@]}" >>"$log_file" 2>&1); then + # attempt to extract the actual error message + local error_line=$(grep -E "error:|not found at" "$log_file" | tail -1 | sed 's/^configure: //') + if [[ -n "$error_line" ]]; then + echo "FAIL ($error_line)" + else + echo "FAIL (configure)" + fi + return 1 + fi + + # make + if ! (cd "$project_root" && make >>"$log_file" 2>&1); then + # attempt to extract make error + local error_line=$(grep -E "^make.*Error|error:" "$log_file" | tail -1 | head -c 60) + if [[ -n "$error_line" ]]; then + echo "FAIL (make: $error_line...)" + else + echo "FAIL (make)" + fi + return 1 + fi + + # test executable + local mib2h5="$project_root/src/mib2h5" + if [[ ! -f "$mib2h5" ]]; then + echo "FAIL (executable mib2h5 not found)" + return 1 + fi + + # determine hdf5 library path for LD_LIBRARY_PATH + local hdf5_lib="" + if [[ -n "${HDF5_ROOT:-}" ]]; then + hdf5_lib="$HDF5_ROOT" + elif [[ -n "${HDF5_HOME:-}" ]]; then + hdf5_lib="$HDF5_HOME" + elif [[ -n "${HDF5_DIR:-}" ]]; then + hdf5_lib="$HDF5_DIR" + elif [[ -n "$hdf5_test_path" ]] && [[ "$test_name" == "explicit_path" ]]; then + hdf5_lib="$hdf5_test_path" + fi + + local ld_path="" + if [[ -n "$hdf5_lib" ]]; then + ld_path="LD_LIBRARY_PATH=$hdf5_lib/lib:${LD_LIBRARY_PATH:-}" + fi + + # test basic commands + if ! (cd "$project_root" && env "$ld_path" "$mib2h5" --version >>"$log_file" 2>&1); then + echo "FAIL (--version)" + return 1 + fi + + if ! (cd "$project_root" && env "$ld_path" "$mib2h5" --help >>"$log_file" 2>&1); then + echo "FAIL (--help)" + return 1 + fi + + echo "PASS" + return 0 +} + + +main() { + # parse arguments + case "${1:-}" in + --clean) + echo "Cleaning build artefacts..." + cleanup + rm -rf "$log_dir" + echo "Done" + exit 0 + ;; + --list) + echo "Available tests:" + echo " system - Test with system HDF5 installation" + echo " explicit - Test with explicit --with-hdf5 path (requires HDF5_TEST_PATH)" + echo " hdf5_root - Test with HDF5_ROOT environment variable" + echo " hdf5_home - Test with HDF5_HOME environment variable" + echo " hdf5_dir - Test with HDF5_DIR environment variable" + echo "" + echo "Usage:" + echo " $0 # Run all tests" + echo " $0 --only TEST # Run specific test" + echo " $0 --list # Show this list" + echo " $0 --clean # Clean build artefacts" + exit 0 + ;; + --only) + if [[ -z "${2:-}" ]]; then + echo "Error: --only requires a test name" + echo "Use --list to see available tests" + exit 1 + fi + test_filter="$2" + ;; + *) + if [[ -n "${1:-}" ]]; then + echo "Unknown option: $1" + echo "Use --list to see available options" + exit 1 + fi + ;; + esac + + echo "=== C Build Tests ===" + if [[ "$test_filter" != "all" ]]; then + echo "Running only: $test_filter" + fi + echo + + # check prerequisites + echo -n "Prerequisites check... " + if check_prerequisites >/dev/null 2>&1; then + echo "OK" + else + echo "FAIL" + # re-run to show stdout + check_prerequisites + exit 1 + fi + echo + + # create log directory + mkdir -p "$log_dir" + + # run autoreconf once + echo -n "Running autoreconf -i... " + if (cd "$project_root" && autoreconf -i >/dev/null 2>&1); then + echo "OK" + else + echo "FAIL" + exit 1 + fi + echo + + # test 1: system hdf5 + if should_run_test "system" "$test_filter"; then + run_isolated_test "system_hdf5" "./configure" "" + fi + + # test 2: explicit path + if should_run_test "explicit" "$test_filter"; then + if [[ -n "$hdf5_test_path" ]]; then + run_isolated_test "explicit_path" "./configure --with-hdf5=$hdf5_test_path" "" + else + skipped_tests=$((skipped_tests + 1)) + echo "Test: explicit_path... SKIP (set HDF5_TEST_PATH to test)" + fi + fi + + # test 3: hdf5_root environment variable + if should_run_test "hdf5_root" "$test_filter"; then + if [[ -n "${HDF5_ROOT:-}" ]]; then + run_isolated_test "hdf5_root" "./configure" "HDF5_ROOT=$HDF5_ROOT" || true + else + skipped_tests=$((skipped_tests + 1)) + echo "Test: hdf5_root... SKIP (HDF5_ROOT not set)" + fi + fi + + # test 4: hdf5_home environment variable + if should_run_test "hdf5_home" "$test_filter"; then + if [[ -n "${HDF5_HOME:-}" ]]; then + run_isolated_test "hdf5_home" "./configure" "HDF5_HOME=$HDF5_HOME" || true + else + skipped_tests=$((skipped_tests + 1)) + echo "Test: hdf5_home... SKIP (HDF5_HOME not set)" + fi + fi + + # test 5: hdf5_dir environment variable + if should_run_test "hdf5_dir" "$test_filter"; then + if [[ -n "${HDF5_DIR:-}" ]]; then + run_isolated_test "hdf5_dir" "./configure" "HDF5_DIR=$HDF5_DIR" || true + else + skipped_tests=$((skipped_tests + 1)) + echo "Test: hdf5_dir... SKIP (HDF5_DIR not set)" + fi + fi + + # summary + echo + + # handle case where no tests ran + if [[ $total_tests -eq 0 ]] && [[ $skipped_tests -gt 0 ]]; then + echo "Tests run: 0, Skipped: $skipped_tests" + echo "No tests were run. Check --list for available tests." + exit 0 + fi + + # normal summary + echo "Tests: $passed_tests/$total_tests passed" + if [[ $skipped_tests -gt 0 ]]; then + echo "Skipped: $skipped_tests" + fi + + if [[ $failed_tests -eq 0 ]]; then + if [[ $total_tests -gt 0 ]]; then + echo "All tests passed!" + fi + exit 0 + else + echo "Failed: $failed_tests" + echo "Check logs in: $log_dir" + exit 1 + fi +} + +main "$@" From 1023357d7fef7d3647f2705000c1ddc991b26260 Mon Sep 17 00:00:00 2001 From: Timothy Poon Date: Sat, 13 Sep 2025 11:26:21 +0100 Subject: [PATCH 09/16] Add initial GH action to test building with autotools from C source --- .github/workflows/test-build-c.yml | 190 +++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 .github/workflows/test-build-c.yml diff --git a/.github/workflows/test-build-c.yml b/.github/workflows/test-build-c.yml new file mode 100644 index 0000000..1308b81 --- /dev/null +++ b/.github/workflows/test-build-c.yml @@ -0,0 +1,190 @@ +name: C Build Tests + +on: + push: + branches: [main, dev] + pull_request: + workflow_dispatch: + +jobs: + # build different hdf5 artefacts + build-hdf5: + runs-on: ubuntu-latest + timeout-minutes: 30 + strategy: + matrix: + include: + - name: system + prefix: /usr/local + artefact-name: hdf5-system + - name: custom + prefix: /opt/hdf5 + artefact-name: hdf5-custom + container: gcc:7 + name: Build HDF5 - ${{ matrix.name }} + steps: + - name: Install build dependencies + run: apt update && apt install -y wget + + - name: Cache HDF5 build + id: cache-hdf5 + uses: actions/cache@v4 + with: + path: /tmp/${{ matrix.artefact-name }} + key: hdf5-1.14.6-${{ matrix.name }}-gcc7-${{ runner.os }}-v1 + restore-keys: | + hdf5-1.14.6-${{ matrix.name }}-gcc7-${{ runner.os }}- + hdf5-1.14.6-${{ matrix.name }}-gcc7- + + - name: Download and build HDF5 + if: steps.cache-hdf5.outputs.cache-hit != 'true' + run: | + # use HDF5 1.14.x + wget https://github.com/HDFGroup/hdf5/releases/download/hdf5_1.14.6/hdf5-1.14.6.tar.gz + tar -xzf hdf5-1.14.6.tar.gz + cd hdf5-1.14.6 + + # configure for specified prefix + ./configure --prefix=${{ matrix.prefix }} + make -j$(nproc) + + # staged for artefact + make install DESTDIR=/tmp/${{ matrix.artefact-name }} + + - name: Create tarball artefact + run: | + cd /tmp/${{ matrix.artefact-name }} + tar -czf /tmp/${{ matrix.artefact-name }}.tar.gz . + + - name: Upload HDF5 artefact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.artefact-name }} + path: /tmp/${{ matrix.artefact-name }}.tar.gz + retention-days: 7 + compression-level: 0 + + # test gcc 7-14 + test-gcc-versions: + needs: build-hdf5 + runs-on: ubuntu-latest + timeout-minutes: 15 + strategy: + fail-fast: false + matrix: + gcc-version: [7, 8, 9, 10, 11, 12, 13, 14] + container: gcc:${{ matrix.gcc-version }} + name: GCC ${{ matrix.gcc-version }} - system-wide installation + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Download HDF5 system artefact + uses: actions/download-artifact@v4 + with: + name: hdf5-system + + - name: Install HDF5 system-wide + run: | + tar -xzf hdf5-system.tar.gz -C / + ldconfig + + - name: Install build dependencies + run: | + apt update + apt install -y autoconf automake libtool pkg-config + + - name: Generate configure script + run: autoreconf -i + + - name: Run build test + run: | + ./tests/test_build/test_build_c.sh --only system + + - name: Upload test logs on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: logs-gcc-${{ matrix.gcc-version }}-system + path: tests/test_build/logs/ + retention-days: 7 + + # test different methods of specifying HDF5 + test-hdf5-methods: + needs: build-hdf5 + runs-on: ubuntu-latest + timeout-minutes: 15 + strategy: + fail-fast: false + matrix: + include: + # system-wide + - method: system + artefact: hdf5-system + test-name: system + setup: "" + lib-path: "" + description: "system-wide HDF5 at /usr/local" + + # explicit path + - method: explicit + artefact: hdf5-custom + test-name: explicit + setup: "export HDF5_TEST_PATH=/opt/hdf5" + lib-path: /opt/hdf5/lib + description: "explicit --with-hdf5=/opt/hdf5" + + # via environment variable + - method: env_var + artefact: hdf5-custom + test-name: hdf5_root + setup: "export HDF5_ROOT=/opt/hdf5" + lib-path: /opt/hdf5/lib + description: "environment variable HDF5_ROOT" + + container: gcc:11 + name: HDF5 ${{ matrix.method }} + env: + LD_LIBRARY_PATH: ${{ matrix.lib-path }} + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Download HDF5 artefact + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.artefact }} + + - name: Install HDF5 + run: | + echo "Installing HDF5 for: ${{ matrix.description }}" + tar -xzf ${{ matrix.artefact }}.tar.gz -C / + # update library cache for system-wide installation + if [ "${{ matrix.method }}" = "system" ]; then + ldconfig + fi + + - name: Install build dependencies + run: | + apt update + apt install -y autoconf automake libtool pkg-config + + - name: Generate configure script + run: autoreconf -i + + - name: Run build test + run: | + # set test-specific environment + ${{ matrix.setup }} + + # run test + echo "Testing: ${{ matrix.description }}" + ./tests/test_build/test_build_c.sh --only ${{ matrix.test-name }} + + - name: Upload test logs on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: logs-hdf5-${{ matrix.method }} + path: tests/test_build/logs/ + retention-days: 7 From 1c0b497c7fe6d5260605d87856f4ede16162b513 Mon Sep 17 00:00:00 2001 From: Timothy Poon <62692924+ptim0626@users.noreply.github.com> Date: Sat, 13 Sep 2025 12:28:17 +0100 Subject: [PATCH 10/16] Use apt-get in container script --- .github/workflows/test-build-c.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test-build-c.yml b/.github/workflows/test-build-c.yml index 1308b81..9c21f2f 100644 --- a/.github/workflows/test-build-c.yml +++ b/.github/workflows/test-build-c.yml @@ -24,7 +24,7 @@ jobs: name: Build HDF5 - ${{ matrix.name }} steps: - name: Install build dependencies - run: apt update && apt install -y wget + run: apt-get update && apt-get install -y wget - name: Cache HDF5 build id: cache-hdf5 @@ -91,8 +91,8 @@ jobs: - name: Install build dependencies run: | - apt update - apt install -y autoconf automake libtool pkg-config + apt-get update + apt-get install -y autoconf automake libtool pkg-config - name: Generate configure script run: autoreconf -i @@ -166,8 +166,8 @@ jobs: - name: Install build dependencies run: | - apt update - apt install -y autoconf automake libtool pkg-config + apt-get update + apt-get install -y autoconf automake libtool pkg-config - name: Generate configure script run: autoreconf -i From d0150b4b0d6d9078f629e8a8bcdda46bd1a45b3e Mon Sep 17 00:00:00 2001 From: Timothy Poon <62692924+ptim0626@users.noreply.github.com> Date: Sat, 13 Sep 2025 12:39:15 +0100 Subject: [PATCH 11/16] Add sudo for apt-get --- .github/workflows/test-build-c.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test-build-c.yml b/.github/workflows/test-build-c.yml index 9c21f2f..e1b5628 100644 --- a/.github/workflows/test-build-c.yml +++ b/.github/workflows/test-build-c.yml @@ -24,7 +24,7 @@ jobs: name: Build HDF5 - ${{ matrix.name }} steps: - name: Install build dependencies - run: apt-get update && apt-get install -y wget + run: sudo apt-get update && sudo apt-get install -y wget - name: Cache HDF5 build id: cache-hdf5 @@ -91,8 +91,8 @@ jobs: - name: Install build dependencies run: | - apt-get update - apt-get install -y autoconf automake libtool pkg-config + sudo apt-get update + sudo apt-get install -y autoconf automake libtool pkg-config - name: Generate configure script run: autoreconf -i @@ -166,8 +166,8 @@ jobs: - name: Install build dependencies run: | - apt-get update - apt-get install -y autoconf automake libtool pkg-config + sudo apt-get update + sudo apt-get install -y autoconf automake libtool pkg-config - name: Generate configure script run: autoreconf -i From 6f601dcd29dc2cc8ed585faf9cb7f434b6340b30 Mon Sep 17 00:00:00 2001 From: Timothy Poon <62692924+ptim0626@users.noreply.github.com> Date: Sat, 13 Sep 2025 12:43:48 +0100 Subject: [PATCH 12/16] Format apt-get update and install as two lines --- .github/workflows/test-build-c.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-build-c.yml b/.github/workflows/test-build-c.yml index e1b5628..3f715f4 100644 --- a/.github/workflows/test-build-c.yml +++ b/.github/workflows/test-build-c.yml @@ -24,7 +24,9 @@ jobs: name: Build HDF5 - ${{ matrix.name }} steps: - name: Install build dependencies - run: sudo apt-get update && sudo apt-get install -y wget + run: | + sudo apt-get update + sudo apt-get install -y wget - name: Cache HDF5 build id: cache-hdf5 From 72ecf6328e4cba9c3174199ae2cb72a065ecd886 Mon Sep 17 00:00:00 2001 From: Timothy Poon <62692924+ptim0626@users.noreply.github.com> Date: Sat, 13 Sep 2025 13:13:29 +0100 Subject: [PATCH 13/16] Remove sudo in Docker image --- .github/workflows/test-build-c.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test-build-c.yml b/.github/workflows/test-build-c.yml index 3f715f4..801e202 100644 --- a/.github/workflows/test-build-c.yml +++ b/.github/workflows/test-build-c.yml @@ -25,8 +25,8 @@ jobs: steps: - name: Install build dependencies run: | - sudo apt-get update - sudo apt-get install -y wget + apt-get update + apt-get install -y wget - name: Cache HDF5 build id: cache-hdf5 @@ -93,8 +93,8 @@ jobs: - name: Install build dependencies run: | - sudo apt-get update - sudo apt-get install -y autoconf automake libtool pkg-config + apt-get update + apt-get install -y autoconf automake libtool pkg-config - name: Generate configure script run: autoreconf -i @@ -168,8 +168,8 @@ jobs: - name: Install build dependencies run: | - sudo apt-get update - sudo apt-get install -y autoconf automake libtool pkg-config + apt-get update + apt-get install -y autoconf automake libtool pkg-config - name: Generate configure script run: autoreconf -i From f85866954d69d65c8d7132483ed225afd4edaca8 Mon Sep 17 00:00:00 2001 From: Timothy Poon <62692924+ptim0626@users.noreply.github.com> Date: Sat, 13 Sep 2025 13:40:08 +0100 Subject: [PATCH 14/16] Use archive repositories for gcc <= 10 --- .github/workflows/test-build-c.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/test-build-c.yml b/.github/workflows/test-build-c.yml index 801e202..f1be3e1 100644 --- a/.github/workflows/test-build-c.yml +++ b/.github/workflows/test-build-c.yml @@ -23,6 +23,12 @@ jobs: container: gcc:7 name: Build HDF5 - ${{ matrix.name }} steps: + - name: Use archive repositories for Debian Buster + run: | + sed -i 's|deb.debian.org|archive.debian.org|g' /etc/apt/sources.list + sed -i 's|security.debian.org|archive.debian.org|g' /etc/apt/sources.list + sed -i '/buster-updates/d' /etc/apt/sources.list + - name: Install build dependencies run: | apt-get update @@ -91,6 +97,14 @@ jobs: tar -xzf hdf5-system.tar.gz -C / ldconfig + - name: Use archive repositories for Debian Buster + if: matrix.gcc-version <= 10 + run: | + # gcc 7-10 use debian buster which reached EOL + sed -i 's|deb.debian.org|archive.debian.org|g' /etc/apt/sources.list + sed -i 's|security.debian.org|archive.debian.org|g' /etc/apt/sources.list + sed -i '/buster-updates/d' /etc/apt/sources.list + - name: Install build dependencies run: | apt-get update From d33ef8f79c0460a97e172f09390ce0a2dfce59de Mon Sep 17 00:00:00 2001 From: Timothy Poon <62692924+ptim0626@users.noreply.github.com> Date: Sat, 13 Sep 2025 14:22:32 +0100 Subject: [PATCH 15/16] Avoid passing empty string to env --- tests/test_build/test_build_c.sh | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/tests/test_build/test_build_c.sh b/tests/test_build/test_build_c.sh index c5c1718..66a4ff4 100755 --- a/tests/test_build/test_build_c.sh +++ b/tests/test_build/test_build_c.sh @@ -174,14 +174,28 @@ run_test_internal() { fi # test basic commands - if ! (cd "$project_root" && env "$ld_path" "$mib2h5" --version >>"$log_file" 2>&1); then - echo "FAIL (--version)" - return 1 - fi + if [[ -n "$ld_path" ]]; then + # use env when ld_path is set + if ! (cd "$project_root" && env "$ld_path" "$mib2h5" --version >>"$log_file" 2>&1); then + echo "FAIL (--version)" + return 1 + fi - if ! (cd "$project_root" && env "$ld_path" "$mib2h5" --help >>"$log_file" 2>&1); then - echo "FAIL (--help)" - return 1 + if ! (cd "$project_root" && env "$ld_path" "$mib2h5" --help >>"$log_file" 2>&1); then + echo "FAIL (--help)" + return 1 + fi + else + # run directly when ld_path is empty (system-wide installation) + if ! (cd "$project_root" && "$mib2h5" --version >>"$log_file" 2>&1); then + echo "FAIL (--version)" + return 1 + fi + + if ! (cd "$project_root" && "$mib2h5" --help >>"$log_file" 2>&1); then + echo "FAIL (--help)" + return 1 + fi fi echo "PASS" From 761858b5ee44946795ed7f540bbcc49c8fee69e8 Mon Sep 17 00:00:00 2001 From: Timothy Poon <62692924+ptim0626@users.noreply.github.com> Date: Sat, 13 Sep 2025 14:40:59 +0100 Subject: [PATCH 16/16] Fix gcc docker version with buster --- .github/workflows/test-build-c.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-build-c.yml b/.github/workflows/test-build-c.yml index f1be3e1..38a671f 100644 --- a/.github/workflows/test-build-c.yml +++ b/.github/workflows/test-build-c.yml @@ -98,9 +98,9 @@ jobs: ldconfig - name: Use archive repositories for Debian Buster - if: matrix.gcc-version <= 10 + if: matrix.gcc-version == 7 || matrix.gcc-version == 8 run: | - # gcc 7-10 use debian buster which reached EOL + # gcc 7, 8 use debian buster which reached EOL sed -i 's|deb.debian.org|archive.debian.org|g' /etc/apt/sources.list sed -i 's|security.debian.org|archive.debian.org|g' /etc/apt/sources.list sed -i '/buster-updates/d' /etc/apt/sources.list