summaryrefslogtreecommitdiff
path: root/var/spack/repos/builtin/packages/intel-tbb/package.py
blob: 8f3ca07ed17312452f3a598251022cd2350a7f73 (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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# 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 inspect
import platform
import sys

import spack.build_systems.cmake
import spack.build_systems.makefile
from spack.package import *


class IntelTbb(CMakePackage, MakefilePackage):
    """Widely used C++ template library for task parallelism.
    Intel Threading Building Blocks (Intel TBB) lets you easily write parallel
    C++ programs that take full advantage of multicore performance, that are
    portable and composable, and that have future-proof scalability.
    """

    homepage = "https://www.threadingbuildingblocks.org/"
    url_prefix = "https://github.com/oneapi-src/oneTBB/"
    url = url_prefix + "archive/v2020.1.tar.gz"
    git = "https://github.com/oneapi-src/oneTBB.git"

    maintainers("rscohn2")

    # Note: when adding new versions, please check and update the
    # patches, filters and url_for_version() below as needed.

    license("Apache-2.0")

    version("master", branch="master")
    version("2021.9.0", sha256="1ce48f34dada7837f510735ff1172f6e2c261b09460e3bf773b49791d247d24e")
    version("2021.8.0", sha256="eee380323bb7ce864355ed9431f85c43955faaae9e9bce35c62b372d7ffd9f8b")
    version("2021.7.0", sha256="2cae2a80cda7d45dc7c072e4295c675fff5ad8316691f26f40539f7e7e54c0cc")
    version("2021.6.0", sha256="4897dd106d573e9dacda8509ca5af1a0e008755bf9c383ef6777ac490223031f")
    version("2021.5.0", sha256="e5b57537c741400cf6134b428fc1689a649d7d38d9bb9c1b6d64f092ea28178a")
    version("2021.4.0", sha256="021796c7845e155e616f5ecda16daa606ebb4c6f90b996e5c08aebab7a8d3de3")
    version("2021.3.0", sha256="8f616561603695bbb83871875d2c6051ea28f8187dbe59299961369904d1d49e")
    version("2021.2.0", sha256="cee20b0a71d977416f3e3b4ec643ee4f38cedeb2a9ff015303431dd9d8d79854")
    version("2021.1.1", sha256="b182c73caaaabc44ddc5ad13113aca7e453af73c1690e4061f71dfe4935d74e8")
    version("2020.3", sha256="ebc4f6aa47972daed1f7bf71d100ae5bf6931c2e3144cf299c8cc7d041dca2f3")
    version("2020.2", sha256="4804320e1e6cbe3a5421997b52199e3c1a3829b2ecb6489641da4b8e32faf500")
    version("2020.1", sha256="7c96a150ed22bc3c6628bc3fef9ed475c00887b26d37bca61518d76a56510971")
    version("2020.0", sha256="57714f2d2cf33935db33cee93af57eb3ecd5a7bef40c1fb7ca4a41d79684b118")
    version("2019.9", sha256="3f5ea81b9caa195f1967a599036b473b2e7c347117330cda99b79cfcf5b77c84")
    version("2019.8", sha256="6b540118cbc79f9cbc06a35033c18156c21b84ab7b6cf56d773b168ad2b68566")
    version("2019.7", sha256="94847fc627ed081c63ea253e31f23645ed3671548106b095ce303d1da5d76275")
    version("2019.6", sha256="21cd496ac768560e70d35e5423878aa3bcf0285f7194be77935d8febf0b18f47")
    version("2019.5", sha256="abf9236e6ec9a3675fa59ab56c2192c7ab4f7096a82af118e8efa514b2541578")
    version("2019.4", sha256="673e540aba6e526b220cbeacc3e4ff7b19a8689a00d7a09a9dc94396d73b24df")
    version("2019.3", sha256="4cb6bde796ae056e7c29f31bfdc6cfd0cfe848925219e9c82a20f09158e81542")
    version("2019.2", sha256="3bbe21054bd5b593ef99d4dfe451432cbf1f6f9429cd0dd543e879ef7e4e3327")
    version("2019.1", sha256="e6fb8dd1a1ae834b4e5f4ae6c4c87a3362f81a3aaeddfa6325168c6cfee59391")
    version("2019", sha256="91f00308a4e431bd9632b439d516134d7084f1eb35f52b7c9b111b46bdfcf093")
    version("2018.6", sha256="0ebb5fc877871ef15f7395d6e3c86de4ffedb820dc336383a3ab71fc39426aa7")
    version("2018.5", sha256="b8dbab5aea2b70cf07844f86fa413e549e099aa3205b6a04059ca92ead93a372")
    version("2018.4", sha256="c973b41b6da3db10efa7e14ce64a850e3fbfbcc16374494a005bf994d53a770a")
    version("2018.3", sha256="e5f19d747f6adabfc7daf2cc0a1ddcfab0f26bc083d70ea0a63def4a9f3919c5")
    version("2018.2", sha256="733c4dba646573b8285b1923dc106f0d771725bea620baa3659c86ab9312a1f4")
    version("2018.1", sha256="a9f51e0d081fbdda441d0150e759c7562318d6d7bc5a0c9a9d8064217d4d8d8d")
    version("2018", sha256="d427c58a59863c5f9510fffb3d05cd1bcc7abb94cdde1613407559e88b1263ab")
    version("2017.8", sha256="227cc1a8329da67f9957285f0020ad4d73d9ce26cbf88614349b8b74bb189ae1")
    version("2017.7", sha256="f487243e5931e967479189ef75946f02e3bb666ea73dcc19ac2828edd5550746")
    version("2017.6", sha256="b0f40edd010b90ce2519c1cebfa6f33216a1828d4fba19291b5cd23bd7fe809b")
    version("2017.5", sha256="b785e7181317350f0bb20f7bffda20bdecde7e82b824d2e5eb6d408a3b9cbeaf")
    version("2017.4", sha256="9a70ae3068767bf8c530bf98b9bbc655e36e82a301b347f7de76f99f401df1dd")
    version("2017.3", sha256="230ed3ff32bb3e91df1f59e4a3a567bde02639d9970b7e87cee0421b4c0b0f23")
    version("2017.2", sha256="dd37c896f95ca2357e828c24c9c4a169c6a6b5c905b3862a6cab09474d164497")
    version("2017.1", sha256="9b5b36b6d0ed97a3a1711b9095e78aed79bc998957a4a6b3d8a7af063523f037")
    version("2017", sha256="470544b0f374987273cc12e7706353edba8f9547578291d45b5b29358d4e5e81")
    version("4.4.6", sha256="65101b3a0eda38320ec3e3603daa79c54e6a60fb59ed2959738eaf4ce6d17f0a")
    version("4.4.5", sha256="2e372703fe444442c77760229897f00bb4babff62f7d0861b3f2783883cb257e")
    version("4.4.4", sha256="3ed03838c4e368b78305b0561cac48d369919bb4d9d68edd4d8a3becd6f62f5c")
    version("4.4.3", sha256="f0ff2e3735c8057b792f29c96f4f7623c1e4c76abfeda88be48645b8338c0f00")
    version("4.4.2", sha256="1ab10e70354685cee3ddf614f3e291434cea86c8eb62031e025f4052278152ad")
    version("4.4.1", sha256="05737bf6dd220b31aad63d77ca59c742271f81b4cc6643aa6f93d37450ae32b5")
    version("4.4", sha256="93c74b6054c69c86fa49d0fce7c50061fc907cb198a7237b8dd058298fd40c0e")

    build_system(
        conditional("makefile", when="@:2020.3"),
        conditional("cmake", when="@2021:"),
        default="cmake",
    )

    provides("tbb")

    # Clang builds incorrectly determine GCC version which in turn incorrectly
    # causes a mismatch in C++ features resulting in a link error. This also
    # means that clang builds require a gcc compiler to work correctly (this
    # has always been the case).
    #
    #    See https://github.com/intel/tbb/pull/147 for details.
    #
    conflicts("%apple-clang", when="@:2019.6", msg="2019.7 or later required for clang")
    conflicts("%clang", when="@:2019.6", msg="2019.7 or later required for clang")

    conflicts("%gcc@6.1:", when="@:4.4.3", msg="4.4.4 or later required for GCC >= 6.1.")

    variant("shared", default=True, description="Builds a shared version of TBB libraries")

    variant(
        "cxxstd",
        default="default",
        values=("default", "98", "11", "14", "17"),
        multi=False,
        description="Use the specified C++ standard when building.",
    )

    variant("tm", default=True, description="Enable use of transactional memory on x86")

    # Testing version ranges inside when clauses was fixed in e9ee9eaf.
    # See: #8957 and #13989.

    # Build and install CMake config files if we're new enough.
    # CMake support started in 2017.7.
    depends_on("cmake@3.1.0:", type="build", when="@2017.7:")

    depends_on("hwloc", when="@2021.1.1:")

    # Patch for pedantic warnings (#10836).  This was fixed in the TBB
    # source tree in 2019.6.
    patch("gcc_generic-pedantic-2019.patch", level=1, when="@2019.1:2019.5")
    patch("gcc_generic-pedantic-4.4.patch", level=1, when="@:2019.0")

    # Patch and conflicts for GCC 13 support (#1031).
    patch("gcc_13-2021-v2.patch", when="@2021.1:")
    conflicts("%gcc@13", when="@:2021.3")

    # Patch cmakeConfig.cmake.in to find the libraries where we install them.
    patch("tbb_cmakeConfig-2019.5.patch", level=0, when="@2019.5:2021.0")
    patch("tbb_cmakeConfig.patch", level=0, when="@2017.7:2019.4")

    # Restore the debug targets.
    patch("makefile-debug.patch", when="@2020:2021.0")

    # Some very old systems don't support transactional memory.
    patch("disable-tm.patch", when="~tm")

    # Add support for building on arm64 macOS,
    # also included in hombrew and already available upstream:
    # https://github.com/oneapi-src/oneTBB/pull/258
    # https://github.com/oneapi-src/oneTBB/commit/86f6dcdc17a8f5ef2382faaef860cfa5243984fe.patch?full_index=1
    patch("macos-arm64.patch", when="@:2021.0")

    # build older tbb with %oneapi
    patch("intel-tbb.2020.3-icx.patch", when="@2020.3 %oneapi")

    # Support for building with %nvhpc
    # 1) remove flags nvhpc compilers do not recognize
    patch("intel-tbb.nvhpc-remove-flags.2017.patch", when="@2017:2018.9 %nvhpc")
    patch("intel-tbb.nvhpc-remove-flags.2019.patch", when="@2019:2019.0 %nvhpc")
    patch("intel-tbb.nvhpc-remove-flags.2019.1.patch", when="@2019.1:2019.6 %nvhpc")
    patch("intel-tbb.nvhpc-remove-flags.2019.7.patch", when="@2019.7:2019.8 %nvhpc")
    # The 2019.9 patch below was tested successfully
    # on @2019.9, @2020.0, and @2020.3
    patch("intel-tbb.nvhpc-remove-flags.2019.9.patch", when="@2019.9: %nvhpc")
    # 2) Fix generation of version script tbb.def for ld (nvc++ -E
    # appears to produce more output than g++ -E which was causing problems)
    # The 2017 patch below was tested on @2017, @2017.8, @2018,
    # @2018.3, @2018.6, 2019, @2019.[1-9], and @2020.[0-3]
    patch("intel-tbb.nvhpc-version-script-fix.2017.patch", when="@2017 %nvhpc")

    # Version and tar file names:
    #  2020.0 --> v2020.0.tar.gz  starting with 2020
    #  2017.1 --> 2017_U1.tar.gz  starting with 2017
    #  2017   --> 2017.tar.gz
    #  4.4.6  --> 4.4.6.tar.gz
    #
    def url_for_version(self, version):
        url = self.url_prefix + "archive/{0}.tar.gz"
        if version[0] >= 2020:
            name = "v{0}".format(version)
        elif version[0] >= 2017 and len(version) > 1:
            name = "{0}_U{1}".format(version[0], version[1])
        else:
            name = "{0}".format(version)
        return url.format(name)

    @property
    def libs(self):
        shared = True if "+shared" in self.spec else False
        return find_libraries("libtbb*", root=self.prefix, shared=shared, recursive=True)


class SetupEnvironment:
    # We set OS here in case the user has it set to something else
    # that TBB doesn't expect.
    def setup_build_environment(self, env):
        env.set("OS", platform.system())


class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder, SetupEnvironment):
    def cmake_args(self):
        spec = self.spec
        options = [
            self.define("CMAKE_HWLOC_2_INCLUDE_PATH", spec["hwloc"].prefix.include),
            self.define("CMAKE_HWLOC_2_LIBRARY_PATH", spec["hwloc"].libs),
            self.define("-DTBB_CPF", True),
            self.define("TBB_STRICT", False),
        ]
        if spec.variants["cxxstd"].value != "default":
            options.append(self.define("CMAKE_CXX_STANDARD", spec.variants["cxxstd"].value))
        return options

    @run_after("install")
    def install_pkgconfig(self):
        # pkg-config generation is introduced in May 5, 2021.
        # It must not be overwritten by spack-generated tbb.pc.
        # https://github.com/oneapi-src/oneTBB/commit/478de5b1887c928e52f029d706af6ea640a877be
        if self.spec.satisfies("@:2021.2.0"):
            mkdirp(self.prefix.lib.pkgconfig)

            with open(join_path(self.prefix.lib.pkgconfig, "tbb.pc"), "w") as f:
                f.write("prefix={0}\n".format(self.prefix))
                f.write("exec_prefix=${prefix}\n")
                f.write("libdir={0}\n".format(self.prefix.lib))
                f.write("includedir={0}\n".format(self.prefix.include))
                f.write("\n")
                f.write("Name: Threading Building Blocks\n")
                f.write("Description: Intel's parallelism library for C++\n")
                f.write("Version: {0}\n".format(self.spec.version))
                f.write("Cflags: -I${includedir}\n")
                f.write("Libs: -L${libdir} -ltbb -latomic\n")


