summaryrefslogtreecommitdiff
path: root/var/spack/repos/builtin/packages/netcdf-cxx4/package.py
blob: ae6e541d1a93a8d173be1e844164610c4c507ab4 (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
# 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 os

from spack.package import *


class NetcdfCxx4(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 C++ distribution."""

    homepage = "https://www.unidata.ucar.edu/software/netcdf"
    url = "ftp://ftp.unidata.ucar.edu/pub/netcdf/netcdf-cxx4-4.3.1.tar.gz"

    maintainers("WardF")

    license("Apache-2.0")

    version("4.3.1", sha256="6a1189a181eed043b5859e15d5c080c30d0e107406fbb212c8fb9814e90f3445")
    version("4.3.0", sha256="e34fbc6aba243ec82c23e9ee99db2430555ada849c54c1f3ab081b0ddd0f5f30")

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

    depends_on("netcdf-c")

    depends_on("doxygen", when="+doc", type="build")

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

    def flag_handler(self, name, flags):
        if name == "cflags" and "+pic" in self.spec:
            flags.append(self.compiler.cc_pic_flag)
        if name == "cxxflags" and "+pic" in self.spec:
            flags.append(self.compiler.cxx_pic_flag)
        elif name == "ldlibs":
            # Address the underlinking problem reported in
            # https://github.com/Unidata/netcdf-cxx4/issues/86, which also
            # results into a linking error on macOS:
            flags.append(self.spec["netcdf-c"].libs.link_flags)

        # Note that cflags and cxxflags 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 = ["libnetcdf_c++4"]

        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)
        )

    @when("@4.3.1:+shared")
    @on_package_attributes(run_tests=True)
    def patch(self):
        # We enable the filter tests only when the tests are requested by the
        # user. This, however, has a side effect: an extra file 'libh5bzip2.so'
        # gets installed (note that the file has .so extension even on darwin).
        # It's unclear whether that is intended but given the description of the
        # configure option --disable-filter-testing (Do not run filter test and
        # example; requires shared libraries and netCDF-4), we currently assume
        # that the file is not really meant for the installation. To make all
        # installations consistent and independent of whether the shared
        # libraries or the tests are requested, we prevent installation of
        # 'libh5bzip2.so':
        filter_file(
            r"(^\s*)lib(_LTLIBRARIES\s*)(=\s*libh5bzip2\.la\s*$)",
            r"\1noinst\2+\3",
            join_path(self.stage.source_path, "plugins", "Makefile.in"),
        )

    def configure_args(self):
        config_args = self.enable_or_disable("shared")

        if "+doc" in self.spec:
            config_args.append("--enable-doxygen")
        else:
            config_args.append("--disable-doxygen")

        if self.spec.satisfies("@4.3.1:"):
            if self.run_tests and "+shared" in self.spec:
                config_args.append("--enable-filter-testing")
                if self.spec.satisfies("^hdf5+mpi"):
                    # The package itself does not need the MPI libraries but
                    # includes <hdf5.h> in the filter test C code, which
                    # requires <mpi.h> when HDF5 is built with the MPI support.
                    # Using the MPI wrapper introduces overlinking to MPI
                    # libraries and we would prefer not to use it but it is the
                    # only reliable way to provide the compiler with the correct
                    # path to <mpi.h>. For example, <mpi.h> of a MacPorts-built
                    # MPICH might reside in /opt/local/include/mpich-gcc10,
                    # which Spack does not know about and cannot inject with its
                    # compiler wrapper.
                    config_args.append("CC={0}".format(self.spec["mpi"].mpicc))
            else:
                config_args.append("--disable-filter-testing")

        return config_args

    @run_after("configure")
    def rename_version(self):
        # See https://github.com/Unidata/netcdf-cxx4/issues/109
        # The issue is fixed upstream:
        #   https://github.com/Unidata/netcdf-cxx4/commit/e7cc5bab02cf089dc79616456a0a951fee979fe9
        # We do not apply the upstream patch because we want to avoid running
        # autoreconf and introduce additional dependencies. We do not generate a
        # patch for the configure script because the patched string contains the
        # version and we would need a patch file for each supported version of
        # the library. We do not implement the patching with filter_file in the
        # patch method because writing a robust regexp seems to be more
        # difficult that simply renaming the file if exists. It also looks like
        # we can simply remove the file since it is not used anywhere.
        if not self.spec.satisfies("@:4.3.1 platform=darwin"):
            return

        with working_dir(self.build_directory):
            fname = "VERSION"
            if os.path.exists(fname):
                os.rename(fname, "{0}.txt".format(fname))

    def check(self):
        with working_dir(self.build_directory):
            make("check", parallel=False)