From 4e4f255ddf5a44cf31351178ef97a7c1fb5bdb2c Mon Sep 17 00:00:00 2001 From: Sergey Kosukhin <sergey.kosukhin@mpimet.mpg.de> Date: Tue, 12 Jul 2022 13:21:43 +0200 Subject: [PATCH] Make CI script for ICON parallel integration to Levante more robust. --- .../levante-dkrz/test.icon-pio.intel-classic | 148 +++++++++++++++--- 1 file changed, 130 insertions(+), 18 deletions(-) diff --git a/.ci/bb/levante-dkrz/test.icon-pio.intel-classic b/.ci/bb/levante-dkrz/test.icon-pio.intel-classic index 3bfa59906..b64f626d5 100755 --- a/.ci/bb/levante-dkrz/test.icon-pio.intel-classic +++ b/.ci/bb/levante-dkrz/test.icon-pio.intel-classic @@ -9,27 +9,69 @@ top_srcdir=$(cd "${script_dir}/../../.."; pwd) . "${script_dir}/utils.sh" init_intelclassic202150 -test -f "${top_srcdir}/configure" || "${top_srcdir}/autogen.sh" +# Make sure that the libtool script has a chance to erroneously link to the +# shared versions of YAXT and PPM: +for file in \ + "${PPM_ROOT}/lib/libscalesppmcore.so" \ + "${YAXT_ROOT}/lib/libyaxt.so" \ + "${YAXT_ROOT}/lib/libyaxt_c.so"; do + test -r "${file}" || { + echo "ERROR: file '${file}' not found" >&2 + exit 1 + } +done # When configured as part of ICON, C headers, Fortran modules and library files -# of YAXT and PPM become available only at the build time. The following -# imitates that. - -WRONG_YAXT_ROOT=$(init_gcc1120 >/dev/null && echo "${YAXT_ROOT}") -export PKG_CONFIG_PATH="${WRONG_YAXT_ROOT}/lib/pkgconfig" -export LD_LIBRARY_PATH="${WRONG_YAXT_ROOT}/lib:${LD_LIBRARY_PATH-}" - +# of YAXT and PPM become available only at the build time. We mock that by +# creating two empty directories for YAXT and PPM before running the configure +# script of CDI and copy the required files into them before running make: LOCAL_YAXT_ROOT="$(pwd)/cdi-test-yaxt" LOCAL_PPM_ROOT="$(pwd)/cdi-test-ppm" - rm -rf "${LOCAL_YAXT_ROOT}" "${LOCAL_PPM_ROOT}" +mkdir "${LOCAL_YAXT_ROOT}" "${LOCAL_PPM_ROOT}" + +# Make sure that CDI gets linked to the right instances of YAXT even if certain +# environment variables and linker flags point to the wrong existing instance: +WRONG_YAXT_LIBDIR="$(init_gcc1120 >/dev/null && echo "${YAXT_ROOT}")/lib" -# There is not way for the configure script of ICON to provide the configure +for file in \ + "${WRONG_YAXT_LIBDIR}/libyaxt.la" \ + "${WRONG_YAXT_LIBDIR}/libyaxt_c.la" \ + "${WRONG_YAXT_LIBDIR}/pkgconfig/yaxt.pc" \ + "${WRONG_YAXT_LIBDIR}/pkgconfig/yaxt_c.pc"; do + test -f "${file}" || { + echo "ERROR: file '${file}' not found" >&2 + exit 1 + } +done + +export PKG_CONFIG_PATH="${WRONG_YAXT_LIBDIR}/pkgconfig" +export LD_LIBRARY_PATH="${WRONG_YAXT_LIBDIR}:${LD_LIBRARY_PATH-}" +LDFLAGS="-L${WRONG_YAXT_LIBDIR}" + +# There is no way for the configure script of ICON to provide the configure # script of CDI with the path to the installation of NetCDF in use. Here we # imitate a situation when 'nc-config' from another (wrong) installation of -# NetCDF is in the PATH. +# NetCDF is in the ${PATH}. WRONG_NETCDF_ROOT=$(init_gcc1120 >/dev/null && echo "${NETCDF_ROOT}") -export PATH="${WRONG_NETCDF_ROOT}/bin:${PATH-}" +WRONG_NETCDF_BINDIR="${WRONG_NETCDF_ROOT}/bin" + +# It looks like we cannot properly check whether the wrong 'nc-config' in the +# ${PATH} causes any inconsistency. All we can do is run a not very reliable +# indirect check of whether CDI gets built without the unwanted dependency on +# cURL: +nc_has_dap=`"${WRONG_NETCDF_BINDIR}/nc-config" --has-dap` || { + echo "ERROR: failed to check whether NetCDF in '${WRONG_NETCDF_ROOT}' is built with DAP support" >&2 + exit 1 +} +test "x${nc_has_dap}" = 'xyes' || { + echo "ERROR: NetCDF in '${WRONG_NETCDF_ROOT}' is built without DAP support" >&2 + exit 1 +} + +export PATH="${WRONG_NETCDF_BINDIR}:${PATH-}" + +test -f "${top_srcdir}/configure" || "${top_srcdir}/autogen.sh" "${top_srcdir}/configure" \ --disable-cdi-app \ @@ -67,7 +109,7 @@ CXX=no \ F77=no \ FC="${MPIFC}" \ FCFLAGS="-gdwarf-4 -g -pc64 -fp-model source" \ -LDFLAGS="-L${NETCDF_ROOT}/lib -L${ECCODES_ROOT}/lib64" \ +LDFLAGS="${LDFLAGS} -L${NETCDF_ROOT}/lib -L${ECCODES_ROOT}/lib64" \ LIBS='-Wl,--as-needed -lnetcdf -leccodes' \ MPIROOT= \ MPI_C_INCLUDE= \ @@ -93,15 +135,85 @@ acx_cv_have_nc4hdf5=no \ acx_cv_have_netcdf2=yes \ acx_cv_have_netcdf4=yes \ acx_cv_have_pnetcdf=no \ -acx_cv_option_search_PPM_initialize_c="${LOCAL_PPM_ROOT}/lib/libscalesppmcore.a" \ -acx_cv_option_search_xt_initialized_c="${LOCAL_YAXT_ROOT}/lib/libyaxt_c.a" \ -acx_cv_option_search_xt_initialized_fc="${LOCAL_YAXT_ROOT}/lib/libyaxt.a ${LOCAL_YAXT_ROOT}/lib/libyaxt_c.a" +acx_cv_option_search_PPM_initialize_c="${LOCAL_PPM_ROOT}/lib/libscalesppmcore.la" \ +acx_cv_option_search_xt_initialized_c="${LOCAL_YAXT_ROOT}/lib/libyaxt_c.la" \ +acx_cv_option_search_xt_initialized_fc="${LOCAL_YAXT_ROOT}/lib/libyaxt.la ${LOCAL_YAXT_ROOT}/lib/libyaxt_c.la" -rsync -uavz "${YAXT_ROOT}/" "${LOCAL_YAXT_ROOT}" --exclude='*.la' --exclude='*.pc' --exclude='*.so' --exclude='*.so.*' -rsync -uavz "${PPM_ROOT}/" "${LOCAL_PPM_ROOT}" --exclude='*.la' --exclude='*.pc' --exclude='*.so' --exclude='*.so.*' + +# Create local copies of YAXT and PPM and make them similar to what they look like +# when the libraries are built inside the build system of ICON: +rsync -uavz "${YAXT_ROOT}/" "${LOCAL_YAXT_ROOT}/" --exclude='*.pc' --exclude='*.so' --exclude='*.so.*' +rsync -uavz "${PPM_ROOT}/" "${LOCAL_PPM_ROOT}/" --exclude='*.pc' --exclude='*.so' --exclude='*.so.*' +sed -i -E -e "{ +# The build system of ICON disables the shared versions of the libraries +# (i.e. configures them with '--disable-shared'): +s/^dlname=.*/dlname=''/ +s/^library_names=.*/library_names=''/ +# The linking to the libraries is done without installing them: +s/^installed=.*/installed=no/ +}" `find "${LOCAL_YAXT_ROOT}" "${LOCAL_PPM_ROOT}" -name '*.la'` make -j8 +# The current general approach in the build system of ICON is to avoid building +# the shared versions of the bundled libraries and link to the static ones +# without -L and -l flags. Instead, to avoid possible ambiguity, the linking is +# done by passing paths to static library as positional arguments for the +# linker. That, however, does not work well with libtool scripts as they inject +# all files referred by the positional arguments into the generated static +# libraries (archives). That is usually fine with the GNU linker but is a +# problem for the MacOS one, which might ignore the whole library file: +# ld: warning: ignoring file libcdipio.a, building for macOS-x86_64 but attempting to link with file built for macOS-x86_64 +# To circumvent the problem, we tell the configure of CDI to link to YAXT and +# PPM using libtool .la files and check that libcdipio.a does not contain any +# other archive files, which the linker might potentially not be able to handle: +tested_file='src/.libs/libcdipio.a' +invalid_entries=`ar t "${tested_file}" | sed -n '/\.a$/p'` || { + echo "ERROR: failed to check $1 for invalid entries" >&2 + exit 1 +} +if test -n "${invalid_entries}"; then + { + echo "ERROR: '${tested_file}' has invalid entries:" >&2 + echo "${invalid_entries}" >&2 + } >&2 + exit 1 +fi + +make -j8 check TESTS= XFAIL_TESTS= + +# Check that a test program is linked to YAXT and PPM statically as it should +# when built inside the build system of ICON: +tested_file='tests/pio_write.parallel' +invalid_deps=`ldd "${tested_file}" | sed -E -n '/libscalesppmcore|libyaxt/p'` || { + echo "ERROR: failed to check '${tested_file}' for invalid dependencies" >&2 + exit 1 +} +if test -n "${invalid_deps}"; then + { + echo "ERROR: '${tested_file}' has invalid dependencies:" >&2 + echo "${invalid_deps}" >&2 + } >&2 + exit 1 +fi + +# Check that we do not link to the instance of YAXT from ${WRONG_YAXT_LIBDIR} +# (we might fail earlier if ${WRONG_YAXT_LIBDIR} contains the shared version of +# the library): +make -C examples/pio collectData2003.parallel + +# Check whether CDI is built without the unwanted dependency on cURL: +tested_file='./app/cdi' +cdi_built_with=`"${tested_file}" -d 2>&1 | sed -E -n '/^[ ]*with:/p'` && test -n "${cdi_built_with}" || { + echo "ERROR: failed to get the expected debug output from '${tested_file}'" >&2 + exit 1 +} +case " ${cdi_built_with} " in + *' OPeNDAP '*) + echo "ERROR: CDI is built with the unwanted dependency on cURL (i.e. OPeNDAP support is enabled)" 2>&1 + exit 1 ;; +esac + make -j8 check || { cat tests/test-suite.log; exit 1; } check_all_tests_passed tests/test-suite.log -- GitLab