class MakefileBuilder(spack.build_systems.makefile.MakefileBuilder, SetupEnvironment):
    def coerce_to_spack(self, tbb_build_subdir):
        for compiler in ["icc", "gcc", "clang"]:
            fs = glob.glob(join_path(tbb_build_subdir, "*.%s.inc" % compiler))
            for f in fs:
                lines = open(f).readlines()
                of = open(f, "w")
                for lin in lines:
                    if lin.strip().startswith("CPLUS ="):
                        of.write("# coerced to spack\n")
                        of.write("CPLUS = $(CXX)\n")
                    elif lin.strip().startswith("CONLY ="):
                        of.write("# coerced to spack\n")
                        of.write("CONLY = $(CC)\n")
                    else:
                        of.write(lin)

    def build(self, pkg, spec, prefix):
        # Deactivate use of RTM with GCC when on an OS with a very old
        # assembler.
        if (
            spec.satisfies("%gcc@4.8.0: os=rhel6")
            or spec.satisfies("%gcc@4.8.0: os=centos6")
            or spec.satisfies("%gcc@4.8.0: os=scientific6")
        ):
            filter_file(r"RTM_KEY.*=.*rtm.*", "RTM_KEY =", join_path("build", "linux.gcc.inc"))

        # We need to follow TBB's compiler selection logic to get the proper
        # build + link flags but we still need to use spack's compiler wrappers
        # to accomplish this, we do two things:
        #
        # * Look at the spack spec to determine which compiler we should pass
        #   to tbb's Makefile;
        #
        # * patch tbb's build system to use the compiler wrappers (CC, CXX) for
        #   icc, gcc, clang (see coerce_to_spack());
        #
        self.coerce_to_spack("build")

        if spec.satisfies("%clang") or spec.satisfies("%apple-clang") or spec.satisfies("%rocmcc"):
            tbb_compiler = "clang"
        elif spec.satisfies("%intel"):
            tbb_compiler = "icc"
        else:
            tbb_compiler = "gcc"

        make_opts = []

        # Static builds of TBB are enabled by including 'big_iron.inc' file
        # See caveats in 'big_iron.inc' for limits on using TBB statically
        # Lore states this file must be handed to make before other options
        if "+shared" not in self.spec:
            make_opts.append("extra_inc=big_iron.inc")

        if spec.variants["cxxstd"].value != "default":
            make_opts.append("stdver=c++{0}".format(spec.variants["cxxstd"].value))

        #
        # tbb does not have a configure script or make install target
        # we simply call make, and try to put the pieces together
        #
        make_opts.append("compiler={0}".format(tbb_compiler))
        make(*make_opts)

    def install(self, pkg, spec, prefix):
        mkdirp(prefix)
        mkdirp(prefix.lib)

        # install headers to {prefix}/include
        install_tree("include", prefix.include)

        # install libs to {prefix}/lib
        tbb_lib_names = ["libtbb", "libtbbmalloc", "libtbbmalloc_proxy"]

        for lib_name in tbb_lib_names:
            # install release libs
            install(join_path("build", "*release", lib_name + ".*"), prefix.lib)
            # install debug libs if they exist
            install(join_path("build", "*debug", lib_name + "_debug.*"), prefix.lib)

        if spec.satisfies("@2017.8,2018.1:"):
            # Generate and install the CMake Config file.
            cmake_args = (
                "-DTBB_ROOT={0}".format(prefix),
                "-DTBB_OS={0}".format(platform.system()),
                "-P",
                "tbb_config_generator.cmake",
            )
            with working_dir(join_path(self.stage.source_path, "cmake")):
                inspect.getmodule(self).cmake(*cmake_args)

    @run_after("install")
    def darwin_fix(self):
        # Replace @rpath in ids with full path
        if sys.platform == "darwin":
            fix_darwin_install_name(self.prefix.lib)