diff --git a/recipes/icon/25.11/gh200/compilers.yaml b/recipes/icon/25.11/gh200/compilers.yaml new file mode 100644 index 0000000..91bad58 --- /dev/null +++ b/recipes/icon/25.11/gh200/compilers.yaml @@ -0,0 +1,4 @@ +gcc: + version: "13" +nvhpc: + version: "25.7" diff --git a/recipes/icon/25.11/gh200/config.yaml b/recipes/icon/25.11/gh200/config.yaml new file mode 100644 index 0000000..018b8dc --- /dev/null +++ b/recipes/icon/25.11/gh200/config.yaml @@ -0,0 +1,11 @@ +name: icon +store: /user-environment +spack: + commit: releases/v1.0 + repo: https://github.com/spack/spack.git + packages: + repo: https://github.com/spack/spack-packages.git + commit: develop +description: Compilers and libraries required to build ICON +modules: False +version: 2 diff --git a/recipes/icon/25.11/gh200/environments.yaml b/recipes/icon/25.11/gh200/environments.yaml new file mode 100644 index 0000000..3ce3e87 --- /dev/null +++ b/recipes/icon/25.11/gh200/environments.yaml @@ -0,0 +1,54 @@ +icon: + compiler: [gcc, nvhpc] + network: + mpi: cray-mpich@8.1.32 +cuda %c,cxx,fortran=nvhpc + specs: + - libfabric@2.3 +gdrcopy %c=gcc + - gdrcopy %c,cxx=gcc + - libcxi %c=gcc + unify: true + duplicates: + strategy: full + specs: + - boost ~mpi +thread %c,cxx=gcc + - serialbox@2.6.2 +fortran %c,cxx,fortran=nvhpc + - python@3.11 +optimizations %c,cxx=gcc ^libffi %c,cxx=gcc ^expat %c=gcc ^libmd %c=gcc ^libxcrypt %c=gcc ^gettext %c,cxx=gcc + - cuda@12 + - eccodes@2.36.4 +tools +fortran +aec +openmp jp2k=jasper %c,cxx,fortran=nvhpc ^libjpeg-turbo %c,cxx=gcc + - cosmo-eccodes-definitions@2.36.0.3 + - hdf5 +szip +hl +fortran +mpi %c,cxx,fortran=nvhpc + - netcdf-c@4.9.2 %c,cxx=nvhpc + - netcdf-cxx4@4.3.1 %c,cxx=nvhpc + - netcdf-fortran@4.6.1 %c,cxx,fortran=nvhpc + - nvhpc + - osu-micro-benchmarks %c,cxx=gcc + - openblas %c,cxx,fortran=nvhpc + # for validation + # - cdo # dependencies don't build (check cache?) + # everything needed for nccl on SS11 + - aws-ofi-nccl %c,cxx=gcc ^findutils %c=gcc + - nccl %c,cxx=gcc + - nccl-tests %cxx=gcc + # extras + - libfyaml %c=gcc ^m4 %c,cxx=gcc + - zlib-ng %c,cxx=gcc + - cmake %c,cxx=gcc + # for icon-exclaim + - libxml2 %c=gcc ^libiconv %c=gcc + # force compiler on transitive dependencies + - texinfo %c,cxx=gcc + - numactl %c=gcc + - libnl %c=gcc + - libuv %c=gcc + - ninja %c,cxx=gcc + - libfuse %c,cxx=gcc + variants: + - +mpi + - +cuda + - cuda_arch=90a + views: + default: + link: roots + uenv: + prefix_paths: + LD_LIBRARY_PATH: [lib, lib64] diff --git a/recipes/icon/25.11/gh200/extra/reframe.yaml b/recipes/icon/25.11/gh200/extra/reframe.yaml new file mode 100644 index 0000000..0592e13 --- /dev/null +++ b/recipes/icon/25.11/gh200/extra/reframe.yaml @@ -0,0 +1,13 @@ +default: + features: + - cuda + - mpi + - osu-micro-benchmarks + - nccl-tests + - serial + - openmp + cc: mpicc + cxx: mpic++ + ftn: mpifort + activation: /user-environment/env/default/activate.sh + diff --git a/recipes/icon/25.11/gh200/modules.yaml b/recipes/icon/25.11/gh200/modules.yaml new file mode 100644 index 0000000..a4010ae --- /dev/null +++ b/recipes/icon/25.11/gh200/modules.yaml @@ -0,0 +1,26 @@ +modules: + # Paths to check when creating modules for all module sets + prefix_inspections: + bin: + - PATH + lib: + - LD_LIBRARY_PATH + lib64: + - LD_LIBRARY_PATH + + default: + arch_folder: false + # Where to install modules + roots: + tcl: /snap/modules + tcl: + all: + autoload: run + hash_length: 0 + hide_implicits: true + exclude: + - '%gcc@7.5.0' + - '%gcc@12' + - 'gcc %gcc@7.5.0' + projections: + all: '{name}/{version}' diff --git a/recipes/icon/25.11/gh200/post-install b/recipes/icon/25.11/gh200/post-install new file mode 100644 index 0000000..98ed497 --- /dev/null +++ b/recipes/icon/25.11/gh200/post-install @@ -0,0 +1,5 @@ +#!/bin/bash + +curl -LsSf https://astral.sh/uv/install.sh > uv-installer.sh +UV_INSTALL_DIR="store/env/default/bin" sh uv-installer.sh +rm uv-installer.sh diff --git a/recipes/icon/25.11/gh200/pre-install b/recipes/icon/25.11/gh200/pre-install new file mode 100644 index 0000000..b9fae29 --- /dev/null +++ b/recipes/icon/25.11/gh200/pre-install @@ -0,0 +1,12 @@ +#!/bin/bash + +# packages=("cosmo-eccodes-definitions") +# SPACK_C2SM_TAG="v0.22.2.1" +# +# git clone -b ${SPACK_C2SM_TAG} https://github.com/C2SM/spack-c2sm.git +# +# for package in "${packages[@]}"; do +# cp -r spack-c2sm/repos/c2sm/packages/"${package}" store/repo/packages +# done +# +# rm -rf spack-c2sm diff --git a/recipes/icon/25.11/gh200/repo b/recipes/icon/25.11/gh200/repo new file mode 120000 index 0000000..3f5a289 --- /dev/null +++ b/recipes/icon/25.11/gh200/repo @@ -0,0 +1 @@ +../repo \ No newline at end of file diff --git a/recipes/icon/25.11/repo/packages/cosmo_eccodes_definitions/package.py b/recipes/icon/25.11/repo/packages/cosmo_eccodes_definitions/package.py new file mode 100644 index 0000000..4156b82 --- /dev/null +++ b/recipes/icon/25.11/repo/packages/cosmo_eccodes_definitions/package.py @@ -0,0 +1,53 @@ +from spack_repo.builtin.build_systems.generic import Package + +from spack.package import * + + +class CosmoEccodesDefinitions(Package): + """To simplify the usage of the GRIB 2 format within the COSMO Consortium, a COSMO GRIB 2 Policy has been defined. One element of this policy is to define a unified ecCodes system for the COSMO community, which is compatible with all COSMO software. This unified system is split into two parts, the vendor distribution of the ecCodes, available from ECMWF and the modified samples and definitions used by the COSMO consortium, available in the current repository.""" + + homepage = "https://github.com/COSMO-ORG/eccodes-cosmo-resources.git" + url = "https://github.com/COSMO-ORG/eccodes-cosmo-resources.git" + git = 'https://github.com/COSMO-ORG/eccodes-cosmo-resources.git' + + maintainers('huppd', 'lxavier') + + version('2.36.0.3', tag='v2.36.0.3') + version('2.25.0.3', tag='v2.25.0.3') + version('2.25.0.2', tag='v2.25.0.2') + version('2.25.0.1', tag='v2.25.0.1') + version('2.18.0.1', tag='v2.18.0.1') + + depends_on('eccodes') + depends_on('eccodes@2.36.4', + type=('build', 'link', 'run'), + when='@2.36.0.3') + depends_on('eccodes@2.25.0', + type=('build', 'link', 'run'), + when='@2.25.0.1:2.25.0.3') + depends_on('eccodes@2.18.0', + type=('build', 'link', 'run'), + when='@2.18.0.1') + + def setup_run_environment(self, env): + eccodes_definition_path = ':'.join([ + self.prefix + '/cosmoDefinitions/definitions/', + self.spec['eccodes'].prefix + '/share/eccodes/definitions/' + ]) + env.prepend_path('GRIB_DEFINITION_PATH', eccodes_definition_path) + env.prepend_path('ECCODES_DEFINITION_PATH', eccodes_definition_path) + + eccodes_samples_path = self.prefix + '/cosmoDefinitions/samples/' + env.prepend_path('GRIB_SAMPLES_PATH', eccodes_samples_path) + env.prepend_path('ECCODES_SAMPLES_PATH', eccodes_samples_path) + + def setup_dependent_build_environment(self, env, dependent_spec): + self.setup_run_environment(env) + + def install(self, spec, prefix): + mkdir(prefix.cosmoDefinitions) + mkdir(prefix.cosmoDefinitions + '/definitions') + mkdir(prefix.cosmoDefinitions + '/samples') + install_tree('definitions', prefix.cosmoDefinitions + '/definitions') + install_tree('samples', prefix.cosmoDefinitions + '/samples') + install('RELEASE', prefix.cosmoDefinitions) diff --git a/recipes/icon/25.11/repo/packages/eccodes/cmake_install_rpath.patch b/recipes/icon/25.11/repo/packages/eccodes/cmake_install_rpath.patch new file mode 100644 index 0000000..7e2b250 --- /dev/null +++ b/recipes/icon/25.11/repo/packages/eccodes/cmake_install_rpath.patch @@ -0,0 +1,11 @@ +--- a/cmake/ecbuild_append_to_rpath.cmake ++++ b/cmake/ecbuild_append_to_rpath.cmake +@@ -31,7 +31,7 @@ function( _path_append var path ) + else() + list( FIND ${var} ${path} _found ) + if( _found EQUAL "-1" ) +- set( ${var} "${${var}}:${path}" PARENT_SCOPE ) ++ set( ${var} "${${var}};${path}" PARENT_SCOPE ) + endif() + endif() + endfunction() diff --git a/recipes/icon/25.11/repo/packages/eccodes/openjpeg_jasper.patch b/recipes/icon/25.11/repo/packages/eccodes/openjpeg_jasper.patch new file mode 100644 index 0000000..5793f56 --- /dev/null +++ b/recipes/icon/25.11/repo/packages/eccodes/openjpeg_jasper.patch @@ -0,0 +1,39 @@ +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -43,6 +43,18 @@ ecbuild_add_option( FEATURE JPG + DESCRIPTION "support for JPG decoding/encoding" + DEFAULT ON + ) ++# Options related to JPG. The Jasper and OpenJPEG libraries ++ecbuild_add_option( FEATURE JPG_LIBJASPER ++ DESCRIPTION "Support for JPG decoding/encoding with the Jasper library" ++ CONDITION ENABLE_JPG ++ DEFAULT ON ++) ++ecbuild_add_option( FEATURE JPG_LIBOPENJPEG ++ DESCRIPTION "Support for JPG decoding/encoding with the OpenJPEG library" ++ CONDITION ENABLE_JPG ++ DEFAULT ON ++) ++ + + ecbuild_add_option( FEATURE PNG + DESCRIPTION "support for PNG decoding/encoding" +@@ -144,7 +156,7 @@ if( ENABLE_JPG ) + + find_package( OpenJPEG ) + +- if( JASPER_FOUND ) ++ if( JASPER_FOUND AND ENABLE_JPG_LIBJASPER ) + list( APPEND ECCODES_TPLS Jasper ) + set( HAVE_JPEG 1 ) + set( HAVE_LIBJASPER 1 ) +@@ -152,7 +164,7 @@ if( ENABLE_JPG ) + string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" JASPER_VERSION_MAJOR "${JASPER_VERSION_STRING}") + endif() + +- if( OPENJPEG_FOUND ) ++ if( OPENJPEG_FOUND AND ENABLE_JPG_LIBOPENJPEG ) + list( APPEND ECCODES_TPLS OpenJPEG ) + set( HAVE_JPEG 1 ) + set( HAVE_LIBOPENJPEG 1 ) diff --git a/recipes/icon/25.11/repo/packages/eccodes/package.py b/recipes/icon/25.11/repo/packages/eccodes/package.py new file mode 100644 index 0000000..71c3321 --- /dev/null +++ b/recipes/icon/25.11/repo/packages/eccodes/package.py @@ -0,0 +1,386 @@ +# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +from spack_repo.builtin.build_systems.cmake import CMakePackage + +from spack.package import * + +_definitions = { + # German Meteorological Service (Deutscher Wetterdienst, DWD): + "edzw": { + "conflicts": {"when": "@:2.19.1,2.22.0,2.24.0:"}, + "resources": [ + { + "when": "@2.20.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.20.0-1.tar.gz", + "sha256": "a92932f8a13c33cba65d3a33aa06c7fb4a37ed12a78e9abe2c5e966402b99af4", + }, + { + "when": "@2.21.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.21.0-3.tar.bz2", + "sha256": "046f1f6450abb3b44c31dee6229f4aab06ca0d3576e27e93e05ccb7cd6e2d9d9", + }, + { + "when": "@2.22.1", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.22.1-1.tar.bz2", + "sha256": "be73102a0dcabb236bacd2a70c7b5475f673fda91b49e34df61bef0fa5ad3389", + }, + { + "when": "@2.23.0", + "url": "http://opendata.dwd.de/weather/lib/grib/eccodes_definitions.edzw-2.23.0-4.tar.bz2", + "sha256": "c5db32861c7d23410aed466ffef3ca661410d252870a3949442d3ecb176aa338", + }, + ], + } +} + + +class Eccodes(CMakePackage): + """ecCodes is a package developed by ECMWF for processing meteorological + data in GRIB (1/2), BUFR (3/4) and GTS header formats.""" + + homepage = "https://software.ecmwf.int/wiki/display/ECC/ecCodes+Home" + url = "https://confluence.ecmwf.int/download/attachments/45757960/eccodes-2.2.0-Source.tar.gz?api=v2" + git = "https://github.com/ecmwf/eccodes.git" + list_url = "https://confluence.ecmwf.int/display/ECC/Releases" + + maintainers("skosukhin", "victoria-cherkas", "dominichofer", "climbfuji") + + license("Apache-2.0") + + version("develop", branch="develop") + version("2.36.4", + sha256="198ccb26e8df96544c668ea6853ea153535ab78b10c43339a678f271337aa0da", + url="https://github.com/ecmwf/eccodes/archive/refs/tags/2.36.4.tar.gz" + ) + version("2.34.0", sha256="3cd208c8ddad132789662cf8f67a9405514bfefcacac403c0d8c84507f303aba") + version("2.33.0", sha256="bdcec8ce63654ec6803400c507f01220a9aa403a45fa6b5bdff7fdcc44fd7daf") + version("2.32.1", sha256="ad2ac1bf36577b1d35c4a771b4d174a06f522a1e5ef6c1f5e53a795fb624863e") + version("2.32.0", sha256="b57e8eeb0eba0c05d66fda5527c4ffa84b5ab35c46bcbc9a2227142973ccb8e6") + version("2.31.0", sha256="808ecd2c11fbf2c3f9fc7a36f8c2965b343f3151011b58a1d6e7cc2e6b3cac5d") + version("2.25.0", sha256="8975131aac54d406e5457706fd4e6ba46a8cc9c7dd817a41f2aa64ce1193c04e") + version("2.24.2", sha256="c60ad0fd89e11918ace0d84c01489f21222b11d6cad3ff7495856a0add610403") + version("2.23.0", sha256="cbdc8532537e9682f1a93ddb03440416b66906a4cc25dec3cbd73940d194bf0c") + version("2.22.1", sha256="75c7ee96469bb30b0c8f7edbdc4429ece4415897969f75c36173545242bc9e85") + version("2.21.0", sha256="da0a0bf184bb436052e3eae582defafecdb7c08cdaab7216780476e49b509755") + version("2.20.0", sha256="207a3d7966e75d85920569b55a19824673e8cd0b50db4c4dac2d3d52eacd7985") + version("2.19.1", sha256="9964bed5058e873d514bd4920951122a95963128b12f55aa199d9afbafdd5d4b") + version("2.18.0", sha256="d88943df0f246843a1a062796edbf709ef911de7269648eef864be259e9704e3") + version("2.13.0", sha256="c5ce1183b5257929fc1f1c8496239e52650707cfab24f4e0e1f1a471135b8272") + version("2.5.0", sha256="18ab44bc444168fd324d07f7dea94f89e056f5c5cd973e818c8783f952702e4e") + version("2.2.0", sha256="1a4112196497b8421480e2a0a1164071221e467853486577c4f07627a702f4c3") + + # we are still using spack v0.21 v0.22, so comment these out for now + depends_on("c", type="build") # generated + depends_on("cxx", type="build") # generated + depends_on("fortran", type="build") # generated + + variant("tools", default=False, description="Build the command line tools") + variant("netcdf", default=False, description="Enable GRIB to NetCDF conversion tool") + variant( + "jp2k", + default="openjpeg", + values=("openjpeg", "jasper", "none"), + description="Specify JPEG2000 decoding/encoding backend", + ) + variant("png", default=False, description="Enable PNG support for decoding/encoding") + variant( + "aec", default=True, description="Enable Adaptive Entropy Coding for decoding/encoding" + ) + variant("pthreads", default=False, description="Enable POSIX threads") + variant("openmp", default=False, description="Enable OpenMP threads") + variant( + "memfs", default=False, description="Enable memory based access to definitions/samples" + ) + variant("fortran", default=False, description="Enable the Fortran support") + variant("shared", default=True, description="Build shared versions of the libraries") + + variant( + "extra_definitions", + values=any_combination_of(*_definitions.keys()), + description="List of extra definitions to install", + ) + + depends_on("netcdf-c", when="+netcdf") + # Cannot be built with openjpeg@2.0.x. + depends_on("openjpeg@1.5.0:1.5,2.1.0:2.3", when="jp2k=openjpeg") + # Additional constraint for older versions. + depends_on("openjpeg@:2.1", when="@:2.16 jp2k=openjpeg") + + with when("jp2k=jasper"): + depends_on("jasper") + # jasper 3.x compat from commit 86f0b35f1a8492cb16f82fb976a0a5acd2986ac2 + depends_on("jasper@:2", when="@:2.25.0") + + depends_on("libpng", when="+png") + depends_on("libaec", when="+aec") + # Can be built with Python 2 or Python 3. + depends_on("python", when="+memfs", type="build") + + depends_on("cmake@3.6:", type="build") + depends_on("cmake@3.12:", when="@2.19:", type="build") + + # TODO: ecbuild was only used for the @develop branch + # however, testing 2.36.4, it appears to be a requirement. + # this might be because they package the software differently in GitHub + # (they normally provide releases as tar balls on Confluence) + depends_on("ecbuild", type="build") + #depends_on("ecbuild", type="build", when="@develop") + + conflicts("+openmp", when="+pthreads", msg="Cannot enable both POSIX threads and OMP") + + conflicts( + "+netcdf", + when="~tools", + msg="Cannot enable the NetCDF conversion tool " "when the command line tools are disabled", + ) + + conflicts( + "~tools", + when="@:2.18.0", + msg="The command line tools can be disabled " "only starting version 2.19.0", + ) + + for center, definitions in _definitions.items(): + kwargs = definitions.get("conflicts", None) + if kwargs: + conflicts("extra_definitions={0}".format(center), **kwargs) + for kwargs in definitions.get("resources", []): + resource( + name=center, + destination="spack-definitions", + placement="definitions.{0}".format(center), + **kwargs, + ) + + # Enforce linking against the specified JPEG2000 backend, see also + # https://github.com/ecmwf/eccodes/commit/2c10828495900ff3d80d1e570fe96c1df16d97fb + patch("openjpeg_jasper.patch", when="@:2.16") + + # CMAKE_INSTALL_RPATH must be a semicolon-separated list. + patch("cmake_install_rpath.patch", when="@:2.10") + + # Fix a bug preventing cmake from finding NetCDF: + patch( + "https://github.com/ecmwf/ecbuild/commit/3916c7d22575c45166fcc89edcbe02a6e9b81aa2.patch?full_index=1", + sha256="9dcc4affaaa850d4b7247baa939d0f9ffedea132369f1afc3f248dbf720386c9", + when="@:2.4.0+netcdf", + ) + + @when("%nag+fortran") + def patch(self): + # A number of Fortran source files assume that the kinds of integer and + # real variables are specified in bytes. However, the NAG compiler + # accepts such code only with an additional compiler flag -kind=byte. + # We do not simply add the flag because all user applications would + # have to be compiled with this flag too, which goes against one of the + # purposes of using the NAG compiler: make sure the code does not + # contradict the Fortran standards. The following logic could have been + # implemented as regular patch files, which would, however, be quite + # large. We would also have to introduce several versions of each patch + # file to support different versions of the package. + + patch_kind_files = [ + "fortran/eccodes_f90_head.f90", + "fortran/eccodes_f90_tail.f90", + "fortran/grib_f90_head.f90", + "fortran/grib_f90_tail.f90", + "fortran/grib_types.f90", + ] + + patch_unix_ext_files = [] + + if self.run_tests: + patch_kind_files.extend( + [ + "examples/F90/grib_print_data.f90", + "examples/F90/grib_print_data_static.f90", + # Files that need patching only when the extended regression + # tests are enabled, which we disable unconditionally: + # 'examples/F90/bufr_attributes.f90', + # 'examples/F90/bufr_expanded.f90', + # 'examples/F90/bufr_get_keys.f90', + # 'examples/F90/bufr_read_scatterometer.f90', + # 'examples/F90/bufr_read_synop.f90', + # 'examples/F90/bufr_read_temp.f90', + # 'examples/F90/bufr_read_tempf.f90', + # 'examples/F90/bufr_read_tropical_cyclone.f90', + # 'examples/F90/grib_clone.f90', + # 'examples/F90/grib_get_data.f90', + # 'examples/F90/grib_nearest.f90', + # 'examples/F90/grib_precision.f90', + # 'examples/F90/grib_read_from_file.f90', + # 'examples/F90/grib_samples.f90', + # 'examples/F90/grib_set_keys.f90' + ] + ) + + patch_unix_ext_files.extend( + [ + "examples/F90/bufr_ecc-1284.f90", + "examples/F90/grib_set_data.f90", + "examples/F90/grib_set_packing.f90", + # Files that need patching only when the extended regression + # tests are enabled, which we disable unconditionally: + # 'examples/F90/bufr_copy_data.f90', + # 'examples/F90/bufr_get_string_array.f90', + # 'examples/F90/bufr_keys_iterator.f90', + # 'examples/F90/get_product_kind.f90', + # 'examples/F90/grib_count_messages_multi.f90' + ] + ) + + kwargs = {"string": False, "backup": False, "ignore_absent": True} + + # Return the kind and not the size: + filter_file( + r"(^\s*kind_of_double\s*=\s*)(\d{1,2})(\s*$)", + "\\1kind(real\\2)\\3", + "fortran/grib_types.f90", + **kwargs, + ) + filter_file( + r"(^\s*kind_of_\w+\s*=\s*)(\d{1,2})(\s*$)", + "\\1kind(x\\2)\\3", + "fortran/grib_types.f90", + **kwargs, + ) + + # Replace integer kinds: + for size, r in [(2, 4), (4, 9), (8, 18)]: + filter_file( + r"(^\s*integer\((?:kind=)?){0}(\).*)".format(size), + "\\1selected_int_kind({0})\\2".format(r), + *patch_kind_files, + **kwargs, + ) + + # Replace real kinds: + for size, p, r in [(4, 6, 37), (8, 15, 307)]: + filter_file( + r"(^\s*real\((?:kind=)?){0}(\).*)".format(size), + "\\1selected_real_kind({0}, {1})\\2".format(p, r), + *patch_kind_files, + **kwargs, + ) + + # Enable getarg and exit subroutines: + filter_file( + r"(^\s*program\s+\w+)(\s*$)", + "\\1; use f90_unix_env; use f90_unix_proc\\2", + *patch_unix_ext_files, + **kwargs, + ) + + @property + def libs(self): + libraries = [] + + query_parameters = self.spec.last_query.extra_parameters + + if "shared" in query_parameters: + shared = True + elif "static" in query_parameters: + shared = False + else: + shared = "+shared" in self.spec + + # Return Fortran library if requested: + return_fortran = "fortran" in query_parameters + # Return C library if either requested or the Fortran library is not + # requested (to avoid overlinking) or the static libraries are + # requested: + return_c = "c" in query_parameters or not (return_fortran and shared) + # Return MEMFS library only if enabled and the static libraries are + # requested: + return_memfs = "+memfs" in self.spec and not shared + + if return_fortran: + libraries.append("libeccodes_f90") + + if return_c: + libraries.append("libeccodes") + + if return_memfs: + libraries.append("libeccodes_memfs") + + libs = find_libraries(libraries, root=self.prefix, shared=shared, recursive=True) + + if libs and len(libs) == len(libraries): + return libs + + msg = "Unable to recursively locate {0} {1} libraries in {2}" + raise spack.error.NoLibrariesError( + msg.format("shared" if shared else "static", self.spec.name, self.spec.prefix) + ) + + @run_before("cmake") + def check_fortran(self): + if "+fortran" in self.spec and self.compiler.fc is None: + raise InstallError("Fortran interface requires a Fortran compiler!") + + def cmake_args(self): + jp2k = self.spec.variants["jp2k"].value + + args = [ + self.define_from_variant("ENABLE_BUILD_TOOLS", "tools"), + self.define_from_variant("ENABLE_NETCDF", "netcdf"), + self.define("ENABLE_JPG", jp2k != "none"), + self.define("ENABLE_JPG_LIBJASPER", jp2k == "jasper"), + self.define("ENABLE_JPG_LIBOPENJPEG", jp2k == "openjpeg"), + self.define_from_variant("ENABLE_PNG", "png"), + self.define_from_variant("ENABLE_AEC", "aec"), + self.define_from_variant("ENABLE_ECCODES_THREADS", "pthreads"), + self.define_from_variant("ENABLE_ECCODES_OMP_THREADS", "openmp"), + self.define_from_variant("ENABLE_MEMFS", "memfs"), + self.define( + "ENABLE_PYTHON{0}".format("2" if self.spec.satisfies("@2.20.0:") else ""), False + ), + self.define_from_variant("ENABLE_FORTRAN", "fortran"), + self.define("BUILD_SHARED_LIBS", "BOTH" if "+shared" in self.spec else "OFF"), + self.define("ENABLE_TESTS", self.run_tests), + # Examples are not installed and are just part of the test suite: + self.define("ENABLE_EXAMPLES", self.run_tests), + # Unconditionally disable the extended regression tests, since they + # download additional data (~134MB): + self.define("ENABLE_EXTRA_TESTS", False), + ] + + if self.spec.satisfies("+netcdf"): + # Prevent possible overriding by environment variables NETCDF_ROOT, NETCDF_DIR, and + # NETCDF_PATH: + args.append(self.define("NETCDF_PATH", self.spec["netcdf-c"].prefix)) + # Prevent overriding by environment variable HDF5_ROOT (starting version 2.14.0, + # ecCodes is shipped with ecBuild 3.1.0+, which does not seem to rely on the HDF5_ROOT + # variable): + if self.spec.satisfies("@:2.13"): + args.append(self.define("HDF5_ROOT", self.spec["hdf5"].prefix)) + + if jp2k == "openjpeg": + args.append(self.define("OPENJPEG_PATH", self.spec["openjpeg"].prefix)) + + if self.spec.satisfies("+png"): + args.append(self.define("ZLIB_ROOT", self.spec["zlib-api"].prefix)) + + if self.spec.satisfies("+aec"): + # Prevent overriding by environment variables AEC_DIR and AEC_PATH: + args.append(self.define("AEC_DIR", self.spec["libaec"].prefix)) + + return args + + @run_after("install") + def install_extra_definitions(self): + for center in self.spec.variants["extra_definitions"].value: + if center != "none": + center_dir = "definitions.{0}".format(center) + install_tree( + join_path(self.stage.source_path, "spack-definitions", center_dir), + join_path(self.prefix.share.eccodes, center_dir), + ) + + def check(self): + # https://confluence.ecmwf.int/display/ECC/ecCodes+installation + with working_dir(self.build_directory): + ctest() diff --git a/recipes/icon/25.11/repo/packages/eccodes/readme.md b/recipes/icon/25.11/repo/packages/eccodes/readme.md new file mode 100644 index 0000000..9678342 --- /dev/null +++ b/recipes/icon/25.11/repo/packages/eccodes/readme.md @@ -0,0 +1 @@ +copied from mainline spack November 5 2024 so that we can add eccodes 2.36.0 for mch production diff --git a/recipes/icon/25.11/repo/packages/serialbox/missing_includes.patch b/recipes/icon/25.11/repo/packages/serialbox/missing_includes.patch new file mode 100644 index 0000000..2e21c98 --- /dev/null +++ b/recipes/icon/25.11/repo/packages/serialbox/missing_includes.patch @@ -0,0 +1,11 @@ +--- a/src/serialbox-c/FortranWrapper.cpp ++++ b/src/serialbox-c/FortranWrapper.cpp +@@ -12,6 +12,8 @@ + * + \*===------------------------------------------------------------------------------------------===*/ + ++#include ++ + #include "serialbox-c/FortranWrapper.h" + #include "serialbox-c/FieldMetainfo.h" + #include "serialbox-c/Metainfo.h" diff --git a/recipes/icon/25.11/repo/packages/serialbox/nag/bool_getters.patch b/recipes/icon/25.11/repo/packages/serialbox/nag/bool_getters.patch new file mode 100644 index 0000000..4d23421 --- /dev/null +++ b/recipes/icon/25.11/repo/packages/serialbox/nag/bool_getters.patch @@ -0,0 +1,54 @@ +# This patch is applicable starting version 2.3.1 +--- a/src/serialbox-fortran/m_serialize.f90 ++++ b/src/serialbox-fortran/m_serialize.f90 +@@ -634,11 +634,14 @@ SUBROUTINE fs_get_serializer_metainfo_b(serializer, key, val) + USE, INTRINSIC :: iso_c_binding + TYPE(C_PTR), INTENT(IN), VALUE :: serializer + CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(IN) :: key +- LOGICAL, INTENT(OUT) :: val ++ INTEGER(KIND=C_INT), INTENT(OUT) :: val + END SUBROUTINE fs_get_serializer_metainfo_b_ + END INTERFACE + +- CALL fs_get_serializer_metainfo_b_(serializer%serializer_ptr, TRIM(key)//C_NULL_CHAR, val) ++ INTEGER(KIND=C_INT) :: c_val ++ CALL fs_get_serializer_metainfo_b_(serializer%serializer_ptr, TRIM(key)//C_NULL_CHAR, c_val) ++ ++ val = c_val /= 0 + END SUBROUTINE fs_get_serializer_metainfo_b + + SUBROUTINE fs_get_serializer_metainfo_i(serializer, key, val) +@@ -950,11 +953,14 @@ SUBROUTINE fs_get_field_metainfo_b(serializer, fieldname, key, val) + USE, INTRINSIC :: iso_c_binding + TYPE(C_PTR), INTENT(IN), VALUE :: serializer + CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(IN) :: fieldname, key +- LOGICAL, INTENT(OUT) :: val ++ INTEGER(KIND=C_INT), INTENT(OUT) :: val + END SUBROUTINE fs_get_field_metainfo_b_ + END INTERFACE + +- CALL fs_get_field_metainfo_b_(serializer%serializer_ptr, TRIM(fieldname)//C_NULL_CHAR, TRIM(key)//C_NULL_CHAR, val) ++ INTEGER(KIND=C_INT) :: c_val ++ CALL fs_get_field_metainfo_b_(serializer%serializer_ptr, TRIM(fieldname)//C_NULL_CHAR, TRIM(key)//C_NULL_CHAR, c_val) ++ ++ val = c_val /= 0 + END SUBROUTINE fs_get_field_metainfo_b + + SUBROUTINE fs_get_field_metainfo_i(serializer, fieldname, key, val) +@@ -1466,11 +1472,14 @@ SUBROUTINE fs_get_savepoint_metainfo_b(savepoint, key, val) + USE, INTRINSIC :: iso_c_binding + TYPE(C_PTR), INTENT(IN), VALUE :: savepoint + CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(IN) :: key +- LOGICAL, INTENT(OUT) :: val ++ INTEGER(KIND=C_INT), INTENT(OUT) :: val + END SUBROUTINE fs_get_savepoint_metainfo_b_ + END INTERFACE + +- CALL fs_get_savepoint_metainfo_b_(savepoint%savepoint_ptr, TRIM(key)//C_NULL_CHAR, val) ++ INTEGER(KIND=C_INT) :: c_val ++ CALL fs_get_savepoint_metainfo_b_(savepoint%savepoint_ptr, TRIM(key)//C_NULL_CHAR, c_val) ++ ++ val = c_val /= 0 + END SUBROUTINE fs_get_savepoint_metainfo_b + + SUBROUTINE fs_get_savepoint_metainfo_i(savepoint, key, val) diff --git a/recipes/icon/25.11/repo/packages/serialbox/nag/examples.patch b/recipes/icon/25.11/repo/packages/serialbox/nag/examples.patch new file mode 100644 index 0000000..91857d0 --- /dev/null +++ b/recipes/icon/25.11/repo/packages/serialbox/nag/examples.patch @@ -0,0 +1,27 @@ +# This patch is applicable starting version 2.3.1 +--- a/examples/fortran/simple/m_ser.F90 ++++ b/examples/fortran/simple/m_ser.F90 +@@ -38 +38 @@ USE utils_ppser, ONLY: & +- REAL(KIND=8), DIMENSION(:,:,:) :: a ++ REAL(KIND=SELECTED_REAL_KIND(15)), DIMENSION(:,:,:) :: a +@@ -59 +59 @@ USE utils_ppser, ONLY: & +- REAL(KIND=8), DIMENSION(:,:,:) :: a ++ REAL(KIND=SELECTED_REAL_KIND(15)), DIMENSION(:,:,:) :: a +@@ -91,2 +91,2 @@ USE utils_ppser, ONLY: & +- REAL(KIND=8), DIMENSION(:,:,:) :: a +- REAL(KIND=8) :: rprecision ++ REAL(KIND=SELECTED_REAL_KIND(15)), DIMENSION(:,:,:) :: a ++ REAL(KIND=SELECTED_REAL_KIND(15)) :: rprecision +@@ -97 +97 @@ USE utils_ppser, ONLY: & +- prefix_ref='SerialboxTest',rprecision=rprecision,rperturb=1.0e-5_8) ++ prefix_ref='SerialboxTest',rprecision=rprecision,rperturb=REAL(1.0e-5,SELECTED_REAL_KIND(15))) +--- a/examples/fortran/simple/main_consumer.F90 ++++ b/examples/fortran/simple/main_consumer.F90 +@@ -14 +14 @@ PROGRAM main_consumer +- REAL(KIND=8), DIMENSION(5,5,5) :: a ++ REAL(KIND=SELECTED_REAL_KIND(15)), DIMENSION(5,5,5) :: a +--- a/examples/fortran/simple/main_producer.F90 ++++ b/examples/fortran/simple/main_producer.F90 +@@ -14 +14 @@ PROGRAM main_producer +- REAL(KIND=8), DIMENSION(5,5,5) :: a ++ REAL(KIND=SELECTED_REAL_KIND(15)), DIMENSION(5,5,5) :: a diff --git a/recipes/icon/25.11/repo/packages/serialbox/nag/ftg.patch b/recipes/icon/25.11/repo/packages/serialbox/nag/ftg.patch new file mode 100644 index 0000000..6794227 --- /dev/null +++ b/recipes/icon/25.11/repo/packages/serialbox/nag/ftg.patch @@ -0,0 +1,31 @@ +# This patch is applicable starting version 2.3.1 +--- a/src/serialbox-fortran/m_ser_ftg.f90 ++++ b/src/serialbox-fortran/m_ser_ftg.f90 +@@ -822,5 +822,5 @@ SUBROUTINE ftg_write_logical_1d(fieldname, field, lbounds, ubounds) + CALL ftg_register_only_internal(fieldname, 'bool', fs_boolsize(), lbounds, ubounds) + END IF +- CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', TRIM(ADJUSTL(ftg_loc_hex(C_LOC(field))))) ++ CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', 'N/A') + END IF + +@@ -853,5 +853,5 @@ SUBROUTINE ftg_write_logical_2d(fieldname, field, lbounds, ubounds) + CALL ftg_register_only_internal(fieldname, 'bool', fs_boolsize(), lbounds, ubounds) + END IF +- CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', TRIM(ADJUSTL(ftg_loc_hex(C_LOC(field))))) ++ CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', 'N/A') + END IF + +@@ -886,5 +886,5 @@ SUBROUTINE ftg_write_logical_3d(fieldname, field, lbounds, ubounds) + CALL ftg_register_only_internal(fieldname, 'bool', fs_boolsize(), lbounds, ubounds) + END IF +- CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', TRIM(ADJUSTL(ftg_loc_hex(C_LOC(field))))) ++ CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', 'N/A') + END IF + +@@ -919,5 +919,5 @@ SUBROUTINE ftg_write_logical_4d(fieldname, field, lbounds, ubounds) + CALL ftg_register_only_internal(fieldname, 'bool', fs_boolsize(), lbounds, ubounds) + END IF +- CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', TRIM(ADJUSTL(ftg_loc_hex(C_LOC(field))))) ++ CALL ftg_add_field_metainfo(TRIM(fieldname), 'ftg:loc', 'N/A') + END IF + diff --git a/recipes/icon/25.11/repo/packages/serialbox/nag/interface.patch b/recipes/icon/25.11/repo/packages/serialbox/nag/interface.patch new file mode 100644 index 0000000..abb79bf --- /dev/null +++ b/recipes/icon/25.11/repo/packages/serialbox/nag/interface.patch @@ -0,0 +1,9 @@ +# This patch is applicable starting version 2.0.1 +--- a/src/serialbox-fortran/utils_ppser.f90 ++++ b/src/serialbox-fortran/utils_ppser.f90 +@@ -33 +33 @@ MODULE utils_ppser +-USE iso_fortran_env ++USE f90_unix_proc; USE iso_fortran_env +@@ -66 +66 @@ SUBROUTINE ppser_initialize(directory, prefix, mode, prefix_ref, mpi_rank, rprec +- REAL(KIND=8), OPTIONAL, INTENT(IN) :: rprecision, rperturb ++ REAL(KIND=SELECTED_REAL_KIND(15)), OPTIONAL, INTENT(IN) :: rprecision, rperturb diff --git a/recipes/icon/25.11/repo/packages/serialbox/package.py b/recipes/icon/25.11/repo/packages/serialbox/package.py new file mode 100644 index 0000000..2217af6 --- /dev/null +++ b/recipes/icon/25.11/repo/packages/serialbox/package.py @@ -0,0 +1,190 @@ +# Copyright Spack Project Developers. See COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +from spack_repo.builtin.build_systems.cmake import CMakePackage + +from spack.package import * + + +class Serialbox(CMakePackage): + """Serialbox is a serialization library and tools for C/C++, Python3 and + Fortran. Serialbox is used in several projects for building validation + frameworks against reference runs.""" + + homepage = "https://github.com/GridTools/serialbox" + url = "https://github.com/GridTools/serialbox/archive/v2.6.1.tar.gz" + + maintainers("skosukhin") + + license("BSD-2-Clause") + + version("2.6.2", sha256="d1b4c79078e3b1d4a45b7b024eb647d21873498ac666e41a5ee8b8e13c95a7ac") + version("2.6.1", sha256="b795ce576e8c4fd137e48e502b07b136079c595c82c660cfa2e284b0ef873342") + version("2.6.0", sha256="9199f8637afbd7f2b3c5ba932d1c63e9e14d553a0cafe6c29107df0e04ee9fae") + version("2.5.4", sha256="f4aee8ef284f58e6847968fe4620e222ac7019d805bbbb26c199e4b6a5094fee") + version("2.5.3", sha256="696499b3f43978238c3bcc8f9de50bce2630c07971c47c9e03af0324652b2d5d") + + depends_on("c", type="build") # generated + depends_on("cxx", type="build") # generated + depends_on("fortran", type="build") # generated + + variant("c", default=True, description="enable C interface") + variant("python", default=False, description="enable Python interface") + variant("fortran", default=False, description="enable Fortran interface") + variant("ftg", default=False, description="enable FortranTestGenerator frontend") + variant("sdb", default=False, description="enable stencil debugger") + variant("shared", default=True, description="build shared libraries") + variant("examples", default=False, description="build the examples") + variant("logging", default=True, description="enable the logging infrastructure") + variant("async-api", default=True, description="enable the asynchronous API") + variant("netcdf", default=False, description="build the NetCDF archive backend") + variant( + "std-filesystem", + default=True, + description="use std::experimental::filesystem (no dependency on " "compiled boost libs)", + ) + + depends_on("cmake@3.12:", type="build") + + depends_on("boost@1.54:", type="build") + depends_on("boost+filesystem+system", when="~std-filesystem", type=("build", "link")) + + depends_on("netcdf-c", when="+netcdf") + + # The preprocessor can be run with Python 2: + depends_on("python", type="run") + # The Python interface is compatible only with Python 3: + depends_on("python@3.4:", when="+python", type=("build", "run")) + depends_on("py-numpy", when="+python", type=("build", "run")) + + # pp_ser fails to process source files containing Unicode character with + # Python 3 (https://github.com/GridTools/serialbox/pull/249): + patch("ppser_py3.patch", when="@2.2.0:") + + # NAG patches: + patch("nag/interface.patch", when="@2.0.1:+fortran%nag") + patch("nag/examples.patch", when="@2.3.1:+fortran+examples%nag") + patch("nag/ftg.patch", when="@2.3.1:+ftg%nag") + patch("nag/bool_getters.patch", when="@2.3.1:+fortran%nag@7.1:") + + # Add missing include directives + # (part of https://github.com/GridTools/serialbox/pull/259): + patch("missing_includes.patch", when="@:2.6.1+c") + + conflicts( + "+ftg", + when="~fortran", + msg="the FortranTestGenerator frontend requires the Fortran " "interface", + ) + conflicts( + "+ftg", + when="@:2.2.999", + msg="the FortranTestGenerator frontend is supported only " "starting version 2.3.0", + ) + conflicts("+sdb", when="~python", msg="the stencil debugger requires the Python interface") + conflicts("+fortran", when="~c", msg="the Fortran interface requires the C interface") + conflicts("+python", when="~c", msg="the Python interface requires the C interface") + conflicts("+python", when="~shared", msg="the Python interface requires the shared libraries") + + def patch(self): + # The following is implemented as a method to avoid having two sets of + # almost identical patch files: one with the CR symbols (for versions + # 2.5.x) and one without them (for versions 2.6.x). + + # Remove hard-coded -march=native + # (see https://github.com/GridTools/serialbox/pull/233): + if self.spec.satisfies("@2.0.1:2.6.0"): + filter_file(r"^(\s*set\(CMAKE_CXX_FLAGS.*-march=native)", r"#\1", "CMakeLists.txt") + + # Do not fallback to boost::filesystem: + if "+std-filesystem" in self.spec: + filter_file( + r"(message\()" r'STATUS( "std::experimental::filesystem not found).*("\))', + r"\1FATAL_ERROR\2\3", + "CMakeLists.txt", + ) + + @property + def libs(self): + query_parameters = self.spec.last_query.extra_parameters + + shared = "+shared" in self.spec + + query2libraries = { + tuple(): ["libSerialboxCore"], + ("c", "fortran"): ["libSerialboxFortran", "libSerialboxC", "libSerialboxCore"], + ("c",): ["libSerialboxC", "libSerialboxCore"], + ("fortran",): ["libSerialboxFortran", "libSerialboxC", "libSerialboxCore"], + } + + key = tuple(sorted(query_parameters)) + libraries = query2libraries[key] + + if self.spec.satisfies("@2.5.0:2.5"): + libraries = [ + "{0}{1}".format(name, "Shared" if shared else "Static") for name in libraries + ] + + libs = find_libraries(libraries, root=self.prefix, shared=shared, recursive=True) + + if libs: + return libs + + msg = "Unable to recursively locate {0} libraries in {1}" + raise NoLibrariesError(msg.format(self.spec.name, self.spec.prefix)) + + def flag_handler(self, name, flags): + cmake_flags = [] + + if name == "cxxflags": + # Intel (at least up to version 19.0.1, version 19.0.4 works) and + # PGI (at least up to version 19.9, version 20.1.0 works) compilers + # have problems with C++11 name mangling. An attempt to link to + # libSerialboxCore leads to: + # undefined reference to + # `std::experimental::filesystem::v1::__cxx11::path:: + # _M_find_extension[abi:cxx11]() const' + if self.spec.satisfies("+std-filesystem%intel@:19.0.1"): + cmake_flags.append("-D_GLIBCXX_USE_CXX11_ABI=0") + + return flags, None, (cmake_flags or None) + + def setup_run_environment(self, env): + # Allow for running the preprocessor directly: + env.prepend_path("PATH", self.prefix.python.pp_ser) + # Allow for running the preprocessor as a Python module, as well as + # enable the Python interface in a non-standard directory: + env.prepend_path("PYTHONPATH", self.prefix.python.pp_ser) + + def setup_dependent_package(self, module, dependent_spec): + # Simplify the location of the preprocessor by dependent packages: + self.spec.pp_ser = join_path(self.prefix.python.pp_ser, "pp_ser.py") + + def cmake_args(self): + args = [ + "-DBOOST_ROOT:PATH=%s" % self.spec["boost"].prefix, + # https://cmake.org/cmake/help/v3.15/module/FindBoost.html#boost-cmake + self.define("Boost_NO_BOOST_CMAKE", True), + self.define_from_variant("SERIALBOX_ENABLE_C", "c"), + self.define_from_variant("SERIALBOX_ENABLE_PYTHON", "python"), + self.define_from_variant("SERIALBOX_ENABLE_FORTRAN", "fortran"), + self.define_from_variant("SERIALBOX_ENABLE_FTG", "ftg"), + self.define_from_variant("SERIALBOX_ENABLE_SDB", "sdb"), + self.define_from_variant("SERIALBOX_BUILD_SHARED", "shared"), + self.define_from_variant("SERIALBOX_EXAMPLES", "examples"), + self.define_from_variant("SERIALBOX_LOGGING", "logging"), + self.define_from_variant("SERIALBOX_ASYNC_API", "async-api"), + # CMake scripts of Serialbox (at least up to version 2.6.0) are + # broken and do not instruct the compiler to link to the OpenSSL + # libraries: + self.define("SERIALBOX_USE_OPENSSL", False), + self.define_from_variant("SERIALBOX_ENABLE_EXPERIMENTAL_FILESYSTEM", "std-filesystem"), + self.define_from_variant("SERIALBOX_USE_NETCDF", "netcdf"), + self.define("SERIALBOX_TESTING", self.run_tests), + ] + + if "+netcdf" in self.spec: + args.append("-DNETCDF_ROOT:PATH=%s" % self.spec["netcdf-c"].prefix) + + return args diff --git a/recipes/icon/25.11/repo/packages/serialbox/ppser_py3.patch b/recipes/icon/25.11/repo/packages/serialbox/ppser_py3.patch new file mode 100644 index 0000000..6997c63 --- /dev/null +++ b/recipes/icon/25.11/repo/packages/serialbox/ppser_py3.patch @@ -0,0 +1,48 @@ +# This patch is applicable starting version 2.2.0 +--- a/src/serialbox-python/pp_ser/pp_ser.py ++++ b/src/serialbox-python/pp_ser/pp_ser.py +@@ -51 +51 @@ __email__ = 'oliver.fuhrer@meteoswiss.ch' +-def to_ascii(text): ++def open23(name, mode='r'): +@@ -53 +53,10 @@ def to_ascii(text): +- return bytes(text, 'ascii') ++ return open(name, mode, ++ encoding=(None if 'b' in mode else 'UTF-8'), ++ errors=(None if 'b' in mode else 'surrogateescape')) ++ else: ++ return open(name, mode) ++ ++ ++def bytes23(text): ++ if sys.version_info[0] == 3: ++ return bytes(text, 'UTF-8', 'surrogateescape') +@@ -57,0 +67,11 @@ def to_ascii(text): ++def getline(filename, lineno): ++ try: ++ return linecache.getline(filename, lineno) ++ except: ++ with open23(filename, 'r') as f: ++ for i, line in enumerate(f, start=1): ++ if i == lineno: ++ return line ++ return '' ++ ++ +@@ -608 +628 @@ class PpSer: +- nextline = linecache.getline(os.path.join(self.infile), lookahead_index) ++ nextline = getline(os.path.join(self.infile), lookahead_index) +@@ -613 +633 @@ class PpSer: +- nextline = linecache.getline(os.path.join(self.infile), lookahead_index) ++ nextline = getline(os.path.join(self.infile), lookahead_index) +@@ -711 +731 @@ class PpSer: +- nextline = linecache.getline(os.path.join(self.infile), lookahead_index) ++ nextline = getline(os.path.join(self.infile), lookahead_index) +@@ -716 +736 @@ class PpSer: +- nextline = linecache.getline(os.path.join(self.infile), lookahead_index) ++ nextline = getline(os.path.join(self.infile), lookahead_index) +@@ -803 +823 @@ class PpSer: +- input_file = open(os.path.join(self.infile), 'r') ++ input_file = open23(os.path.join(self.infile), 'r') +@@ -843 +863 @@ class PpSer: +- output_file.write(to_ascii(self.__outputBuffer)) ++ output_file.write(bytes23(self.__outputBuffer)) diff --git a/recipes/icon/25.11/repo/packages/serialbox/readme.md b/recipes/icon/25.11/repo/packages/serialbox/readme.md new file mode 100644 index 0000000..51d9ac6 --- /dev/null +++ b/recipes/icon/25.11/repo/packages/serialbox/readme.md @@ -0,0 +1,2 @@ +copied March 28 2025 from mainline spack (commit 2f3ef790e2ac4d515fa8694874e646ee09e1c42a) in order to get version 2.6.2 +