summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/compilers/__init__.py16
-rw-r--r--lib/spack/spack/installer.py18
-rw-r--r--lib/spack/spack/modules/lmod.py20
-rw-r--r--lib/spack/spack/test/installer.py11
-rw-r--r--lib/spack/spack/test/modules/lmod.py9
-rw-r--r--var/spack/repos/builtin.mock/packages/intel-oneapi-compilers/package.py28
-rw-r--r--var/spack/repos/builtin/packages/intel-oneapi-compilers-classic/package.py41
-rw-r--r--var/spack/repos/builtin/packages/intel-oneapi-compilers/package.py6
8 files changed, 119 insertions, 30 deletions
diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py
index 05ffaf9f6c..e54f8dc96c 100644
--- a/lib/spack/spack/compilers/__init__.py
+++ b/lib/spack/spack/compilers/__init__.py
@@ -49,12 +49,26 @@ _compiler_to_pkg = {
"clang": "llvm+clang",
"oneapi": "intel-oneapi-compilers",
"rocmcc": "llvm-amdgpu",
+ "intel@2020:": "intel-oneapi-compilers-classic",
+}
+
+# TODO: generating this from the previous dict causes docs errors
+package_name_to_compiler_name = {
+ "llvm": "clang",
+ "intel-oneapi-compilers": "oneapi",
+ "llvm-amdgpu": "rocmcc",
+ "intel-oneapi-compilers-classic": "intel",
}
def pkg_spec_for_compiler(cspec):
"""Return the spec of the package that provides the compiler."""
- spec_str = "%s@%s" % (_compiler_to_pkg.get(cspec.name, cspec.name), cspec.versions)
+ for spec, package in _compiler_to_pkg.items():
+ if cspec.satisfies(spec):
+ spec_str = "%s@%s" % (package, cspec.versions)
+ break
+ else:
+ spec_str = str(cspec)
return spack.spec.Spec(spec_str)
diff --git a/lib/spack/spack/installer.py b/lib/spack/spack/installer.py
index 62770d0349..a0f505a922 100644
--- a/lib/spack/spack/installer.py
+++ b/lib/spack/spack/installer.py
@@ -1241,6 +1241,12 @@ class PackageInstaller(object):
fail_fast = request.install_args.get("fail_fast")
self.fail_fast = self.fail_fast or fail_fast
+ def _add_compiler_package_to_config(self, pkg):
+ compiler_search_prefix = getattr(pkg, "compiler_search_prefix", pkg.spec.prefix)
+ spack.compilers.add_compilers_to_config(
+ spack.compilers.find_compilers([compiler_search_prefix])
+ )
+
def _install_task(self, task):
"""
Perform the installation of the requested spec and/or dependency
@@ -1266,9 +1272,7 @@ class PackageInstaller(object):
if use_cache and _install_from_cache(pkg, cache_only, explicit, unsigned):
self._update_installed(task)
if task.compiler:
- spack.compilers.add_compilers_to_config(
- spack.compilers.find_compilers([pkg.spec.prefix])
- )
+ self._add_compiler_package_to_config(pkg)
return
pkg.run_tests = tests is True or tests and pkg.name in tests
@@ -1296,9 +1300,7 @@ class PackageInstaller(object):
# If a compiler, ensure it is added to the configuration
if task.compiler:
- spack.compilers.add_compilers_to_config(
- spack.compilers.find_compilers([pkg.spec.prefix])
- )
+ self._add_compiler_package_to_config(pkg)
except spack.build_environment.StopPhase as e:
# A StopPhase exception means that do_install was asked to
# stop early from clients, and is not an error at this point
@@ -1717,9 +1719,7 @@ class PackageInstaller(object):
# It's an already installed compiler, add it to the config
if task.compiler:
- spack.compilers.add_compilers_to_config(
- spack.compilers.find_compilers([pkg.spec.prefix])
- )
+ self._add_compiler_package_to_config(pkg)
else:
# At this point we've failed to get a write or a read
diff --git a/lib/spack/spack/modules/lmod.py b/lib/spack/spack/modules/lmod.py
index bb288336ea..3378e53354 100644
--- a/lib/spack/spack/modules/lmod.py
+++ b/lib/spack/spack/modules/lmod.py
@@ -184,22 +184,10 @@ class LmodConfiguration(BaseConfiguration):
# If it is in the list of supported compilers family -> compiler
if self.spec.name in spack.compilers.supported_compilers():
provides["compiler"] = spack.spec.CompilerSpec(str(self.spec))
- # Special case for llvm
- if self.spec.name == "llvm":
- provides["compiler"] = spack.spec.CompilerSpec(str(self.spec))
- provides["compiler"].name = "clang"
- # Special case for llvm-amdgpu
- if self.spec.name == "llvm-amdgpu":
- provides["compiler"] = spack.spec.CompilerSpec(str(self.spec))
- provides["compiler"].name = "rocmcc"
- # Special case for oneapi
- if self.spec.name == "intel-oneapi-compilers":
- provides["compiler"] = spack.spec.CompilerSpec(str(self.spec))
- provides["compiler"].name = "oneapi"
- # Special case for oneapi classic
- if self.spec.name == "intel-oneapi-compilers-classic":
- provides["compiler"] = spack.spec.CompilerSpec(str(self.spec))
- provides["compiler"].name = "intel"
+ elif self.spec.name in spack.compilers.package_name_to_compiler_name:
+ # If it is the package for a supported compiler, but of a different name
+ cname = spack.compilers.package_name_to_compiler_name[self.spec.name]
+ provides["compiler"] = spack.spec.CompilerSpec("%s@%s" % (cname, self.spec.version))
# All the other tokens in the hierarchy must be virtual dependencies
for x in self.hierarchy_tokens:
diff --git a/lib/spack/spack/test/installer.py b/lib/spack/spack/test/installer.py
index 8a713ca704..4c85f4ba26 100644
--- a/lib/spack/spack/test/installer.py
+++ b/lib/spack/spack/test/installer.py
@@ -487,6 +487,17 @@ def test_update_tasks_for_compiler_packages_as_compiler(mock_packages, config, m
assert installer.build_pq[0][1].compiler
+def test_bootstrapping_compilers_with_different_names_from_spec(
+ install_mockery, mutable_config, mock_fetch
+):
+ with spack.config.override("config:install_missing_compilers", True):
+ with spack.concretize.disable_compiler_existence_check():
+ spec = spack.spec.Spec("trivial-install-test-package%oneapi@22.2.0").concretized()
+ spec.package.do_install()
+
+ assert spack.spec.CompilerSpec("oneapi@22.2.0") in spack.compilers.all_compiler_specs()
+
+
def test_dump_packages_deps_ok(install_mockery, tmpdir, mock_packages):
"""Test happy path for dump_packages with dependencies."""
diff --git a/lib/spack/spack/test/modules/lmod.py b/lib/spack/spack/test/modules/lmod.py
index 5d0d04032e..c0d228c2fe 100644
--- a/lib/spack/spack/test/modules/lmod.py
+++ b/lib/spack/spack/test/modules/lmod.py
@@ -81,6 +81,15 @@ class TestLmod(object):
else:
assert repetitions == 1
+ def test_compilers_provided_different_name(self, factory, module_configuration):
+ module_configuration("complex_hierarchy")
+ module, spec = factory("intel-oneapi-compilers%clang@3.3")
+
+ provides = module.conf.provides
+
+ assert "compiler" in provides
+ assert provides["compiler"] == spack.spec.CompilerSpec("oneapi@3.0")
+
def test_simple_case(self, modulefile_content, module_configuration):
"""Tests the generation of a simple TCL module file."""
diff --git a/var/spack/repos/builtin.mock/packages/intel-oneapi-compilers/package.py b/var/spack/repos/builtin.mock/packages/intel-oneapi-compilers/package.py
new file mode 100644
index 0000000000..3ab49f1e1c
--- /dev/null
+++ b/var/spack/repos/builtin.mock/packages/intel-oneapi-compilers/package.py
@@ -0,0 +1,28 @@
+# Copyright 2013-2022 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.package import *
+
+
+class IntelOneapiCompilers(Package):
+ """Simple compiler package."""
+
+ homepage = "http://www.example.com"
+ url = "http://www.example.com/oneapi-1.0.tar.gz"
+
+ version("1.0", "0123456789abcdef0123456789abcdef")
+ version("2.0", "abcdef0123456789abcdef0123456789")
+ version("3.0", "def0123456789abcdef0123456789abc")
+
+ @property
+ def compiler_search_prefix(self):
+ return self.prefix.foo.bar.baz.bin
+
+ def install(self, spec, prefix):
+ # Create the minimal compiler that will fool `spack compiler find`
+ mkdirp(self.compiler_search_prefix)
+ with open(self.compiler_search_prefix.icx, "w") as f:
+ f.write('#!/bin/bash\necho "oneAPI DPC++ Compiler %s"' % str(spec.version))
+ set_executable(self.compiler_search_prefix.icx)
diff --git a/var/spack/repos/builtin/packages/intel-oneapi-compilers-classic/package.py b/var/spack/repos/builtin/packages/intel-oneapi-compilers-classic/package.py
index 61b634fb9b..1b81e0ff63 100644
--- a/var/spack/repos/builtin/packages/intel-oneapi-compilers-classic/package.py
+++ b/var/spack/repos/builtin/packages/intel-oneapi-compilers-classic/package.py
@@ -2,6 +2,9 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import os
+
+from llnl.util.link_tree import LinkTree
from spack.package import *
@@ -19,8 +22,6 @@ class IntelOneapiCompilersClassic(Package):
has_code = False
- phases = []
-
# Versions before 2021 are in the `intel` package
# intel-oneapi versions before 2022 use intel@19.0.4
for ver, oneapi_ver in {
@@ -35,8 +36,19 @@ class IntelOneapiCompilersClassic(Package):
version(ver)
depends_on("intel-oneapi-compilers@" + oneapi_ver, when="@" + ver, type="run")
+ @property
+ def oneapi_compiler_prefix(self):
+ oneapi_version = self.spec["intel-oneapi-compilers"].version
+ return self.spec["intel-oneapi-compilers"].prefix.compiler.join(str(oneapi_version))
+
def setup_run_environment(self, env):
- """Adds environment variables to the generated module file."""
+ """Adds environment variables to the generated module file.
+
+ These environment variables come from running:
+ .. code-block:: console
+ $ source {prefix}/{component}/{version}/env/vars.sh
+ and from setting CC/CXX/F77/FC
+ """
oneapi_pkg = self.spec["intel-oneapi-compilers"].package
oneapi_pkg.setup_run_environment(env)
@@ -46,3 +58,26 @@ class IntelOneapiCompilersClassic(Package):
env.set("CXX", bin_prefix.icpc)
env.set("F77", bin_prefix.ifort)
env.set("FC", bin_prefix.ifort)
+
+ def install(self, spec, prefix):
+ # If we symlink top-level directories directly, files won't show up in views
+ # Create real dirs and symlink files instead
+ self.symlink_dir(self.oneapi_compiler_prefix.linux.bin.intel64, prefix.bin)
+ self.symlink_dir(self.oneapi_compiler_prefix.linux.lib, prefix.lib)
+ self.symlink_dir(self.oneapi_compiler_prefix.linux.include, prefix.include)
+ self.symlink_dir(self.oneapi_compiler_prefix.linux.compiler, prefix.compiler)
+ self.symlink_dir(self.oneapi_compiler_prefix.documentation.en.man, prefix.man)
+
+ def symlink_dir(self, src, dest):
+ # Create a real directory at dest
+ mkdirp(dest)
+
+ # Symlink all files in src to dest keeping directories as dirs
+ for entry in os.listdir(src):
+ src_path = os.path.join(src, entry)
+ dest_path = os.path.join(dest, entry)
+ if os.path.isdir(src_path) and os.access(src_path, os.X_OK):
+ link_tree = LinkTree(src_path)
+ link_tree.merge(dest_path)
+ else:
+ os.symlink(src_path, dest_path)
diff --git a/var/spack/repos/builtin/packages/intel-oneapi-compilers/package.py b/var/spack/repos/builtin/packages/intel-oneapi-compilers/package.py
index c596074289..4869fc63d8 100644
--- a/var/spack/repos/builtin/packages/intel-oneapi-compilers/package.py
+++ b/var/spack/repos/builtin/packages/intel-oneapi-compilers/package.py
@@ -149,6 +149,10 @@ class IntelOneapiCompilers(IntelOneApiPackage):
def component_dir(self):
return "compiler"
+ @property
+ def compiler_search_prefix(self):
+ return self.prefix.compiler.join(str(self.version)).linux.bin
+
def setup_run_environment(self, env):
"""Adds environment variables to the generated module file.
@@ -169,7 +173,7 @@ class IntelOneapiCompilers(IntelOneApiPackage):
def install(self, spec, prefix):
# Copy instead of install to speed up debugging
- # install_tree('/opt/intel/oneapi/compiler', self.prefix)
+ # install_tree("/opt/intel/oneapi/compiler", self.prefix)
# install cpp
super(IntelOneapiCompilers, self).install(spec, prefix)