Add libc dependency to compiled packages and runtime deps

This commit differentiate linux from other platforms by
using libc compatibility as a criterion for deciding
which buildcaches / binaries can be reused. Other
platforms still use OS compatibility.

On linux a libc is injected by all compilers as an implicit
external, and the compatibility criterion is that a libc is
compatible with all other libcs with the same name and a
version that is lesser or equal.

Some concretization unit tests use libc when run on linux.
This commit is contained in:
Massimiliano Culpo 2024-04-03 14:18:47 +02:00 committed by Harmen Stoppels
parent 209a3bf302
commit 34146c197a
18 changed files with 190 additions and 88 deletions

View file

@ -283,6 +283,27 @@ def all_compilers_in_config(configuration):
return spack.compilers.all_compilers_from(configuration) return spack.compilers.all_compilers_from(configuration)
def compatible_libc(candidate_libc_spec):
"""Returns a list of libc specs that are compatible with the one passed as argument"""
result = set()
for compiler in all_compilers_in_config(spack.config.CONFIG):
libc = compiler.default_libc()
if not libc:
continue
if (
libc.name == candidate_libc_spec.name
and libc.version >= candidate_libc_spec.version
and libc.external_path == candidate_libc_spec.external_path
):
result.add(libc)
return sorted(result)
def using_libc_compatibility() -> bool:
"""Returns True if we are currently using libc compatibility"""
return spack.platforms.host().name == "linux"
def extend_flag_list(flag_list, new_flags): def extend_flag_list(flag_list, new_flags):
"""Extend a list of flags, preserving order and precedence. """Extend a list of flags, preserving order and precedence.
@ -566,16 +587,16 @@ def _spec_with_default_name(spec_str, name):
return spec return spec
def _external_config_with_implictit_externals(): def _external_config_with_implicit_externals(configuration):
# Read packages.yaml and normalize it, so that it will not contain entries referring to # Read packages.yaml and normalize it, so that it will not contain entries referring to
# virtual packages. # virtual packages.
packages_yaml = _normalize_packages_yaml(spack.config.get("packages")) packages_yaml = _normalize_packages_yaml(configuration.get("packages"))
# Add externals for libc from compilers on Linux # Add externals for libc from compilers on Linux
if spack.platforms.host().name != "linux": if not using_libc_compatibility():
return packages_yaml return packages_yaml
for compiler in all_compilers_in_config(): for compiler in all_compilers_in_config(configuration):
libc = compiler.default_libc() libc = compiler.default_libc()
if libc: if libc:
entry = {"spec": f"{libc} %{compiler.spec}", "prefix": libc.external_path} entry = {"spec": f"{libc} %{compiler.spec}", "prefix": libc.external_path}
@ -801,10 +822,16 @@ def solve(self, setup, specs, reuse=None, output=None, control=None, allow_depre
self.control.load(os.path.join(parent_dir, "heuristic.lp")) self.control.load(os.path.join(parent_dir, "heuristic.lp"))
if spack.config.CONFIG.get("concretizer:duplicates:strategy", "none") != "none": if spack.config.CONFIG.get("concretizer:duplicates:strategy", "none") != "none":
self.control.load(os.path.join(parent_dir, "heuristic_separate.lp")) self.control.load(os.path.join(parent_dir, "heuristic_separate.lp"))
self.control.load(os.path.join(parent_dir, "os_compatibility.lp"))
self.control.load(os.path.join(parent_dir, "display.lp")) self.control.load(os.path.join(parent_dir, "display.lp"))
if not setup.concretize_everything: if not setup.concretize_everything:
self.control.load(os.path.join(parent_dir, "when_possible.lp")) self.control.load(os.path.join(parent_dir, "when_possible.lp"))
# Binary compatibility is based on libc on Linux, and on the os tag elsewhere
if using_libc_compatibility():
self.control.load(os.path.join(parent_dir, "libc_compatibility.lp"))
else:
self.control.load(os.path.join(parent_dir, "os_compatibility.lp"))
timer.stop("load") timer.stop("load")
# Grounding is the first step in the solve -- it turns our facts # Grounding is the first step in the solve -- it turns our facts
@ -1572,7 +1599,7 @@ def emit_facts_from_requirement_rules(self, rules: List[RequirementRule]):
def external_packages(self): def external_packages(self):
"""Facts on external packages, from packages.yaml and implicit externals.""" """Facts on external packages, from packages.yaml and implicit externals."""
packages_yaml = _external_config_with_implictit_externals() packages_yaml = _external_config_with_implicit_externals(spack.config.CONFIG)
self.gen.h1("External packages") self.gen.h1("External packages")
for pkg_name, data in packages_yaml.items(): for pkg_name, data in packages_yaml.items():
@ -1845,6 +1872,15 @@ def _spec_clauses(
if dep.name == "gcc-runtime": if dep.name == "gcc-runtime":
continue continue
# LIBC is also solved again by clingo, but in this case the compatibility
# is not encoded in the parent node - so we need to emit explicit facts
if "libc" in dspec.virtuals:
for x in compatible_libc(dep):
clauses.append(
fn.attr("compatible_libc", spec.name, x.name, x.version)
)
continue
# We know dependencies are real for concrete specs. For abstract # We know dependencies are real for concrete specs. For abstract
# specs they just mean the dep is somehow in the DAG. # specs they just mean the dep is somehow in the DAG.
for dtype in dt.ALL_FLAGS: for dtype in dt.ALL_FLAGS:
@ -2316,6 +2352,10 @@ def setup(
self.gen = ProblemInstanceBuilder() self.gen = ProblemInstanceBuilder()
compiler_parser = CompilerParser(configuration=spack.config.CONFIG).with_input_specs(specs) compiler_parser = CompilerParser(configuration=spack.config.CONFIG).with_input_specs(specs)
# Only relevant for linux
for libc in compiler_parser.allowed_libcs:
self.gen.fact(fn.allowed_libc(libc.name, libc.version))
if not allow_deprecated: if not allow_deprecated:
self.gen.fact(fn.deprecated_versions_not_allowed()) self.gen.fact(fn.deprecated_versions_not_allowed())
@ -2445,18 +2485,35 @@ def visit(node):
def define_runtime_constraints(self): def define_runtime_constraints(self):
"""Define the constraints to be imposed on the runtimes""" """Define the constraints to be imposed on the runtimes"""
recorder = RuntimePropertyRecorder(self) recorder = RuntimePropertyRecorder(self)
# TODO: Use only available compilers ?
for compiler in self.possible_compilers: for compiler in self.possible_compilers:
compiler_with_different_cls_names = {"oneapi": "intel-oneapi-compilers"} compiler_with_different_cls_names = {
"oneapi": "intel-oneapi-compilers",
"clang": "llvm",
}
compiler_cls_name = compiler_with_different_cls_names.get( compiler_cls_name = compiler_with_different_cls_names.get(
compiler.spec.name, compiler.spec.name compiler.spec.name, compiler.spec.name
) )
try: try:
compiler_cls = spack.repo.PATH.get_pkg_class(compiler_cls_name) compiler_cls = spack.repo.PATH.get_pkg_class(compiler_cls_name)
if hasattr(compiler_cls, "runtime_constraints"):
compiler_cls.runtime_constraints(spec=compiler.spec, pkg=recorder)
except spack.repo.UnknownPackageError: except spack.repo.UnknownPackageError:
pass
# Inject libc from available compilers, on Linux
if not compiler.available:
continue continue
if hasattr(compiler_cls, "runtime_constraints"):
compiler_cls.runtime_constraints(spec=compiler.spec, pkg=recorder) if using_libc_compatibility():
libc = compiler.compiler_obj.default_libc()
if libc:
recorder("*").depends_on(
"libc", when=f"%{compiler.spec}", type="link", description="Add libc"
)
recorder("*").depends_on(
str(libc), when=f"%{compiler.spec}", type="link", description="Add libc"
)
recorder.consume_facts() recorder.consume_facts()
@ -2833,7 +2890,19 @@ class CompilerParser:
def __init__(self, configuration) -> None: def __init__(self, configuration) -> None:
self.compilers: Set[KnownCompiler] = set() self.compilers: Set[KnownCompiler] = set()
self.allowed_libcs = set()
for c in all_compilers_in_config(configuration): for c in all_compilers_in_config(configuration):
if using_libc_compatibility():
libc = c.default_libc()
if not libc:
warnings.warn(
f"cannot detect libc from {c.spec}. The compiler will not be used "
f"during concretization."
)
continue
self.allowed_libcs.add(libc)
target = c.target if c.target != "any" else None target = c.target if c.target != "any" else None
candidate = KnownCompiler( candidate = KnownCompiler(
spec=c.spec, os=c.operating_system, target=target, available=True, compiler_obj=c spec=c.spec, os=c.operating_system, target=target, available=True, compiler_obj=c
@ -3199,7 +3268,7 @@ def no_flags(self, node, flag_type):
def external_spec_selected(self, node, idx): def external_spec_selected(self, node, idx):
"""This means that the external spec and index idx has been selected for this package.""" """This means that the external spec and index idx has been selected for this package."""
packages_yaml = _external_config_with_implictit_externals() packages_yaml = _external_config_with_implicit_externals(spack.config.CONFIG)
spec_info = packages_yaml[node.pkg]["externals"][int(idx)] spec_info = packages_yaml[node.pkg]["externals"][int(idx)]
self._specs[node].external_path = spec_info.get("prefix", None) self._specs[node].external_path = spec_info.get("prefix", None)
self._specs[node].external_modules = spack.spec.Spec._format_module_list( self._specs[node].external_modules = spack.spec.Spec._format_module_list(
@ -3514,7 +3583,7 @@ def _check_input_and_extract_concrete_specs(specs):
def _reusable_specs(self, specs): def _reusable_specs(self, specs):
reusable_specs = [] reusable_specs = []
if self.reuse: if self.reuse:
packages = spack.config.get("packages") packages = _external_config_with_implicit_externals(spack.config.CONFIG)
# Specs from the local Database # Specs from the local Database
with spack.store.STORE.db.read_transaction(): with spack.store.STORE.db.read_transaction():
reusable_specs.extend( reusable_specs.extend(

View file

@ -1023,14 +1023,6 @@ error(100, "Cannot select '{0} os={1}' (operating system '{1}' is not buildable)
attr("node_os", node(X, Package), OS), attr("node_os", node(X, Package), OS),
not buildable_os(OS). not buildable_os(OS).
% can't have dependencies on incompatible OS's
error(100, "{0} and dependency {1} have incompatible operating systems 'os={2}' and 'os={3}'", Package, Dependency, PackageNodeOS, DependencyOS)
:- depends_on(node(X, Package), node(Y, Dependency)),
attr("node_os", node(X, Package), PackageNodeOS),
attr("node_os", node(Y, Dependency), DependencyOS),
not os_compatible(PackageNodeOS, DependencyOS),
build(node(X, Package)).
% give OS choice weights according to os declarations % give OS choice weights according to os declarations
node_os_weight(PackageNode, Weight) node_os_weight(PackageNode, Weight)
:- attr("node", PackageNode), :- attr("node", PackageNode),
@ -1043,13 +1035,6 @@ os_compatible(OS, OS) :- os(OS).
% Transitive compatibility among operating systems % Transitive compatibility among operating systems
os_compatible(OS1, OS3) :- os_compatible(OS1, OS2), os_compatible(OS2, OS3). os_compatible(OS1, OS3) :- os_compatible(OS1, OS2), os_compatible(OS2, OS3).
% We can select only operating systems compatible with the ones
% for which we can build software. We need a cardinality constraint
% since we might have more than one "buildable_os(OS)" fact.
:- not 1 { os_compatible(CurrentOS, ReusedOS) : buildable_os(CurrentOS) },
attr("node_os", Package, ReusedOS),
internal_error("Reused OS incompatible with build OS").
% If an OS is set explicitly respect the value % If an OS is set explicitly respect the value
attr("node_os", PackageNode, OS) :- attr("node_os_set", PackageNode, OS), attr("node", PackageNode). attr("node_os", PackageNode, OS) :- attr("node_os_set", PackageNode, OS), attr("node", PackageNode).

View file

@ -0,0 +1,37 @@
% Copyright 2013-2024 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)
%=============================================================================
% Libc compatibility rules for reusing solves.
%
% These rules are used on Linux
%=============================================================================
% A package cannot be reused if the libc is not compatible with it
:- provider(node(X, LibcPackage), node(0, "libc")),
attr("version", node(X, LibcPackage), LibcVersion),
attr("hash", node(R, ReusedPackage), Hash),
% Libc packages can be reused without the "compatible_libc" attribute
ReusedPackage != LibcPackage,
not attr("compatible_libc", node(R, ReusedPackage), LibcPackage, LibcVersion).
% Check whether the DAG has any built package
has_built_packages() :- build(X), not external(X).
% A libc is needed in the DAG
:- has_built_packages(), not provider(_, node(0, "libc")).
% The libc must be chosen among available ones
:- has_built_packages(),
provider(node(X, LibcPackage), node(0, "libc")),
attr("node", node(X, LibcPackage)),
attr("version", node(X, LibcPackage), LibcVersion),
not allowed_libc(LibcPackage, LibcVersion).
% A built node must depend on libc
:- build(PackageNode),
provider(LibcNode, node(0, "libc")),
not external(PackageNode),
not depends_on(PackageNode, LibcNode).

View file

@ -7,8 +7,24 @@
% OS compatibility rules for reusing solves. % OS compatibility rules for reusing solves.
% os_compatible(RecentOS, OlderOS) % os_compatible(RecentOS, OlderOS)
% OlderOS binaries can be used on RecentOS % OlderOS binaries can be used on RecentOS
%
% These rules are used on every platform, but Linux
%============================================================================= %=============================================================================
% macOS % macOS
os_compatible("monterey", "bigsur"). os_compatible("monterey", "bigsur").
os_compatible("bigsur", "catalina"). os_compatible("bigsur", "catalina").
% can't have dependencies on incompatible OS's
error(100, "{0} and dependency {1} have incompatible operating systems 'os={2}' and 'os={3}'", Package, Dependency, PackageNodeOS, DependencyOS)
:- depends_on(node(X, Package), node(Y, Dependency)),
attr("node_os", node(X, Package), PackageNodeOS),
attr("node_os", node(Y, Dependency), DependencyOS),
not os_compatible(PackageNodeOS, DependencyOS),
build(node(X, Package)).
% We can select only operating systems compatible with the ones
% for which we can build software. We need a cardinality constraint
% since we might have more than one "buildable_os(OS)" fact.
:- not 1 { os_compatible(CurrentOS, ReusedOS) : buildable_os(CurrentOS) },
attr("node_os", Package, ReusedOS).

View file

@ -13,6 +13,7 @@
import llnl.util.lang import llnl.util.lang
import spack.compiler
import spack.compilers import spack.compilers
import spack.concretize import spack.concretize
import spack.config import spack.config
@ -67,6 +68,24 @@ def check_concretize(abstract_spec):
return concrete return concrete
@pytest.fixture(scope="function", autouse=True)
def binary_compatibility(monkeypatch, request):
"""Selects whether we use OS compatibility for binaries, or libc compatibility."""
if spack.platforms.real_host().name != "linux":
return
if "mock_packages" not in request.fixturenames:
# Only builtin.mock has a mock glibc package
return
if "database" in request.fixturenames or "mutable_database" in request.fixturenames:
# Databases have been created without glibc support
return
monkeypatch.setattr(spack.solver.asp, "using_libc_compatibility", lambda: True)
monkeypatch.setattr(spack.compiler.Compiler, "default_libc", lambda x: Spec("glibc@=2.28"))
@pytest.fixture( @pytest.fixture(
params=[ params=[
# no_deps # no_deps
@ -1452,6 +1471,8 @@ def test_os_selection_when_multiple_choices_are_possible(
): ):
s = Spec(spec_str).concretized() s = Spec(spec_str).concretized()
for node in s.traverse(): for node in s.traverse():
if node.name == "glibc":
continue
assert node.satisfies(expected_os) assert node.satisfies(expected_os)
@pytest.mark.regression("22718") @pytest.mark.regression("22718")
@ -1764,7 +1785,8 @@ def test_best_effort_coconcretize(self, specs, expected):
for s in result.specs: for s in result.specs:
concrete_specs.update(s.traverse()) concrete_specs.update(s.traverse())
assert len(concrete_specs) == expected libc_offset = 1 if spack.solver.asp.using_libc_compatibility() else 0
assert len(concrete_specs) == expected + libc_offset
@pytest.mark.parametrize( @pytest.mark.parametrize(
"specs,expected_spec,occurances", "specs,expected_spec,occurances",
@ -1884,29 +1906,16 @@ def test_version_weight_and_provenance(self):
result_spec = result.specs[0] result_spec = result.specs[0]
num_specs = len(list(result_spec.traverse())) num_specs = len(list(result_spec.traverse()))
libc_offset = 1 if spack.solver.asp.using_libc_compatibility() else 0
criteria = [ criteria = [
(num_specs - 1, None, "number of packages to build (vs. reuse)"), (num_specs - 1 - libc_offset, None, "number of packages to build (vs. reuse)"),
(2, 0, "version badness"), (2, 0, "version badness"),
] ]
for criterion in criteria: for criterion in criteria:
assert criterion in result.criteria assert criterion in result.criteria, result_spec
assert result_spec.satisfies("^b@1.0") assert result_spec.satisfies("^b@1.0")
@pytest.mark.regression("31169")
@pytest.mark.only_clingo("Use case not supported by the original concretizer")
def test_not_reusing_incompatible_os(self):
root_spec = Spec("b")
s = root_spec.concretized()
wrong_os = s.copy()
wrong_os.architecture = spack.spec.ArchSpec("test-ubuntu2204-x86_64")
with spack.config.override("concretizer:reuse", True):
solver = spack.solver.asp.Solver()
setup = spack.solver.asp.SpackSolverSetup()
result, _, _ = solver.driver.solve(setup, [root_spec], reuse=[wrong_os])
concrete_spec = result.specs[0]
assert concrete_spec.satisfies("os={}".format(s.architecture.os))
@pytest.mark.only_clingo("Use case not supported by the original concretizer") @pytest.mark.only_clingo("Use case not supported by the original concretizer")
def test_reuse_succeeds_with_config_compatible_os(self): def test_reuse_succeeds_with_config_compatible_os(self):
root_spec = Spec("b") root_spec = Spec("b")

View file

@ -0,0 +1,21 @@
# Copyright 2013-2024 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 Glibc(AutotoolsPackage, GNUMirrorPackage):
"""The GNU C Library provides many of the low-level components used
directly by programs written in the C or C++ languages.
"""
homepage = "https://www.gnu.org/software/libc/"
gnu_mirror_path = "libc/glibc-2.33.tar.gz"
git = "https://sourceware.org/git/glibc.git"
tags = ["runtime"]
provides("libc")
version("2.39", sha256="97f84f3b7588cd54093a6f6389b0c1a81e70d99708d74963a2e3eab7c7dc942d")

View file

@ -28,7 +28,6 @@ class Aocc(Package):
""" """
_name = "aocc" _name = "aocc"
family = "compiler"
homepage = "https://www.amd.com/en/developer/aocc.html" homepage = "https://www.amd.com/en/developer/aocc.html"
maintainers("amd-toolchain-support") maintainers("amd-toolchain-support")

View file

@ -53,6 +53,8 @@ class GccRuntime(Package):
provides("libgfortran@4", when="%gcc@7") provides("libgfortran@4", when="%gcc@7")
provides("libgfortran@5", when="%gcc@8:") provides("libgfortran@5", when="%gcc@8:")
depends_on("libc", type="link")
def install(self, spec, prefix): def install(self, spec, prefix):
if spec.platform in ["linux", "cray", "freebsd"]: if spec.platform in ["linux", "cray", "freebsd"]:
libraries = get_elf_libraries(compiler=self.compiler, libraries=self.LIBRARIES) libraries = get_elf_libraries(compiler=self.compiler, libraries=self.LIBRARIES)

View file

@ -1185,13 +1185,5 @@ def runtime_constraints(cls, *, spec, pkg):
description=f"Add a dependency on '{gfortran_str}' for nodes compiled with " description=f"Add a dependency on '{gfortran_str}' for nodes compiled with "
f"{str(spec)} and using the 'fortran' language", f"{str(spec)} and using the 'fortran' language",
) )
libc = compiler.default_libc()
if libc:
pkg("*").depends_on(
str(libc), when=f"%{str(compiler.spec)}", type="link", description="Add libc"
)
# The version of gcc-runtime is the same as the %gcc used to "compile" it # The version of gcc-runtime is the same as the %gcc used to "compile" it
pkg("gcc-runtime").requires(f"@={str(spec.version)}", when=f"%{str(spec)}") pkg("gcc-runtime").requires(f"@={str(spec.version)}", when=f"%{str(spec)}")

View file

@ -198,3 +198,7 @@ def build(self, spec, prefix):
make("-C", "..", f"objdir={os.getcwd()}", "lib") make("-C", "..", f"objdir={os.getcwd()}", "lib")
delete_rpath(join_path("elf", "ld.so")) delete_rpath(join_path("elf", "ld.so"))
make() make()
@property
def libs(self):
return LibraryList([])

View file

@ -14,8 +14,6 @@ class IntelLlvm(CMakePackage):
homepage = "https://github.com/intel/llvm" homepage = "https://github.com/intel/llvm"
git = "https://github.com/intel/llvm.git" git = "https://github.com/intel/llvm.git"
family = "compiler"
license("Apache-2.0") license("Apache-2.0")
version("sycl", branch="sycl") version("sycl", branch="sycl")

View file

@ -422,5 +422,5 @@ def runtime_constraints(cls, *, spec, pkg):
description=f"Add a dependency on 'libifcore' for nodes compiled with " description=f"Add a dependency on 'libifcore' for nodes compiled with "
f"{str(spec)} and using the 'fortran' language", f"{str(spec)} and using the 'fortran' language",
) )
# The version of gcc-runtime is the same as the %gcc used to "compile" it # The version of intel-oneapi-runtime is the same as the %oneapi used to "compile" it
pkg("intel-oneapi-runtime").requires(f"@={str(spec.version)}", when=f"%{str(spec)}") pkg("intel-oneapi-runtime").requires(f"@={str(spec.version)}", when=f"%{str(spec)}")

View file

@ -44,6 +44,8 @@ class IntelOneapiRuntime(Package):
conflicts("platform=windows", msg="IntelOneAPI can only be installed on Linux, and FreeBSD") conflicts("platform=windows", msg="IntelOneAPI can only be installed on Linux, and FreeBSD")
conflicts("platform=darwin", msg="IntelOneAPI can only be installed on Linux, and FreeBSD") conflicts("platform=darwin", msg="IntelOneAPI can only be installed on Linux, and FreeBSD")
depends_on("libc", type="link")
def install(self, spec, prefix): def install(self, spec, prefix):
libraries = get_elf_libraries(compiler=self.compiler, libraries=self.LIBRARIES) libraries = get_elf_libraries(compiler=self.compiler, libraries=self.LIBRARIES)
mkdir(prefix.lib) mkdir(prefix.lib)

View file

@ -1,24 +0,0 @@
# Copyright 2013-2024 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 Libc(BundlePackage):
"""Dummy package to provide interfaces available in libc."""
homepage = "https://en.wikipedia.org/wiki/C_standard_library"
version("1.0") # Dummy
variant("iconv", default=False, description="Provides interfaces for Localization Functions")
variant("rpc", default=False, description="Provides interfaces for RPC")
provides("iconv", when="+iconv")
provides("rpc", when="+rpc")
@property
def libs(self):
return LibraryList([])

View file

@ -28,8 +28,6 @@ class LlvmDoe(CMakePackage, CudaPackage):
generator("ninja") generator("ninja")
family = "compiler" # Used by lmod
version("doe", branch="doe", preferred=True) version("doe", branch="doe", preferred=True)
version("upstream", branch="llvm.org/main") version("upstream", branch="llvm.org/main")
version("bolt", branch="bolt/main") version("bolt", branch="bolt/main")

View file

@ -32,8 +32,6 @@ class Llvm(CMakePackage, CudaPackage):
generator("ninja") generator("ninja")
family = "compiler" # Used by lmod
license("Apache-2.0") license("Apache-2.0")
version("main", branch="main") version("main", branch="main")

View file

@ -16,8 +16,6 @@ class Sollve(CMakePackage):
homepage = "https://www.bnl.gov/compsci/projects/SOLLVE/" homepage = "https://www.bnl.gov/compsci/projects/SOLLVE/"
git = "https://github.com/SOLLVE/llvm.git" git = "https://github.com/SOLLVE/llvm.git"
family = "compiler" # Used by lmod
# NOTE: The debug version of LLVM is an order of magnitude larger than # NOTE: The debug version of LLVM is an order of magnitude larger than
# the release version, and may take up 20-30 GB of space. If you want # the release version, and may take up 20-30 GB of space. If you want
# to save space, build with `build_type=Release`. # to save space, build with `build_type=Release`.

View file

@ -18,8 +18,6 @@ class Templight(CMakePackage):
git = "https://github.com/mikael-s-persson/templight.git" git = "https://github.com/mikael-s-persson/templight.git"
llvm_svn = "http://llvm.org/svn/llvm-project/{0}/trunk" llvm_svn = "http://llvm.org/svn/llvm-project/{0}/trunk"
family = "compiler" # Used by lmod
# Templight is a patch to clang, so we have three versions to care about: # Templight is a patch to clang, so we have three versions to care about:
# - The one that will be used in Spack specifications # - The one that will be used in Spack specifications
# - The git branch that we need to fetch from in the templight repo # - The git branch that we need to fetch from in the templight repo