diff --git a/.github/build-ci/manifests/access_esm3/intel.spack.yaml.j2 b/.github/build-ci/manifests/access_esm3/intel.spack.yaml.j2 new file mode 100644 index 00000000..6ca5eef5 --- /dev/null +++ b/.github/build-ci/manifests/access_esm3/intel.spack.yaml.j2 @@ -0,0 +1,29 @@ +spack: + specs: + # package is defined in the workflows inputs.spack-manifest-data-pairs + # intel_compiler_ver is defined in the standard_definitions.json data file + - '{{ package }}' + packages: + access3: + require: + - 'configurations=MOM6-CICE6-UM13,MOM6-UM13' + um: + require: + - '@13.0' + - casim_ref=um13.0 jules_ref=JULES_vn7.0 shumlib_ref=um13.0 socrates_ref=um13.0 ukca_ref=b42593d0c8fe744f9cc1d1556a664fec792f4766 um_ref=vn13.0_nuopc_esmf_flags + access-cice: + require: + - '@git.3286c36f9b9125ffddbc4d3aa9f98ff87ae1aded=CICE6.6.3-0' + python: + require: + - '@3.11.14' + intel-oneapi-compilers-classic: + require: + - '{{ intel_compiler_ver }}' + all: + require: + - '%access_intel' + - 'target={{ target }}' + concretizer: + unify: false + view: false diff --git a/spack_repo/access/nri/build_systems/um_base.py b/spack_repo/access/nri/build_systems/um_base.py index cbd4376d..2f89a2db 100644 --- a/spack_repo/access/nri/build_systems/um_base.py +++ b/spack_repo/access/nri/build_systems/um_base.py @@ -158,7 +158,7 @@ class UmBasePackage(Package): when="+DR_HOOK") depends_on("eccodes +fortran +netcdf", type=("build", "link", "run"), when="+eccodes") - depends_on("netcdf-fortran@4.5.2", type=("build", "link", "run"), + depends_on("netcdf-fortran@4.5.2:", type=("build", "link", "run"), when="+netcdf") phases = ["build", "install"] diff --git a/spack_repo/access/nri/packages/access3/package.py b/spack_repo/access/nri/packages/access3/package.py index 6bad832f..90505f3c 100644 --- a/spack_repo/access/nri/packages/access3/package.py +++ b/spack_repo/access/nri/packages/access3/package.py @@ -14,6 +14,8 @@ "MOM6-CICE6", "CICE6-WW3", "MOM6-CICE6-WW3", + "MOM6-UM13", + "MOM6-CICE6-UM13", ) # tag,commit pairs for releases in access3-share git repository @@ -78,6 +80,12 @@ class Access3(CMakePackage): depends_on("access-mom6@2025.02.000: +access3", when=f"configurations={conf}") if "WW3" in conf: depends_on("access-ww3@2025.03.0: +access3", when=f"configurations={conf}") + if "UM13" in conf: + conflicts('@:2026.03.001') + depends_on("um +access3+netcdf~eccodes~DR_HOOK", when=f"configurations={conf}") + if "CICE6" in conf and "UM13" in conf: + # Set the driver variant for the UM-CICE coupling code + depends_on("access-cice driver=access/cmeps", when=f"configurations={conf}") def cmake_args(self): # make configurations a cmake argument diff --git a/spack_repo/access/nri/packages/access_esm3/package.py b/spack_repo/access/nri/packages/access_esm3/package.py new file mode 100644 index 00000000..015e4b83 --- /dev/null +++ b/spack_repo/access/nri/packages/access_esm3/package.py @@ -0,0 +1,26 @@ +# Copyright Spack Project Developers. See COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +from spack_repo.builtin.build_systems.bundle import BundlePackage +from spack.package import * + + +class AccessEsm3(BundlePackage): + """ + ACCESS-ESM3 bundle containing the ACCESS-EM3 Package. + + This is used to version the entirety of a released deployment, including + the package, it's dependencies, and the version of + spack-packages/spack-config that it is bundled with + """ + + homepage = "https://www.access-nri.org.au" + + git = "https://github.com/ACCESS-NRI/ACCESS-ESM3.git" + + maintainers("anton-seaice") + + version("latest") + + depends_on("access3") diff --git a/spack_repo/access/nri/packages/gcom/package.py b/spack_repo/access/nri/packages/gcom/package.py index 12834c14..0004c7c8 100644 --- a/spack_repo/access/nri/packages/gcom/package.py +++ b/spack_repo/access/nri/packages/gcom/package.py @@ -5,6 +5,7 @@ # Copyright 2024-2026 ACCESS-NRI from spack_repo.builtin.build_systems.generic import Package +from spack.version.version_types import GitVersion, StandardVersion from spack.package import * @@ -86,7 +87,46 @@ def install(self, spec, prefix): # Do the build with fcm fcm("make", "-f", "fcm-make/gcom.cfg") + self.__create_pkgconfig(spec, prefix) + # Install the library mkdirp(prefix.lib) install("build/lib/libgcom.a", prefix.lib + "/libgcom.a") + install_tree("build/lib/pkgconfig", prefix.lib + "/pkgconfig") install_tree("build/include", prefix.include) + + def __create_pkgconfig(self, spec, prefix): + + # Workaround for https://github.com/spack/spack/issues/50118 + Version = self.spec.version + if isinstance(Version, GitVersion): + version_str = Version.ref_version.string + elif isinstance(Version, StandardVersion): + version_str = Version.string + else: + version_str = "unknown" + + # Location to install pkgconf file + pkgdir = "build/lib/pkgconfig" + mkdirp(pkgdir) + + k = "gcom" + lib = f"lib{k}" + text = f"""\ +prefix={prefix} +exec_prefix=${{prefix}} +libdir=${{exec_prefix}}/lib +includedir=${{prefix}}/include + +Name: {lib} +Description: GCOM {version_str} {lib} Library for Fortran +Version: {version_str} +Libs: -L${{libdir}} -l{k} +Cflags: -I${{includedir}} +""" + pcpath = join_path(pkgdir, f"{lib}.pc") + with open(pcpath, "w", encoding="utf-8") as pc: + nchars_written = pc.write(text) + + if nchars_written < len(text): + raise OSError \ No newline at end of file diff --git a/spack_repo/access/nri/packages/um/package.py b/spack_repo/access/nri/packages/um/package.py index ab907e05..a1c34370 100644 --- a/spack_repo/access/nri/packages/um/package.py +++ b/spack_repo/access/nri/packages/um/package.py @@ -6,7 +6,9 @@ # Based on https://github.com/nci/spack-repo/blob/main/packages/um/package.py from spack_repo.access.nri.build_systems.um_base import UmBasePackage +from spack.version.version_types import StandardVersion from spack.package import * +from os.path import exists class Um(UmBasePackage): """ @@ -41,24 +43,96 @@ class Um(UmBasePackage): variant("mpi", default=True, description="Build with MPI") depends_on("mpi", when="+mpi", type=("build", "link", "run")) + variant("access3", default=False, + description="Install UM as library for Access3 models") + + with when("+access3"): + depends_on("esmf@8.7.0:") + conflicts("~netcdf") + + phases = ["build", "create_pkgconfig", "install"] + + def setup_run_environment(self, env): """ Set the built path into the environment. """ # Add the built executables to the path - env.prepend_path("PATH", join_path(self.prefix, "build-atmos", "bin")) + if not self.spec.variants["access3"].value: + env.prepend_path("PATH", join_path(self.prefix, "build-atmos", "bin")) env.prepend_path("PATH", join_path(self.prefix, "build-recon", "bin")) def install(self, spec, prefix): """ - Install executables and accompanying files into the prefix directory, - according to the directory structure of EXEC_DIR, as described in (e.g.) - https://code.metoffice.gov.uk/trac/roses-u/browser/b/y/3/9/5/trunk/meta/rose-meta.conf + Install executables and libraries into spack release folder (prefix) + When ~access3, this package installs um-atmos.exe + When +access3, the package installs libum-atmos.a + um-recon.exe is always installed. """ - for um_exe in ["atmos", "recon"]: - bin_dir = join_path(f"build-{um_exe}", "bin") + + # List of executables to install, always install recon + um_exe = ["recon"] + + if self.spec.variants["access3"].value: + # Install library files from build-atmos directory straight into prefix path + # so it is in the expected CMAKE_PREFIX_PATH for dependents + for dir_name in ["lib", "include"]: + dir_path = join_path("build-atmos", dir_name) + build_dir = join_path(self.build_dir(), dir_path) + install_dir = join_path(prefix, dir_name) + mkdirp(install_dir) + install_tree(build_dir, install_dir) + else: + # Install atmos executable + um_exe.append("atmos") + + # Install executables and accompanying files into the prefix directory, + # according to the directory structure of EXEC_DIR, as described in (e.g.) + # https://code.metoffice.gov.uk/trac/roses-u/browser/b/y/3/9/5/trunk/meta/rose-meta.conf + for exe in um_exe: + bin_dir = join_path(f"build-{exe}", "bin") build_bin_dir = join_path(self.build_dir(), bin_dir) install_bin_dir = join_path(prefix, bin_dir) mkdirp(install_bin_dir) install_tree(build_bin_dir, install_bin_dir) + + def create_pkgconfig(self, spec, prefix): + """ + If a um-atmos library has been created, make a pkgconfig file for it + """ + k = "um-atmos" + libdir = f"{self.build_dir()}/build-atmos/lib" + lib = f"lib{k}" + + if exists(f"{libdir}/{lib}.a"): + + pkgdir = f"{libdir}/pkgconfig" + mkdirp(pkgdir) + + # Workaround for https://github.com/spack/spack/issues/50118 + Version = self.spec.version + if isinstance(Version, StandardVersion): + version_str = Version.string + else: + version_str = "unknown" + + text = f"""\ +prefix={prefix} +exec_prefix=${{prefix}} +libdir=${{exec_prefix}}/lib +includedir=${{prefix}}/include + +Name: {lib} +Description: UM {version_str} {lib} Library for Fortran +Version: {version_str} +Requires: libgcom +Libs: -L${{libdir}} -l{k} +Cflags: -I${{includedir}} +""" + pcpath = join_path(pkgdir, f"{lib}.pc") + with open(pcpath, "w", encoding="utf-8") as pc: + nchars_written = pc.write(text) + + if nchars_written < len(text): + raise OSError \ No newline at end of file