summaryrefslogtreecommitdiff
path: root/var/spack/repos/builtin/packages/netcdf-fortran/package.py
blob: d43db75fa8ee792ef7cf7ff47da5714ffb05e10c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# Copyright 2013-2023 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)

import glob
import os
from shutil import Error, copyfile

from spack.package import *


class NetcdfFortran(AutotoolsPackage):
    """NetCDF (network Common Data Form) is a set of software libraries and
    machine-independent data formats that support the creation, access, and
    sharing of array-oriented scientific data. This is the Fortran
    distribution."""

    homepage = "https://www.unidata.ucar.edu/software/netcdf"
    url = "https://downloads.unidata.ucar.edu/netcdf-fortran/4.5.4/netcdf-fortran-4.5.4.tar.gz"

    maintainers("skosukhin", "WardF")

    license("Apache-2.0")

    version("4.6.1", sha256="b50b0c72b8b16b140201a020936aa8aeda5c79cf265c55160986cd637807a37a")
    version("4.6.0", sha256="198bff6534cc85a121adc9e12f1c4bc53406c403bda331775a1291509e7b2f23")
    version("4.5.4", sha256="0a19b26a2b6e29fab5d29d7d7e08c24e87712d09a5cafeea90e16e0a2ab86b81")
    version("4.5.3", sha256="123a5c6184336891e62cf2936b9f2d1c54e8dee299cfd9d2c1a1eb05dd668a74")
    version("4.5.2", sha256="b959937d7d9045184e9d2040a915d94a7f4d0185f4a9dceb8f08c94b0c3304aa")
    version("4.4.5", sha256="2467536ce29daea348c736476aa8e684c075d2f6cab12f3361885cb6905717b8")
    version("4.4.4", sha256="b2d395175f8d283e68c8be516e231a96b191ade67ad0caafaf7fa01b1e6b5d75")
    version("4.4.3", sha256="330373aa163d5931e475b5e83da5c1ad041e855185f24e6a8b85d73b48d6cda9")

    variant("pic", default=True, description="Produce position-independent code (for shared libs)")
    variant("shared", default=True, description="Enable shared library")
    variant("doc", default=False, description="Enable building docs")

    depends_on("netcdf-c")
    depends_on("netcdf-c@4.7.4:", when="@4.5.3:")  # nc_def_var_szip required
    depends_on("doxygen", when="+doc", type="build")

    # Enable 'make check' for NAG, which is too strict.
    patch("nag_testing.patch", when="@4.4.5%nag")

    # File fortran/nf_logging.F90 is compiled without -DLOGGING, which leads
    # to missing symbols in the library. Additionally, the patch enables
    # building with NAG, which refuses to compile empty source files (see also
    # comments in the patch):
    patch("logging.patch", when="@:4.4.5")

    # Prevent excessive linking to system libraries. Without this patch the
    # library might get linked to the system installation of libcurl. See
    # https://github.com/Unidata/netcdf-fortran/commit/0a11f580faebbc1c4dce68bf5135709d1c7c7cc1#diff-67e997bcfdac55191033d57a16d1408a
    patch("excessive_linking.patch", when="@4.4.5")

    # Parallel builds do not work in the fortran directory. This patch is
    # derived from https://github.com/Unidata/netcdf-fortran/pull/211
    patch("no_parallel_build.patch", when="@4.5.2")

    filter_compiler_wrappers("nf-config", relative_root="bin")

    def flag_handler(self, name, flags):
        if name == "cflags":
            if "+pic" in self.spec:
                flags.append(self.compiler.cc_pic_flag)
        elif name == "fflags":
            if "+pic" in self.spec:
                flags.append(self.compiler.f77_pic_flag)
            if self.spec.satisfies("%gcc@10:"):
                # https://github.com/Unidata/netcdf-fortran/issues/212
                flags.append("-fallow-argument-mismatch")
            elif self.compiler.name == "cce":
                # Cray compiler generates module files with uppercase names by
                # default, which is not handled by the makefiles of
                # NetCDF-Fortran:
                # https://github.com/Unidata/netcdf-fortran/pull/221.
                # The following flag forces the compiler to produce module
                # files with lowercase names.
                flags.append("-ef")

        # Note that cflags and fflags should be added by the compiler wrapper
        # and not on the command line to avoid overriding the default
        # compilation flags set by the configure script:
        return flags, None, None

    @property
    def libs(self):
        libraries = ["libnetcdff"]

        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

        libs = find_libraries(libraries, root=self.prefix, shared=shared, recursive=True)

        if libs:
            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)
        )

    def configure_args(self):
        config_args = ["--enable-static"]
        config_args += self.enable_or_disable("shared")
        config_args += self.enable_or_disable("doxygen", variant="doc")

        netcdf_c_spec = self.spec["netcdf-c"]
        if "+mpi" in netcdf_c_spec or "+parallel-netcdf" in netcdf_c_spec:
            # Prefixing with 'mpiexec -n 4' is not necessarily the correct way
            # to launch MPI programs on a particular machine (e.g. 'srun -n 4'
            # with additional arguments might be the right one). Therefore, we
            # make sure the parallel tests are not launched at all (although it
            # is the default behaviour currently):
            config_args.append("--disable-parallel-tests")
            if self.spec.satisfies("@4.5.0:4.5.2"):
                # Versions from 4.5.0 to 4.5.2 check whether the Fortran MPI
                # interface is available and fail the configuration if it is
                # not. However, the interface is needed for a subset of the test
                # programs only (the library itself does not need it), which are
                # not run by default and explicitly disabled above. To avoid the
                # configuration failure, we set the following cache variable:
                config_args.append("ac_cv_func_MPI_File_open=yes")

        return config_args

    def check(self):
        make("check", parallel=self.spec.satisfies("@4.5:"))

    @run_after("install")
    def cray_module_filenames(self):
        # Cray compiler searches for module files with uppercase names by
        # default and with lowercase names when the '-ef' flag is specified.
        # To avoid warning messages when compiler user applications in both
        # cases, we create copies of all '*.mod' files in the prefix/include
        # with names in upper- and lowercase.
        if self.spec.compiler.name != "cce":
            return

        with working_dir(self.spec.prefix.include):
            for f in glob.glob("*.mod"):
                name, ext = os.path.splitext(f)
                try:
                    # Create a copy with uppercase name:
                    copyfile(f, name.upper() + ext)
                except Error:
                    # Assume that the exception tells us that the file with
                    # uppercase name already exists. Try to create a file with
                    # lowercase name then:
                    try:
                        copyfile(f, name.lower() + ext)
                    except Error:
                        pass