Turn the compiler wrapper into a package
Remove the compiler wrappers from core Spack, and move the relevant code into the "compiler-wrapper" package.
This commit is contained in:
parent
e5f8049f3d
commit
95115d4290
1
lib/spack/env/aocc/clang
vendored
1
lib/spack/env/aocc/clang
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/aocc/clang++
vendored
1
lib/spack/env/aocc/clang++
vendored
@ -1 +0,0 @@
|
||||
../cpp
|
1
lib/spack/env/aocc/flang
vendored
1
lib/spack/env/aocc/flang
vendored
@ -1 +0,0 @@
|
||||
../fc
|
1
lib/spack/env/arm/armclang
vendored
1
lib/spack/env/arm/armclang
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/arm/armclang++
vendored
1
lib/spack/env/arm/armclang++
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/arm/armflang
vendored
1
lib/spack/env/arm/armflang
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/c++
vendored
1
lib/spack/env/c++
vendored
@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/c89
vendored
1
lib/spack/env/c89
vendored
@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/c99
vendored
1
lib/spack/env/c99
vendored
@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/case-insensitive/CC
vendored
1
lib/spack/env/case-insensitive/CC
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/cce/case-insensitive/CC
vendored
1
lib/spack/env/cce/case-insensitive/CC
vendored
@ -1 +0,0 @@
|
||||
../../cc
|
1
lib/spack/env/cce/case-insensitive/crayCC
vendored
1
lib/spack/env/cce/case-insensitive/crayCC
vendored
@ -1 +0,0 @@
|
||||
../../cc
|
1
lib/spack/env/cce/cc
vendored
1
lib/spack/env/cce/cc
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/cce/craycc
vendored
1
lib/spack/env/cce/craycc
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/cce/crayftn
vendored
1
lib/spack/env/cce/crayftn
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/cce/ftn
vendored
1
lib/spack/env/cce/ftn
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/clang/clang
vendored
1
lib/spack/env/clang/clang
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/clang/clang++
vendored
1
lib/spack/env/clang/clang++
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/clang/flang
vendored
1
lib/spack/env/clang/flang
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/clang/gfortran
vendored
1
lib/spack/env/clang/gfortran
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/cpp
vendored
1
lib/spack/env/cpp
vendored
@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/f77
vendored
1
lib/spack/env/f77
vendored
@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/f90
vendored
1
lib/spack/env/f90
vendored
@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/f95
vendored
1
lib/spack/env/f95
vendored
@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/fc
vendored
1
lib/spack/env/fc
vendored
@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/fj/case-insensitive/FCC
vendored
1
lib/spack/env/fj/case-insensitive/FCC
vendored
@ -1 +0,0 @@
|
||||
../../cc
|
1
lib/spack/env/fj/fcc
vendored
1
lib/spack/env/fj/fcc
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/fj/frt
vendored
1
lib/spack/env/fj/frt
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/ftn
vendored
1
lib/spack/env/ftn
vendored
@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/gcc/g++
vendored
1
lib/spack/env/gcc/g++
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/gcc/gcc
vendored
1
lib/spack/env/gcc/gcc
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/gcc/gfortran
vendored
1
lib/spack/env/gcc/gfortran
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/intel/icc
vendored
1
lib/spack/env/intel/icc
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/intel/icpc
vendored
1
lib/spack/env/intel/icpc
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/intel/ifort
vendored
1
lib/spack/env/intel/ifort
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/ld
vendored
1
lib/spack/env/ld
vendored
@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/ld.gold
vendored
1
lib/spack/env/ld.gold
vendored
@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/ld.lld
vendored
1
lib/spack/env/ld.lld
vendored
@ -1 +0,0 @@
|
||||
cc
|
1
lib/spack/env/nag/nagfor
vendored
1
lib/spack/env/nag/nagfor
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/nvhpc/nvc
vendored
1
lib/spack/env/nvhpc/nvc
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/nvhpc/nvc++
vendored
1
lib/spack/env/nvhpc/nvc++
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/nvhpc/nvfortran
vendored
1
lib/spack/env/nvhpc/nvfortran
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/oneapi/dpcpp
vendored
1
lib/spack/env/oneapi/dpcpp
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/oneapi/icpx
vendored
1
lib/spack/env/oneapi/icpx
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/oneapi/icx
vendored
1
lib/spack/env/oneapi/icx
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/oneapi/ifx
vendored
1
lib/spack/env/oneapi/ifx
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/pgi/pgc++
vendored
1
lib/spack/env/pgi/pgc++
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/pgi/pgcc
vendored
1
lib/spack/env/pgi/pgcc
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/pgi/pgfortran
vendored
1
lib/spack/env/pgi/pgfortran
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/rocmcc/amdclang
vendored
1
lib/spack/env/rocmcc/amdclang
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/rocmcc/amdclang++
vendored
1
lib/spack/env/rocmcc/amdclang++
vendored
@ -1 +0,0 @@
|
||||
../cpp
|
1
lib/spack/env/rocmcc/amdflang
vendored
1
lib/spack/env/rocmcc/amdflang
vendored
@ -1 +0,0 @@
|
||||
../fc
|
1
lib/spack/env/xl/xlc
vendored
1
lib/spack/env/xl/xlc
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl/xlc++
vendored
1
lib/spack/env/xl/xlc++
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl/xlf
vendored
1
lib/spack/env/xl/xlf
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl/xlf90
vendored
1
lib/spack/env/xl/xlf90
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl_r/xlc++_r
vendored
1
lib/spack/env/xl_r/xlc++_r
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl_r/xlc_r
vendored
1
lib/spack/env/xl_r/xlc_r
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl_r/xlf90_r
vendored
1
lib/spack/env/xl_r/xlf90_r
vendored
@ -1 +0,0 @@
|
||||
../cc
|
1
lib/spack/env/xl_r/xlf_r
vendored
1
lib/spack/env/xl_r/xlf_r
vendored
@ -1 +0,0 @@
|
||||
../cc
|
@ -21,6 +21,7 @@
|
||||
import spack.platforms
|
||||
import spack.spec
|
||||
import spack.traverse
|
||||
import spack.version
|
||||
|
||||
from .config import spec_for_current_python
|
||||
|
||||
@ -126,6 +127,10 @@ def concretize(self) -> "spack.spec.Spec":
|
||||
if node.name == "gcc-runtime":
|
||||
node.versions = self.host_compiler.versions
|
||||
|
||||
# Can't use re2c@3.1 with Python 3.6
|
||||
if self.host_python.satisfies("@3.6"):
|
||||
s["re2c"].versions.versions = [spack.version.from_string("=2.2")]
|
||||
|
||||
for edge in spack.traverse.traverse_edges([s], cover="edges"):
|
||||
if edge.spec.name == "python":
|
||||
edge.spec = self.host_python
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -584,23 +584,6 @@ def set_package_py_globals(pkg, context: Context = Context.BUILD):
|
||||
# Don't use which for this; we want to find it in the current dir.
|
||||
module.configure = Executable("./configure")
|
||||
|
||||
# Put spack compiler paths in module scope. (Some packages use it
|
||||
# in setup_run_environment etc, so don't put it context == build)
|
||||
link_dir = spack.paths.build_env_path
|
||||
|
||||
# Set spack_cc, etc. for backward compatibility. This might change if the compiler wrapper
|
||||
# is modeled as a package.
|
||||
global_names = {
|
||||
"c": ("spack_cc",),
|
||||
"cxx": ("spack_cxx",),
|
||||
"fortran": ("spack_fc", "spack_f77"),
|
||||
}
|
||||
for language in ("c", "cxx", "fortran"):
|
||||
spec = pkg.spec.dependencies(virtuals=[language])
|
||||
value = None if not spec else os.path.join(link_dir, spec[0].package.link_paths[language])
|
||||
for name in global_names[language]:
|
||||
setattr(module, name, value)
|
||||
|
||||
# Useful directories within the prefix are encapsulated in
|
||||
# a Prefix object.
|
||||
module.prefix = pkg.prefix
|
||||
|
@ -4,22 +4,16 @@
|
||||
import itertools
|
||||
import os
|
||||
import pathlib
|
||||
import platform
|
||||
import re
|
||||
import sys
|
||||
from typing import Dict, List, Optional, Sequence, Tuple, Union
|
||||
|
||||
import archspec.cpu
|
||||
|
||||
import llnl.util.tty as tty
|
||||
from llnl.util.lang import classproperty, memoized
|
||||
|
||||
import spack
|
||||
import spack.compilers.error
|
||||
import spack.compilers.libraries
|
||||
import spack.config
|
||||
import spack.package_base
|
||||
import spack.paths
|
||||
import spack.util.executable
|
||||
|
||||
# Local "type" for type hints
|
||||
@ -109,7 +103,7 @@ def determine_version(cls, exe: Path) -> str:
|
||||
|
||||
@classmethod
|
||||
def compiler_bindir(cls, prefix: Path) -> Path:
|
||||
"""Overridable method for the location of the compiler bindir within the preifx"""
|
||||
"""Overridable method for the location of the compiler bindir within the prefix"""
|
||||
return os.path.join(prefix, "bin")
|
||||
|
||||
@classmethod
|
||||
@ -183,109 +177,6 @@ def standard_flag(self, *, language: str, standard: str) -> str:
|
||||
def _standard_flag(self, *, language: str, standard: str) -> str:
|
||||
raise NotImplementedError("Must be implemented by derived classes")
|
||||
|
||||
@property
|
||||
def disable_new_dtags(self) -> str:
|
||||
if platform.system() == "Darwin":
|
||||
return ""
|
||||
return "--disable-new-dtags"
|
||||
|
||||
@property
|
||||
def enable_new_dtags(self) -> str:
|
||||
if platform.system() == "Darwin":
|
||||
return ""
|
||||
return "--enable-new-dtags"
|
||||
|
||||
def setup_dependent_build_environment(self, env, dependent_spec):
|
||||
# FIXME (compiler as nodes): check if this is good enough or should be made more general
|
||||
|
||||
# The package is not used as a compiler, so skip this setup
|
||||
if not any(
|
||||
lang in dependent_spec and dependent_spec[lang].name == self.spec.name
|
||||
for lang in ("c", "cxx", "fortran")
|
||||
):
|
||||
return
|
||||
|
||||
# Populate an object with the list of environment modifications and return it
|
||||
link_dir = pathlib.Path(spack.paths.build_env_path)
|
||||
env_paths = []
|
||||
|
||||
for language, attr_name, wrapper_var_name, spack_var_name in [
|
||||
("c", "cc", "CC", "SPACK_CC"),
|
||||
("cxx", "cxx", "CXX", "SPACK_CXX"),
|
||||
("fortran", "fortran", "F77", "SPACK_F77"),
|
||||
("fortran", "fortran", "FC", "SPACK_FC"),
|
||||
]:
|
||||
if language not in dependent_spec or dependent_spec[language].name != self.spec.name:
|
||||
continue
|
||||
|
||||
if not hasattr(self, attr_name):
|
||||
continue
|
||||
|
||||
compiler = getattr(self, attr_name)
|
||||
env.set(spack_var_name, compiler)
|
||||
|
||||
if language not in self.link_paths:
|
||||
continue
|
||||
|
||||
wrapper_path = link_dir / self.link_paths.get(language)
|
||||
env.set(wrapper_var_name, str(wrapper_path))
|
||||
env.set(f"SPACK_{wrapper_var_name}_RPATH_ARG", self.rpath_arg)
|
||||
|
||||
uarch = dependent_spec.architecture.target
|
||||
version_number, _ = archspec.cpu.version_components(
|
||||
self.spec.version.dotted_numeric_string
|
||||
)
|
||||
try:
|
||||
isa_arg = uarch.optimization_flags(self.archspec_name(), version_number)
|
||||
except (ValueError, archspec.cpu.UnsupportedMicroarchitecture):
|
||||
isa_arg = ""
|
||||
|
||||
if isa_arg:
|
||||
env.set(f"SPACK_TARGET_ARGS_{attr_name.upper()}", isa_arg)
|
||||
|
||||
# Add spack build environment path with compiler wrappers first in
|
||||
# the path. We add the compiler wrapper path, which includes default
|
||||
# wrappers (cc, c++, f77, f90), AND a subdirectory containing
|
||||
# compiler-specific symlinks. The latter ensures that builds that
|
||||
# are sensitive to the *name* of the compiler see the right name when
|
||||
# we're building with the wrappers.
|
||||
#
|
||||
# Conflicts on case-insensitive systems (like "CC" and "cc") are
|
||||
# handled by putting one in the <build_env_path>/case-insensitive
|
||||
# directory. Add that to the path too.
|
||||
compiler_specific = os.path.join(
|
||||
spack.paths.build_env_path, os.path.dirname(self.link_paths[language])
|
||||
)
|
||||
for item in [spack.paths.build_env_path, compiler_specific]:
|
||||
env_paths.append(item)
|
||||
ci = os.path.join(item, "case-insensitive")
|
||||
if os.path.isdir(ci):
|
||||
env_paths.append(ci)
|
||||
|
||||
# FIXME (compiler as nodes): make these paths language specific
|
||||
env.set("SPACK_LINKER_ARG", self.linker_arg)
|
||||
|
||||
paths = _implicit_rpaths(pkg=self)
|
||||
if paths:
|
||||
env.set("SPACK_COMPILER_IMPLICIT_RPATHS", ":".join(paths))
|
||||
|
||||
# Check whether we want to force RPATH or RUNPATH
|
||||
if spack.config.CONFIG.get("config:shared_linking:type") == "rpath":
|
||||
env.set("SPACK_DTAGS_TO_STRIP", self.enable_new_dtags)
|
||||
env.set("SPACK_DTAGS_TO_ADD", self.disable_new_dtags)
|
||||
else:
|
||||
env.set("SPACK_DTAGS_TO_STRIP", self.disable_new_dtags)
|
||||
env.set("SPACK_DTAGS_TO_ADD", self.enable_new_dtags)
|
||||
|
||||
spec = self.spec
|
||||
if spec.extra_attributes:
|
||||
extra_rpaths = spec.extra_attributes.get("extra_rpaths")
|
||||
if extra_rpaths:
|
||||
env.append_path("SPACK_COMPILER_EXTRA_RPATHS", ":".join(extra_rpaths))
|
||||
|
||||
for item in env_paths:
|
||||
env.prepend_path("SPACK_ENV_PATH", item)
|
||||
|
||||
def archspec_name(self) -> str:
|
||||
"""Name that archspec uses to refer to this compiler"""
|
||||
return self.spec.name
|
||||
@ -324,12 +215,6 @@ def _fortran_path(self) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def _implicit_rpaths(pkg: spack.package_base.PackageBase) -> List[str]:
|
||||
detector = spack.compilers.libraries.CompilerPropertyDetector(pkg.spec)
|
||||
paths = detector.implicit_rpaths()
|
||||
return paths
|
||||
|
||||
|
||||
@memoized
|
||||
def _compiler_output(
|
||||
compiler_path: Path, *, version_argument: str, ignore_errors: Tuple[int, ...] = ()
|
||||
|
@ -38,7 +38,6 @@
|
||||
r"^lib/spack/spack/.*\.sh$",
|
||||
r"^lib/spack/spack/.*\.lp$",
|
||||
r"^lib/spack/llnl/.*\.py$",
|
||||
r"^lib/spack/env/cc$",
|
||||
# special case some test data files that have license headers
|
||||
r"^lib/spack/spack/test/data/style/broken.dummy",
|
||||
r"^lib/spack/spack/test/data/unparse/.*\.txt",
|
||||
|
@ -31,7 +31,6 @@
|
||||
# spack directory hierarchy
|
||||
lib_path = os.path.join(prefix, "lib", "spack")
|
||||
external_path = os.path.join(lib_path, "external")
|
||||
build_env_path = os.path.join(lib_path, "env")
|
||||
module_path = os.path.join(lib_path, "spack")
|
||||
command_path = os.path.join(module_path, "cmd")
|
||||
analyzers_path = os.path.join(module_path, "analyzers")
|
||||
|
@ -3149,6 +3149,16 @@ def define_runtime_constraints(self):
|
||||
# Inject default flags for compilers
|
||||
recorder("*").default_flags(compiler)
|
||||
|
||||
# FIXME (compiler as nodes): think of using isinstance(compiler_cls, WrappedCompiler)
|
||||
# Add a dependency on the compiler wrapper
|
||||
if sys.platform != "win32":
|
||||
recorder("*").depends_on(
|
||||
"compiler-wrapper",
|
||||
when=f"%{compiler.name}@{compiler.versions}",
|
||||
type="build",
|
||||
description=f"Add the compiler wrapper when using {compiler}",
|
||||
)
|
||||
|
||||
if not using_libc_compatibility():
|
||||
continue
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
import os
|
||||
import platform
|
||||
import posixpath
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
@ -13,19 +13,16 @@
|
||||
from llnl.util.filesystem import HeaderList, LibraryList
|
||||
|
||||
import spack.build_environment
|
||||
import spack.build_systems.compiler
|
||||
import spack.concretize
|
||||
import spack.config
|
||||
import spack.deptypes as dt
|
||||
import spack.package_base
|
||||
import spack.paths
|
||||
import spack.spec
|
||||
import spack.util.environment
|
||||
import spack.util.spack_yaml as syaml
|
||||
from spack.build_environment import UseMode, _static_to_shared_library, dso_suffix
|
||||
from spack.context import Context
|
||||
from spack.installer import PackageInstaller
|
||||
from spack.paths import build_env_path
|
||||
from spack.util.environment import EnvironmentModifications
|
||||
from spack.util.executable import Executable
|
||||
|
||||
@ -42,55 +39,41 @@ def prep_and_join(path, *pths):
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def build_environment(working_env):
|
||||
cc = Executable(os.path.join(build_env_path, "cc"))
|
||||
cxx = Executable(os.path.join(build_env_path, "c++"))
|
||||
fc = Executable(os.path.join(build_env_path, "fc"))
|
||||
|
||||
def build_environment(monkeypatch, wrapper_dir, tmp_path):
|
||||
realcc = "/bin/mycc"
|
||||
prefix = "/spack-test-prefix"
|
||||
prefix = str(tmp_path)
|
||||
|
||||
os.environ["SPACK_CC"] = realcc
|
||||
os.environ["SPACK_CXX"] = realcc
|
||||
os.environ["SPACK_FC"] = realcc
|
||||
monkeypatch.setenv("SPACK_CC", realcc)
|
||||
monkeypatch.setenv("SPACK_CXX", realcc)
|
||||
monkeypatch.setenv("SPACK_FC", realcc)
|
||||
|
||||
os.environ["SPACK_PREFIX"] = prefix
|
||||
os.environ["SPACK_ENV_PATH"] = "test"
|
||||
os.environ["SPACK_DEBUG_LOG_DIR"] = "."
|
||||
os.environ["SPACK_DEBUG_LOG_ID"] = "foo-hashabc"
|
||||
os.environ["SPACK_SHORT_SPEC"] = "foo@1.2 arch=linux-rhel6-x86_64 /hashabc"
|
||||
monkeypatch.setenv("SPACK_PREFIX", prefix)
|
||||
monkeypatch.setenv("SPACK_ENV_PATH", "test")
|
||||
monkeypatch.setenv("SPACK_DEBUG_LOG_DIR", ".")
|
||||
monkeypatch.setenv("SPACK_DEBUG_LOG_ID", "foo-hashabc")
|
||||
monkeypatch.setenv("SPACK_SHORT_SPEC", "foo@1.2 arch=linux-rhel6-x86_64 /hashabc")
|
||||
|
||||
os.environ["SPACK_CC_RPATH_ARG"] = "-Wl,-rpath,"
|
||||
os.environ["SPACK_CXX_RPATH_ARG"] = "-Wl,-rpath,"
|
||||
os.environ["SPACK_F77_RPATH_ARG"] = "-Wl,-rpath,"
|
||||
os.environ["SPACK_FC_RPATH_ARG"] = "-Wl,-rpath,"
|
||||
os.environ["SPACK_LINKER_ARG"] = "-Wl,"
|
||||
os.environ["SPACK_DTAGS_TO_ADD"] = "--disable-new-dtags"
|
||||
os.environ["SPACK_DTAGS_TO_STRIP"] = "--enable-new-dtags"
|
||||
os.environ["SPACK_SYSTEM_DIRS"] = "/usr/include|/usr/lib"
|
||||
os.environ["SPACK_MANAGED_DIRS"] = f"{prefix}/opt/spack"
|
||||
os.environ["SPACK_TARGET_ARGS"] = ""
|
||||
monkeypatch.setenv("SPACK_CC_RPATH_ARG", "-Wl,-rpath,")
|
||||
monkeypatch.setenv("SPACK_CXX_RPATH_ARG", "-Wl,-rpath,")
|
||||
monkeypatch.setenv("SPACK_F77_RPATH_ARG", "-Wl,-rpath,")
|
||||
monkeypatch.setenv("SPACK_FC_RPATH_ARG", "-Wl,-rpath,")
|
||||
monkeypatch.setenv("SPACK_CC_LINKER_ARG", "-Wl,")
|
||||
monkeypatch.setenv("SPACK_CXX_LINKER_ARG", "-Wl,")
|
||||
monkeypatch.setenv("SPACK_FC_LINKER_ARG", "-Wl,")
|
||||
monkeypatch.setenv("SPACK_F77_LINKER_ARG", "-Wl,")
|
||||
monkeypatch.setenv("SPACK_DTAGS_TO_ADD", "--disable-new-dtags")
|
||||
monkeypatch.setenv("SPACK_DTAGS_TO_STRIP", "--enable-new-dtags")
|
||||
monkeypatch.setenv("SPACK_SYSTEM_DIRS", "/usr/include|/usr/lib")
|
||||
monkeypatch.setenv("SPACK_MANAGED_DIRS", f"{prefix}/opt/spack")
|
||||
monkeypatch.setenv("SPACK_TARGET_ARGS", "")
|
||||
|
||||
if "SPACK_DEPENDENCIES" in os.environ:
|
||||
del os.environ["SPACK_DEPENDENCIES"]
|
||||
monkeypatch.delenv("SPACK_DEPENDENCIES", raising=False)
|
||||
|
||||
yield {"cc": cc, "cxx": cxx, "fc": fc}
|
||||
cc = Executable(str(wrapper_dir / "cc"))
|
||||
cxx = Executable(str(wrapper_dir / "c++"))
|
||||
fc = Executable(str(wrapper_dir / "fc"))
|
||||
|
||||
for name in (
|
||||
"SPACK_CC",
|
||||
"SPACK_CXX",
|
||||
"SPACK_FC",
|
||||
"SPACK_PREFIX",
|
||||
"SPACK_ENV_PATH",
|
||||
"SPACK_DEBUG_LOG_DIR",
|
||||
"SPACK_SHORT_SPEC",
|
||||
"SPACK_CC_RPATH_ARG",
|
||||
"SPACK_CXX_RPATH_ARG",
|
||||
"SPACK_F77_RPATH_ARG",
|
||||
"SPACK_FC_RPATH_ARG",
|
||||
"SPACK_TARGET_ARGS",
|
||||
):
|
||||
del os.environ[name]
|
||||
return {"cc": cc, "cxx": cxx, "fc": fc}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -322,14 +305,14 @@ def test_external_config_env(mock_packages, mutable_config, working_env):
|
||||
@pytest.mark.regression("9107")
|
||||
@pytest.mark.not_on_windows("Windows does not support module files")
|
||||
def test_spack_paths_before_module_paths(
|
||||
mutable_config, mock_packages, compiler_factory, monkeypatch, working_env
|
||||
mutable_config, mock_packages, compiler_factory, monkeypatch, working_env, wrapper_dir
|
||||
):
|
||||
gcc_entry = compiler_factory(spec="gcc@14.0.1 languages=c,c++")
|
||||
gcc_entry["modules"] = ["some_module"]
|
||||
mutable_config.set("packages", {"gcc": {"externals": [gcc_entry]}})
|
||||
|
||||
module_path = os.path.join("path", "to", "module")
|
||||
spack_path = os.path.join(spack.paths.prefix, os.path.join("lib", "spack", "env"))
|
||||
monkeypatch.setenv("SPACK_ENV_PATH", wrapper_dir)
|
||||
|
||||
def _set_wrong_cc(x):
|
||||
os.environ["PATH"] = module_path + os.pathsep + os.environ["PATH"]
|
||||
@ -341,7 +324,7 @@ def _set_wrong_cc(x):
|
||||
spack.build_environment.setup_package(s.package, dirty=False)
|
||||
|
||||
paths = os.environ["PATH"].split(os.pathsep)
|
||||
assert paths.index(spack_path) < paths.index(module_path)
|
||||
assert paths.index(str(wrapper_dir)) < paths.index(module_path)
|
||||
|
||||
|
||||
def test_package_inheritance_module_setup(config, mock_packages, working_env):
|
||||
@ -484,11 +467,9 @@ def test_parallel_false_is_not_propagating(default_mock_concretization):
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"config_setting,expected_flag",
|
||||
[
|
||||
("runpath", "" if platform.system() == "Darwin" else "--enable-new-dtags"),
|
||||
("rpath", "" if platform.system() == "Darwin" else "--disable-new-dtags"),
|
||||
],
|
||||
[("runpath", "--enable-new-dtags"), ("rpath", "--disable-new-dtags")],
|
||||
)
|
||||
@pytest.mark.skipif(sys.platform != "linux", reason="dtags make sense only on linux")
|
||||
def test_setting_dtags_based_on_config(
|
||||
config_setting, expected_flag, config, mock_packages, working_env
|
||||
):
|
||||
@ -787,12 +768,11 @@ def test_optimization_flags_are_using_node_target(default_mock_concretization, m
|
||||
"""Tests that we are using the target on the node to be compiled to retrieve the uarch
|
||||
specific flags, and not the target of the compiler.
|
||||
"""
|
||||
monkeypatch.setattr(spack.build_systems.compiler, "_implicit_rpaths", lambda pkg: [])
|
||||
gcc = default_mock_concretization("gcc target=core2")
|
||||
compiler_wrapper_pkg = default_mock_concretization("compiler-wrapper target=core2").package
|
||||
mpileaks = default_mock_concretization("mpileaks target=x86_64")
|
||||
|
||||
env = EnvironmentModifications()
|
||||
gcc.package.setup_dependent_build_environment(env, mpileaks)
|
||||
compiler_wrapper_pkg.setup_dependent_build_environment(env, mpileaks)
|
||||
actions = env.group_by_name()["SPACK_TARGET_ARGS_CC"]
|
||||
|
||||
assert len(actions) == 1 and isinstance(actions[0], spack.util.environment.SetEnv)
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
import spack.build_environment
|
||||
import spack.config
|
||||
from spack.paths import build_env_path
|
||||
from spack.util.environment import SYSTEM_DIR_CASE_ENTRY, set_env
|
||||
from spack.util.executable import Executable, ProcessError
|
||||
|
||||
@ -110,12 +109,6 @@
|
||||
#: The prefix of the package being mock installed
|
||||
pkg_prefix = "/spack-test-prefix"
|
||||
|
||||
# Compilers to use during tests
|
||||
cc = Executable(os.path.join(build_env_path, "cc"))
|
||||
ld = Executable(os.path.join(build_env_path, "ld"))
|
||||
cpp = Executable(os.path.join(build_env_path, "cpp"))
|
||||
cxx = Executable(os.path.join(build_env_path, "c++"))
|
||||
fc = Executable(os.path.join(build_env_path, "fc"))
|
||||
|
||||
#: the "real" compiler the wrapper is expected to invoke
|
||||
real_cc = "/bin/mycc"
|
||||
@ -169,7 +162,10 @@ def wrapper_environment(working_env):
|
||||
SPACK_TARGET_ARGS_CC="-march=znver2 -mtune=znver2",
|
||||
SPACK_TARGET_ARGS_CXX="-march=znver2 -mtune=znver2",
|
||||
SPACK_TARGET_ARGS_FORTRAN="-march=znver4 -mtune=znver4",
|
||||
SPACK_LINKER_ARG="-Wl,",
|
||||
SPACK_CC_LINKER_ARG="-Wl,",
|
||||
SPACK_CXX_LINKER_ARG="-Wl,",
|
||||
SPACK_FC_LINKER_ARG="-Wl,",
|
||||
SPACK_F77_LINKER_ARG="-Wl,",
|
||||
SPACK_DTAGS_TO_ADD="--disable-new-dtags",
|
||||
SPACK_DTAGS_TO_STRIP="--enable-new-dtags",
|
||||
SPACK_COMPILER_FLAGS_KEEP="",
|
||||
@ -198,6 +194,7 @@ def check_args(cc, args, expected):
|
||||
per line, so that we see whether arguments that should (or shouldn't)
|
||||
contain spaces are parsed correctly.
|
||||
"""
|
||||
cc = Executable(str(cc))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-args"):
|
||||
cc_modified_args = cc(*args, output=str).strip().split("\n")
|
||||
assert cc_modified_args == expected
|
||||
@ -210,9 +207,9 @@ def check_args_contents(cc, args, must_contain, must_not_contain):
|
||||
per line, so that we see whether arguments that should (or shouldn't)
|
||||
contain spaces are parsed correctly.
|
||||
"""
|
||||
cc = Executable(str(cc))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-args"):
|
||||
cc_modified_args = cc(*args, output=str).strip().split("\n")
|
||||
print(cc_modified_args)
|
||||
for a in must_contain:
|
||||
assert a in cc_modified_args
|
||||
for a in must_not_contain:
|
||||
@ -225,6 +222,7 @@ def check_env_var(executable, var, expected):
|
||||
This assumes that cc will print debug output when it's environment
|
||||
contains SPACK_TEST_COMMAND=dump-env-<variable-to-debug>
|
||||
"""
|
||||
executable = Executable(str(executable))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-env-" + var):
|
||||
output = executable(*test_args, output=str).strip()
|
||||
assert executable.path + ": " + var + ": " + expected == output
|
||||
@ -232,17 +230,25 @@ def check_env_var(executable, var, expected):
|
||||
|
||||
def dump_mode(cc, args):
|
||||
"""Make cc dump the mode it detects, and return it."""
|
||||
cc = Executable(str(cc))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-mode"):
|
||||
return cc(*args, output=str).strip()
|
||||
|
||||
|
||||
def test_no_wrapper_environment():
|
||||
def test_no_wrapper_environment(wrapper_dir):
|
||||
cc = Executable(str(wrapper_dir / "cc"))
|
||||
with pytest.raises(ProcessError):
|
||||
output = cc(output=str)
|
||||
assert "Spack compiler must be run from Spack" in output
|
||||
|
||||
|
||||
def test_vcheck_mode(wrapper_environment):
|
||||
def test_modes(wrapper_environment, wrapper_dir):
|
||||
cc = wrapper_dir / "cc"
|
||||
cxx = wrapper_dir / "c++"
|
||||
cpp = wrapper_dir / "cpp"
|
||||
ld = wrapper_dir / "ld"
|
||||
|
||||
# vcheck
|
||||
assert dump_mode(cc, ["-I/include", "--version"]) == "vcheck"
|
||||
assert dump_mode(cc, ["-I/include", "-V"]) == "vcheck"
|
||||
assert dump_mode(cc, ["-I/include", "-v"]) == "vcheck"
|
||||
@ -250,38 +256,39 @@ def test_vcheck_mode(wrapper_environment):
|
||||
assert dump_mode(cc, ["-I/include", "--version", "-c"]) == "vcheck"
|
||||
assert dump_mode(cc, ["-I/include", "-V", "-o", "output"]) == "vcheck"
|
||||
|
||||
|
||||
def test_cpp_mode(wrapper_environment):
|
||||
# cpp
|
||||
assert dump_mode(cc, ["-E"]) == "cpp"
|
||||
assert dump_mode(cxx, ["-E"]) == "cpp"
|
||||
assert dump_mode(cpp, []) == "cpp"
|
||||
|
||||
|
||||
def test_as_mode(wrapper_environment):
|
||||
# as
|
||||
assert dump_mode(cc, ["-S"]) == "as"
|
||||
|
||||
|
||||
def test_ccld_mode(wrapper_environment):
|
||||
# ccld
|
||||
assert dump_mode(cc, []) == "ccld"
|
||||
assert dump_mode(cc, ["foo.c", "-o", "foo"]) == "ccld"
|
||||
assert dump_mode(cc, ["foo.c", "-o", "foo", "-Wl,-rpath,foo"]) == "ccld"
|
||||
assert dump_mode(cc, ["foo.o", "bar.o", "baz.o", "-o", "foo", "-Wl,-rpath,foo"]) == "ccld"
|
||||
|
||||
|
||||
def test_ld_mode(wrapper_environment):
|
||||
# ld
|
||||
assert dump_mode(ld, []) == "ld"
|
||||
assert dump_mode(ld, ["foo.o", "bar.o", "baz.o", "-o", "foo", "-Wl,-rpath,foo"]) == "ld"
|
||||
|
||||
|
||||
def test_ld_unterminated_rpath(wrapper_environment):
|
||||
@pytest.mark.regression("37179")
|
||||
def test_expected_args(wrapper_environment, wrapper_dir):
|
||||
cc = wrapper_dir / "cc"
|
||||
fc = wrapper_dir / "fc"
|
||||
ld = wrapper_dir / "ld"
|
||||
|
||||
# ld_unterminated_rpath
|
||||
check_args(
|
||||
ld,
|
||||
["foo.o", "bar.o", "baz.o", "-o", "foo", "-rpath"],
|
||||
["ld", "--disable-new-dtags", "foo.o", "bar.o", "baz.o", "-o", "foo", "-rpath"],
|
||||
)
|
||||
|
||||
|
||||
def test_xlinker_unterminated_rpath(wrapper_environment):
|
||||
# xlinker_unterminated_rpath
|
||||
check_args(
|
||||
cc,
|
||||
["foo.o", "bar.o", "baz.o", "-o", "foo", "-Xlinker", "-rpath"],
|
||||
@ -299,8 +306,7 @@ def test_xlinker_unterminated_rpath(wrapper_environment):
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def test_wl_unterminated_rpath(wrapper_environment):
|
||||
# wl_unterminated_rpath
|
||||
check_args(
|
||||
cc,
|
||||
["foo.o", "bar.o", "baz.o", "-o", "foo", "-Wl,-rpath"],
|
||||
@ -309,99 +315,7 @@ def test_wl_unterminated_rpath(wrapper_environment):
|
||||
+ ["-Wl,--disable-new-dtags", "foo.o", "bar.o", "baz.o", "-o", "foo", "-Wl,-rpath"],
|
||||
)
|
||||
|
||||
|
||||
def test_ld_flags(wrapper_environment, wrapper_flags):
|
||||
check_args(
|
||||
ld,
|
||||
test_args,
|
||||
["ld"]
|
||||
+ test_include_paths
|
||||
+ test_library_paths
|
||||
+ ["--disable-new-dtags"]
|
||||
+ test_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
|
||||
def test_cpp_flags(wrapper_environment, wrapper_flags):
|
||||
check_args(
|
||||
cpp,
|
||||
test_args,
|
||||
["cpp"]
|
||||
+ test_include_paths
|
||||
+ test_library_paths
|
||||
+ test_args_without_paths
|
||||
+ spack_cppflags,
|
||||
)
|
||||
|
||||
|
||||
def test_cc_flags(wrapper_environment, wrapper_flags):
|
||||
check_args(
|
||||
cc,
|
||||
test_args,
|
||||
[real_cc]
|
||||
+ target_args
|
||||
+ test_include_paths
|
||||
+ ["-Lfoo"]
|
||||
+ test_library_paths
|
||||
+ ["-Wl,--disable-new-dtags"]
|
||||
+ test_wl_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_cppflags
|
||||
+ spack_cflags
|
||||
+ ["-Wl,--gc-sections"]
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
|
||||
def test_cxx_flags(wrapper_environment, wrapper_flags):
|
||||
check_args(
|
||||
cxx,
|
||||
test_args,
|
||||
[real_cc]
|
||||
+ target_args
|
||||
+ test_include_paths
|
||||
+ ["-Lfoo"]
|
||||
+ test_library_paths
|
||||
+ ["-Wl,--disable-new-dtags"]
|
||||
+ test_wl_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_cppflags
|
||||
+ ["-Wl,--gc-sections"]
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
|
||||
def test_fc_flags(wrapper_environment, wrapper_flags):
|
||||
check_args(
|
||||
fc,
|
||||
test_args,
|
||||
[real_cc]
|
||||
+ target_args_fc
|
||||
+ test_include_paths
|
||||
+ ["-Lfoo"]
|
||||
+ test_library_paths
|
||||
+ ["-Wl,--disable-new-dtags"]
|
||||
+ test_wl_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_fflags
|
||||
+ spack_cppflags
|
||||
+ ["-Wl,--gc-sections"]
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
|
||||
def test_always_cflags(wrapper_environment, wrapper_flags):
|
||||
with set_env(SPACK_ALWAYS_CFLAGS="-always1 -always2"):
|
||||
check_args(
|
||||
cc,
|
||||
["-v", "--cmd-line-v-opt"],
|
||||
[real_cc] + ["-always1", "-always2"] + ["-v", "--cmd-line-v-opt"],
|
||||
)
|
||||
|
||||
|
||||
def test_Wl_parsing(wrapper_environment):
|
||||
# Wl_parsing
|
||||
check_args(
|
||||
cc,
|
||||
["-Wl,-rpath,/a,--enable-new-dtags,-rpath=/b,--rpath", "-Wl,/c"],
|
||||
@ -410,26 +324,22 @@ def test_Wl_parsing(wrapper_environment):
|
||||
+ ["-Wl,--disable-new-dtags", "-Wl,-rpath,/a", "-Wl,-rpath,/b", "-Wl,-rpath,/c"],
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.regression("37179")
|
||||
def test_Wl_parsing_with_missing_value(wrapper_environment):
|
||||
# Wl_parsing_with_missing_value
|
||||
check_args(
|
||||
cc,
|
||||
["-Wl,-rpath=/a,-rpath=", "-Wl,--rpath="],
|
||||
[real_cc] + target_args + ["-Wl,--disable-new-dtags", "-Wl,-rpath,/a"],
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.regression("37179")
|
||||
def test_Wl_parsing_NAG_is_ignored(wrapper_environment):
|
||||
# Wl_parsing_NAG_is_ignored
|
||||
check_args(
|
||||
fc,
|
||||
["-Wl,-Wl,,x,,y,,z"],
|
||||
[real_cc] + target_args_fc + ["-Wl,--disable-new-dtags", "-Wl,-Wl,,x,,y,,z"],
|
||||
)
|
||||
|
||||
|
||||
def test_Xlinker_parsing(wrapper_environment):
|
||||
# Xlinker_parsing
|
||||
#
|
||||
# -Xlinker <x> ... -Xlinker <y> may have compiler flags inbetween, like -O3 in this
|
||||
# example. Also check that a trailing -Xlinker (which is a compiler error) is not
|
||||
# dropped or given an empty argument.
|
||||
@ -460,8 +370,8 @@ def test_Xlinker_parsing(wrapper_environment):
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def test_rpath_without_value(wrapper_environment):
|
||||
# rpath_without_value
|
||||
#
|
||||
# cc -Wl,-rpath without a value shouldn't drop -Wl,-rpath;
|
||||
# same for -Xlinker
|
||||
check_args(
|
||||
@ -475,14 +385,10 @@ def test_rpath_without_value(wrapper_environment):
|
||||
[real_cc] + target_args + ["-Wl,--disable-new-dtags", "-O3", "-g", "-Xlinker", "-rpath"],
|
||||
)
|
||||
|
||||
|
||||
def test_dep_rpath(wrapper_environment):
|
||||
"""Ensure RPATHs for root package are added."""
|
||||
# dep_rapth
|
||||
check_args(cc, test_args, [real_cc] + target_args + common_compile_args)
|
||||
|
||||
|
||||
def test_dep_include(wrapper_environment):
|
||||
"""Ensure a single dependency include directory is added."""
|
||||
# dep_include
|
||||
with set_env(SPACK_INCLUDE_DIRS="x"):
|
||||
check_args(
|
||||
cc,
|
||||
@ -497,29 +403,9 @@ def test_dep_include(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_system_path_cleanup(wrapper_environment):
|
||||
"""Ensure SPACK_ENV_PATH is removed from PATH, even with trailing /
|
||||
|
||||
The compiler wrapper has to ensure that it is not called nested
|
||||
like it would happen when gcc's collect2 looks in PATH for ld.
|
||||
|
||||
To prevent nested calls, the compiler wrapper removes the elements
|
||||
of SPACK_ENV_PATH from PATH. Autotest's generated testsuite appends
|
||||
a / to each element of PATH when adding AUTOTEST_PATH.
|
||||
Thus, ensure that PATH cleanup works even with trailing /.
|
||||
"""
|
||||
system_path = "/bin:/usr/bin:/usr/local/bin"
|
||||
cc_dir = os.path.dirname(cc.path)
|
||||
with set_env(SPACK_ENV_PATH=cc_dir, SPACK_CC="true"):
|
||||
with set_env(PATH=cc_dir + ":" + system_path):
|
||||
check_env_var(cc, "PATH", system_path)
|
||||
with set_env(PATH=cc_dir + "/:" + system_path):
|
||||
check_env_var(cc, "PATH", system_path)
|
||||
|
||||
|
||||
def test_dep_lib(wrapper_environment):
|
||||
"""Ensure a single dependency RPATH is added."""
|
||||
# dep_lib
|
||||
#
|
||||
# Ensure a single dependency RPATH is added
|
||||
with set_env(SPACK_LINK_DIRS="x", SPACK_RPATH_DIRS="x"):
|
||||
check_args(
|
||||
cc,
|
||||
@ -535,9 +421,9 @@ def test_dep_lib(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_dep_lib_no_rpath(wrapper_environment):
|
||||
"""Ensure a single dependency link flag is added with no dep RPATH."""
|
||||
# dep_lib_no_rpath
|
||||
#
|
||||
# Ensure a single dependency link flag is added with no dep RPATH
|
||||
with set_env(SPACK_LINK_DIRS="x"):
|
||||
check_args(
|
||||
cc,
|
||||
@ -552,9 +438,8 @@ def test_dep_lib_no_rpath(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_dep_lib_no_lib(wrapper_environment):
|
||||
"""Ensure a single dependency RPATH is added with no -L."""
|
||||
# dep_lib_no_lib
|
||||
# Ensure a single dependency RPATH is added with no -L
|
||||
with set_env(SPACK_RPATH_DIRS="x"):
|
||||
check_args(
|
||||
cc,
|
||||
@ -569,9 +454,8 @@ def test_dep_lib_no_lib(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ccld_deps(wrapper_environment):
|
||||
"""Ensure all flags are added in ccld mode."""
|
||||
# ccld_deps
|
||||
# Ensure all flags are added in ccld mode
|
||||
with set_env(
|
||||
SPACK_INCLUDE_DIRS="xinc:yinc:zinc",
|
||||
SPACK_RPATH_DIRS="xlib:ylib:zlib",
|
||||
@ -592,13 +476,13 @@ def test_ccld_deps(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ccld_deps_isystem(wrapper_environment):
|
||||
"""Ensure all flags are added in ccld mode.
|
||||
When a build uses -isystem, Spack should inject it's
|
||||
include paths using -isystem. Spack will insert these
|
||||
after any provided -isystem includes, but before any
|
||||
system directories included using -isystem"""
|
||||
# ccld_deps_isystem
|
||||
#
|
||||
# Ensure all flags are added in ccld mode.
|
||||
# When a build uses -isystem, Spack should inject it's
|
||||
# include paths using -isystem. Spack will insert these
|
||||
# after any provided -isystem includes, but before any
|
||||
# system directories included using -isystem
|
||||
with set_env(
|
||||
SPACK_INCLUDE_DIRS="xinc:yinc:zinc",
|
||||
SPACK_RPATH_DIRS="xlib:ylib:zlib",
|
||||
@ -620,9 +504,8 @@ def test_ccld_deps_isystem(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_cc_deps(wrapper_environment):
|
||||
"""Ensure -L and RPATHs are not added in cc mode."""
|
||||
# cc_deps
|
||||
# Ensure -L and RPATHs are not added in cc mode
|
||||
with set_env(
|
||||
SPACK_INCLUDE_DIRS="xinc:yinc:zinc",
|
||||
SPACK_RPATH_DIRS="xlib:ylib:zlib",
|
||||
@ -640,9 +523,8 @@ def test_cc_deps(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ccld_with_system_dirs(wrapper_environment):
|
||||
"""Ensure all flags are added in ccld mode."""
|
||||
# ccld_with_system_dirs
|
||||
# Ensure all flags are added in ccld mode
|
||||
with set_env(
|
||||
SPACK_INCLUDE_DIRS="xinc:yinc:zinc",
|
||||
SPACK_RPATH_DIRS="xlib:ylib:zlib",
|
||||
@ -673,12 +555,11 @@ def test_ccld_with_system_dirs(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ccld_with_system_dirs_isystem(wrapper_environment):
|
||||
"""Ensure all flags are added in ccld mode.
|
||||
Ensure that includes are in the proper
|
||||
place when a build uses -isystem, and uses
|
||||
system directories in the include paths"""
|
||||
# ccld_with_system_dirs_isystem
|
||||
# Ensure all flags are added in ccld mode.
|
||||
# Ensure that includes are in the proper
|
||||
# place when a build uses -isystem, and uses
|
||||
# system directories in the include paths
|
||||
with set_env(
|
||||
SPACK_INCLUDE_DIRS="xinc:yinc:zinc",
|
||||
SPACK_RPATH_DIRS="xlib:ylib:zlib",
|
||||
@ -711,9 +592,8 @@ def test_ccld_with_system_dirs_isystem(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ld_deps(wrapper_environment):
|
||||
"""Ensure no (extra) -I args or -Wl, are passed in ld mode."""
|
||||
# ld_deps
|
||||
# Ensure no (extra) -I args or -Wl, are passed in ld mode
|
||||
with set_env(
|
||||
SPACK_INCLUDE_DIRS="xinc:yinc:zinc",
|
||||
SPACK_RPATH_DIRS="xlib:ylib:zlib",
|
||||
@ -732,9 +612,8 @@ def test_ld_deps(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ld_deps_no_rpath(wrapper_environment):
|
||||
"""Ensure SPACK_LINK_DEPS controls -L for ld."""
|
||||
# ld_deps_no_rpath
|
||||
# Ensure SPACK_LINK_DEPS controls -L for ld
|
||||
with set_env(SPACK_INCLUDE_DIRS="xinc:yinc:zinc", SPACK_LINK_DIRS="xlib:ylib:zlib"):
|
||||
check_args(
|
||||
ld,
|
||||
@ -748,9 +627,8 @@ def test_ld_deps_no_rpath(wrapper_environment):
|
||||
+ test_args_without_paths,
|
||||
)
|
||||
|
||||
|
||||
def test_ld_deps_no_link(wrapper_environment):
|
||||
"""Ensure SPACK_RPATH_DEPS controls -rpath for ld."""
|
||||
# ld_deps_no_link
|
||||
# Ensure SPACK_RPATH_DEPS controls -rpath for ld
|
||||
with set_env(SPACK_INCLUDE_DIRS="xinc:yinc:zinc", SPACK_RPATH_DIRS="xlib:ylib:zlib"):
|
||||
check_args(
|
||||
ld,
|
||||
@ -765,10 +643,124 @@ def test_ld_deps_no_link(wrapper_environment):
|
||||
)
|
||||
|
||||
|
||||
def test_ld_deps_partial(wrapper_environment):
|
||||
def test_expected_args_with_flags(wrapper_environment, wrapper_flags, wrapper_dir):
|
||||
cc = wrapper_dir / "cc"
|
||||
cxx = wrapper_dir / "c++"
|
||||
cpp = wrapper_dir / "cpp"
|
||||
fc = wrapper_dir / "fc"
|
||||
ld = wrapper_dir / "ld"
|
||||
|
||||
# ld_flags
|
||||
check_args(
|
||||
ld,
|
||||
test_args,
|
||||
["ld"]
|
||||
+ test_include_paths
|
||||
+ test_library_paths
|
||||
+ ["--disable-new-dtags"]
|
||||
+ test_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
# cpp_flags
|
||||
check_args(
|
||||
cpp,
|
||||
test_args,
|
||||
["cpp"]
|
||||
+ test_include_paths
|
||||
+ test_library_paths
|
||||
+ test_args_without_paths
|
||||
+ spack_cppflags,
|
||||
)
|
||||
|
||||
# cc_flags
|
||||
check_args(
|
||||
cc,
|
||||
test_args,
|
||||
[real_cc]
|
||||
+ target_args
|
||||
+ test_include_paths
|
||||
+ ["-Lfoo"]
|
||||
+ test_library_paths
|
||||
+ ["-Wl,--disable-new-dtags"]
|
||||
+ test_wl_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_cppflags
|
||||
+ spack_cflags
|
||||
+ ["-Wl,--gc-sections"]
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
# cxx_flags
|
||||
check_args(
|
||||
cxx,
|
||||
test_args,
|
||||
[real_cc]
|
||||
+ target_args
|
||||
+ test_include_paths
|
||||
+ ["-Lfoo"]
|
||||
+ test_library_paths
|
||||
+ ["-Wl,--disable-new-dtags"]
|
||||
+ test_wl_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_cppflags
|
||||
+ ["-Wl,--gc-sections"]
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
# fc_flags
|
||||
check_args(
|
||||
fc,
|
||||
test_args,
|
||||
[real_cc]
|
||||
+ target_args_fc
|
||||
+ test_include_paths
|
||||
+ ["-Lfoo"]
|
||||
+ test_library_paths
|
||||
+ ["-Wl,--disable-new-dtags"]
|
||||
+ test_wl_rpaths
|
||||
+ test_args_without_paths
|
||||
+ spack_fflags
|
||||
+ spack_cppflags
|
||||
+ ["-Wl,--gc-sections"]
|
||||
+ spack_ldlibs,
|
||||
)
|
||||
|
||||
# always_cflags
|
||||
with set_env(SPACK_ALWAYS_CFLAGS="-always1 -always2"):
|
||||
check_args(
|
||||
cc,
|
||||
["-v", "--cmd-line-v-opt"],
|
||||
[real_cc] + ["-always1", "-always2"] + ["-v", "--cmd-line-v-opt"],
|
||||
)
|
||||
|
||||
|
||||
def test_system_path_cleanup(wrapper_environment, wrapper_dir):
|
||||
"""Ensure SPACK_ENV_PATH is removed from PATH, even with trailing /
|
||||
|
||||
The compiler wrapper has to ensure that it is not called nested
|
||||
like it would happen when gcc's collect2 looks in PATH for ld.
|
||||
|
||||
To prevent nested calls, the compiler wrapper removes the elements
|
||||
of SPACK_ENV_PATH from PATH. Autotest's generated testsuite appends
|
||||
a / to each element of PATH when adding AUTOTEST_PATH.
|
||||
Thus, ensure that PATH cleanup works even with trailing /.
|
||||
"""
|
||||
cc = wrapper_dir / "cc"
|
||||
system_path = "/bin:/usr/bin:/usr/local/bin"
|
||||
with set_env(SPACK_ENV_PATH=str(wrapper_dir), SPACK_CC="true"):
|
||||
with set_env(PATH=str(wrapper_dir) + ":" + system_path):
|
||||
check_env_var(cc, "PATH", system_path)
|
||||
with set_env(PATH=str(wrapper_dir) + "/:" + system_path):
|
||||
check_env_var(cc, "PATH", system_path)
|
||||
|
||||
|
||||
def test_ld_deps_partial(wrapper_environment, wrapper_dir):
|
||||
"""Make sure ld -r (partial link) is handled correctly on OS's where it
|
||||
doesn't accept rpaths.
|
||||
"""
|
||||
ld = wrapper_dir / "ld"
|
||||
with set_env(SPACK_INCLUDE_DIRS="xinc", SPACK_RPATH_DIRS="xlib", SPACK_LINK_DIRS="xlib"):
|
||||
# TODO: do we need to add RPATHs on other platforms like Linux?
|
||||
# TODO: Can't we treat them the same?
|
||||
@ -805,7 +797,8 @@ def test_ld_deps_partial(wrapper_environment):
|
||||
)
|
||||
|
||||
|
||||
def test_ccache_prepend_for_cc(wrapper_environment):
|
||||
def test_ccache_prepend_for_cc(wrapper_environment, wrapper_dir):
|
||||
cc = wrapper_dir / "cc"
|
||||
with set_env(SPACK_CCACHE_BINARY="ccache"):
|
||||
os.environ["SPACK_SHORT_SPEC"] = "foo@1.2=linux-x86_64"
|
||||
check_args(
|
||||
@ -828,7 +821,8 @@ def test_ccache_prepend_for_cc(wrapper_environment):
|
||||
)
|
||||
|
||||
|
||||
def test_no_ccache_prepend_for_fc(wrapper_environment):
|
||||
def test_no_ccache_prepend_for_fc(wrapper_environment, wrapper_dir):
|
||||
fc = wrapper_dir / "fc"
|
||||
os.environ["SPACK_SHORT_SPEC"] = "foo@1.2=linux-x86_64"
|
||||
check_args(
|
||||
fc,
|
||||
@ -845,7 +839,8 @@ def test_no_ccache_prepend_for_fc(wrapper_environment):
|
||||
)
|
||||
|
||||
|
||||
def test_keep_and_replace(wrapper_environment):
|
||||
def test_keep_and_replace(wrapper_environment, wrapper_dir):
|
||||
cc = wrapper_dir / "cc"
|
||||
werror_specific = ["-Werror=meh"]
|
||||
werror = ["-Werror"]
|
||||
werror_all = werror_specific + werror
|
||||
@ -906,7 +901,8 @@ def test_keep_and_replace(wrapper_environment):
|
||||
],
|
||||
)
|
||||
@pytest.mark.usefixtures("wrapper_environment", "mutable_config")
|
||||
def test_flag_modification(cfg_override, initial, expected, must_be_gone):
|
||||
def test_flag_modification(cfg_override, initial, expected, must_be_gone, wrapper_dir):
|
||||
cc = wrapper_dir / "cc"
|
||||
spack.config.add(cfg_override)
|
||||
env = spack.build_environment.clean_environment()
|
||||
|
||||
@ -917,7 +913,9 @@ def test_flag_modification(cfg_override, initial, expected, must_be_gone):
|
||||
|
||||
|
||||
@pytest.mark.regression("9160")
|
||||
def test_disable_new_dtags(wrapper_environment, wrapper_flags):
|
||||
def test_disable_new_dtags(wrapper_environment, wrapper_flags, wrapper_dir):
|
||||
cc = Executable(str(wrapper_dir / "cc"))
|
||||
ld = Executable(str(wrapper_dir / "ld"))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-args"):
|
||||
result = ld(*test_args, output=str).strip().split("\n")
|
||||
assert "--disable-new-dtags" in result
|
||||
@ -926,7 +924,9 @@ def test_disable_new_dtags(wrapper_environment, wrapper_flags):
|
||||
|
||||
|
||||
@pytest.mark.regression("9160")
|
||||
def test_filter_enable_new_dtags(wrapper_environment, wrapper_flags):
|
||||
def test_filter_enable_new_dtags(wrapper_environment, wrapper_flags, wrapper_dir):
|
||||
cc = Executable(str(wrapper_dir / "cc"))
|
||||
ld = Executable(str(wrapper_dir / "ld"))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-args"):
|
||||
result = ld(*(test_args + ["--enable-new-dtags"]), output=str)
|
||||
result = result.strip().split("\n")
|
||||
@ -938,7 +938,9 @@ def test_filter_enable_new_dtags(wrapper_environment, wrapper_flags):
|
||||
|
||||
|
||||
@pytest.mark.regression("22643")
|
||||
def test_linker_strips_loopopt(wrapper_environment, wrapper_flags):
|
||||
def test_linker_strips_loopopt(wrapper_environment, wrapper_flags, wrapper_dir):
|
||||
cc = Executable(str(wrapper_dir / "cc"))
|
||||
ld = Executable(str(wrapper_dir / "ld"))
|
||||
with set_env(SPACK_TEST_COMMAND="dump-args"):
|
||||
# ensure that -loopopt=0 is not present in ld mode
|
||||
result = ld(*(test_args + ["-loopopt=0"]), output=str)
|
||||
@ -958,7 +960,9 @@ def test_linker_strips_loopopt(wrapper_environment, wrapper_flags):
|
||||
assert "-loopopt=0" in result
|
||||
|
||||
|
||||
def test_spack_managed_dirs_are_prioritized(wrapper_environment):
|
||||
def test_spack_managed_dirs_are_prioritized(wrapper_environment, wrapper_dir):
|
||||
cc = Executable(str(wrapper_dir / "cc"))
|
||||
|
||||
# We have two different stores with 5 packages divided over them
|
||||
pkg1 = "/path/to/spack-1/opt/spack/linux-ubuntu22.04-zen2/gcc-13.2.0/pkg-1.0-abcdef"
|
||||
pkg2 = "/path/to/spack-1/opt/spack/linux-ubuntu22.04-zen2/gcc-13.2.0/pkg-2.0-abcdef"
|
||||
|
@ -344,10 +344,20 @@ def test_get_spec_filter_list(mutable_mock_env_path, mutable_mock_repo):
|
||||
"libelf",
|
||||
"gcc",
|
||||
"gcc-runtime",
|
||||
"compiler-wrapper",
|
||||
}
|
||||
depth_2_set = {"mpich", "callpath", "dyninst", "libdwarf", "libelf", "gcc", "gcc-runtime"}
|
||||
depth_1_set = {"dyninst", "libdwarf", "libelf", "gcc", "gcc-runtime"}
|
||||
depth_0_set = {"libdwarf", "libelf", "gcc", "gcc-runtime"}
|
||||
depth_2_set = {
|
||||
"mpich",
|
||||
"callpath",
|
||||
"dyninst",
|
||||
"libdwarf",
|
||||
"libelf",
|
||||
"gcc",
|
||||
"gcc-runtime",
|
||||
"compiler-wrapper",
|
||||
}
|
||||
depth_1_set = {"dyninst", "libdwarf", "libelf", "gcc", "gcc-runtime", "compiler-wrapper"}
|
||||
depth_0_set = {"libdwarf", "libelf", "gcc", "gcc-runtime", "compiler-wrapper"}
|
||||
|
||||
expectations = {
|
||||
None: full_set,
|
||||
|
@ -223,7 +223,7 @@ def test_load_first(install_mockery, mock_fetch, mock_archive, mock_packages):
|
||||
for dep in ("mpileaks", "callpath", "dyninst", "libelf", "libdwarf", "mpich")
|
||||
)
|
||||
assert all(
|
||||
len([diff for diff in result["intersect"] if diff[0] == attr]) == 7
|
||||
len([diff for diff in result["intersect"] if diff[0] == attr]) == 8
|
||||
for attr in (
|
||||
"version",
|
||||
"node_target",
|
||||
|
@ -170,7 +170,7 @@ def _check_json_output(spec_list):
|
||||
|
||||
|
||||
def _check_json_output_deps(spec_list):
|
||||
assert len(spec_list) == 15
|
||||
assert len(spec_list) == 16
|
||||
|
||||
names = [spec["name"] for spec in spec_list]
|
||||
assert names.count("mpileaks") == 3
|
||||
@ -272,6 +272,7 @@ def test_find_format_deps(database, config):
|
||||
dyninst-8.2
|
||||
libdwarf-20130729
|
||||
libelf-0.8.13
|
||||
compiler-wrapper-1.0
|
||||
gcc-10.2.1
|
||||
gcc-runtime-10.2.1
|
||||
zmpi-1.0
|
||||
@ -293,6 +294,7 @@ def test_find_format_deps_paths(database, config):
|
||||
dyninst-8.2 {mpileaks['dyninst'].prefix}
|
||||
libdwarf-20130729 {mpileaks['libdwarf'].prefix}
|
||||
libelf-0.8.13 {mpileaks['libelf'].prefix}
|
||||
compiler-wrapper-1.0 {mpileaks['compiler-wrapper'].prefix}
|
||||
gcc-10.2.1 {mpileaks['gcc'].prefix}
|
||||
gcc-runtime-10.2.1 {mpileaks['gcc-runtime'].prefix}
|
||||
zmpi-1.0 {mpileaks['zmpi'].prefix}
|
||||
|
@ -61,7 +61,7 @@ def test_install_package_and_dependency(
|
||||
assert filename in files
|
||||
|
||||
content = filename.open().read()
|
||||
assert 'tests="3"' in content
|
||||
assert 'tests="4"' in content
|
||||
assert 'failures="0"' in content
|
||||
assert 'errors="0"' in content
|
||||
|
||||
@ -106,12 +106,12 @@ def test_install_package_already_installed(
|
||||
|
||||
content = filename.open().read()
|
||||
print(content)
|
||||
assert 'tests="4"' in content
|
||||
assert 'tests="5"' in content
|
||||
assert 'failures="0"' in content
|
||||
assert 'errors="0"' in content
|
||||
|
||||
skipped = [line for line in content.split("\n") if "skipped" in line]
|
||||
assert len(skipped) == 4
|
||||
assert len(skipped) == 5
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@ -448,16 +448,16 @@ def just_throw(*args, **kwargs):
|
||||
|
||||
# Only libelf error is reported (through libdwarf root spec). libdwarf
|
||||
# install is skipped and it is not an error.
|
||||
assert 'tests="1"' in content
|
||||
assert 'tests="0"' not in content
|
||||
assert 'failures="0"' in content
|
||||
assert 'errors="1"' in content
|
||||
assert 'errors="0"' not in content
|
||||
|
||||
# Nothing should have succeeded
|
||||
assert 'errors="0"' not in content
|
||||
|
||||
# We want to have both stdout and stderr
|
||||
assert "<system-out>" in content
|
||||
assert 'error message="{0}"'.format(msg) in content
|
||||
assert f'error message="{msg}"' in content
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("noop_install", "mock_packages", "config")
|
||||
|
@ -30,7 +30,7 @@ def test_mark_all_explicit(mutable_database):
|
||||
mark("-e", "-a")
|
||||
gc("-y")
|
||||
all_specs = spack.store.STORE.layout.all_specs()
|
||||
assert len(all_specs) == 16
|
||||
assert len(all_specs) == 17
|
||||
|
||||
|
||||
@pytest.mark.db
|
||||
@ -64,4 +64,4 @@ def test_mark_all_implicit_then_explicit(mutable_database):
|
||||
mark("-e", "-a")
|
||||
gc("-y")
|
||||
all_specs = spack.store.STORE.layout.all_specs()
|
||||
assert len(all_specs) == 16
|
||||
assert len(all_specs) == 17
|
||||
|
@ -90,7 +90,7 @@ def test_recursive_uninstall(mutable_database):
|
||||
|
||||
@pytest.mark.db
|
||||
@pytest.mark.regression("3690")
|
||||
@pytest.mark.parametrize("constraint,expected_number_of_specs", [("dyninst", 9), ("libelf", 7)])
|
||||
@pytest.mark.parametrize("constraint,expected_number_of_specs", [("dyninst", 10), ("libelf", 8)])
|
||||
def test_uninstall_spec_with_multiple_roots(
|
||||
constraint, expected_number_of_specs, mutable_database
|
||||
):
|
||||
@ -100,7 +100,7 @@ def test_uninstall_spec_with_multiple_roots(
|
||||
|
||||
|
||||
@pytest.mark.db
|
||||
@pytest.mark.parametrize("constraint,expected_number_of_specs", [("dyninst", 15), ("libelf", 15)])
|
||||
@pytest.mark.parametrize("constraint,expected_number_of_specs", [("dyninst", 16), ("libelf", 16)])
|
||||
def test_force_uninstall_spec_with_ref_count_not_zero(
|
||||
constraint, expected_number_of_specs, mutable_database
|
||||
):
|
||||
@ -170,7 +170,7 @@ def db_specs():
|
||||
|
||||
all_specs, mpileaks_specs, callpath_specs, mpi_specs = db_specs()
|
||||
total_specs = len(all_specs)
|
||||
assert total_specs == 15
|
||||
assert total_specs == 16
|
||||
assert len(mpileaks_specs) == 3
|
||||
assert len(callpath_specs) == 2
|
||||
assert len(mpi_specs) == 3
|
||||
|
@ -466,7 +466,7 @@ def test_architecture_deep_inheritance(self, mock_targets, compiler_factory):
|
||||
with spack.config.override("packages", {"gcc": {"externals": [cnl_compiler]}}):
|
||||
spec_str = "mpileaks %gcc@4.5.0 os=CNL target=nocona ^dyninst os=CNL ^callpath os=CNL"
|
||||
spec = spack.concretize.concretize_one(spec_str)
|
||||
for s in spec.traverse(root=False):
|
||||
for s in spec.traverse(root=False, deptype=("link", "run")):
|
||||
assert s.architecture.target == spec.architecture.target
|
||||
|
||||
def test_compiler_flags_from_user_are_grouped(self):
|
||||
@ -1991,17 +1991,17 @@ def test_installed_specs_disregard_conflicts(self, mutable_database, monkeypatch
|
||||
assert s.satisfies("~debug"), s
|
||||
|
||||
@pytest.mark.regression("32471")
|
||||
def test_require_targets_are_allowed(self, mutable_database):
|
||||
def test_require_targets_are_allowed(self, mutable_config, mutable_database):
|
||||
"""Test that users can set target constraints under the require attribute."""
|
||||
# Configuration to be added to packages.yaml
|
||||
required_target = archspec.cpu.TARGETS[spack.platforms.test.Test.default].family
|
||||
external_conf = {"all": {"require": f"target={required_target}"}}
|
||||
spack.config.set("packages", external_conf)
|
||||
mutable_config.set("packages", external_conf)
|
||||
|
||||
with spack.config.override("concretizer:reuse", False):
|
||||
spec = spack.concretize.concretize_one("mpich")
|
||||
|
||||
for s in spec.traverse():
|
||||
for s in spec.traverse(deptype=("link", "run")):
|
||||
assert s.satisfies(f"target={required_target}")
|
||||
|
||||
def test_external_python_extensions_have_dependency(self):
|
||||
@ -2994,7 +2994,7 @@ def test_filtering_reused_specs(
|
||||
@pytest.mark.usefixtures("mutable_database", "mock_store")
|
||||
@pytest.mark.parametrize(
|
||||
"reuse_yaml,expected_length",
|
||||
[({"from": [{"type": "local"}]}, 19), ({"from": [{"type": "buildcache"}]}, 0)],
|
||||
[({"from": [{"type": "local"}]}, 20), ({"from": [{"type": "buildcache"}]}, 0)],
|
||||
)
|
||||
@pytest.mark.not_on_windows("Expected length is different on Windows")
|
||||
def test_selecting_reused_sources(
|
||||
|
@ -2154,3 +2154,12 @@ def info(self):
|
||||
@pytest.fixture()
|
||||
def mock_runtimes(config, mock_packages):
|
||||
return mock_packages.packages_with_tags("runtime")
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def wrapper_dir(install_mockery):
|
||||
"""Installs the compiler wrapper and returns the prefix where the script is installed."""
|
||||
wrapper = spack.spec.Spec("compiler-wrapper").concretized()
|
||||
wrapper_pkg = wrapper.package
|
||||
PackageInstaller([wrapper_pkg], explicit=True).install()
|
||||
return wrapper_pkg.bin_dir()
|
||||
|
@ -95,11 +95,11 @@ def upstream_and_downstream_db(tmpdir, gen_mock_layout):
|
||||
@pytest.mark.parametrize(
|
||||
"install_tree,result",
|
||||
[
|
||||
("all", ["pkg-b", "pkg-c", "gcc-runtime", "gcc"]),
|
||||
("all", ["pkg-b", "pkg-c", "gcc-runtime", "gcc", "compiler-wrapper"]),
|
||||
("upstream", ["pkg-c"]),
|
||||
("local", ["pkg-b", "gcc-runtime", "gcc"]),
|
||||
("local", ["pkg-b", "gcc-runtime", "gcc", "compiler-wrapper"]),
|
||||
("{u}", ["pkg-c"]),
|
||||
("{d}", ["pkg-b", "gcc-runtime", "gcc"]),
|
||||
("{d}", ["pkg-b", "gcc-runtime", "gcc", "compiler-wrapper"]),
|
||||
],
|
||||
ids=["all", "upstream", "local", "upstream_path", "downstream_path"],
|
||||
)
|
||||
@ -491,7 +491,7 @@ def test_005_db_exists(database):
|
||||
def test_010_all_install_sanity(database):
|
||||
"""Ensure that the install layout reflects what we think it does."""
|
||||
all_specs = spack.store.STORE.layout.all_specs()
|
||||
assert len(all_specs) == 16
|
||||
assert len(all_specs) == 17
|
||||
|
||||
# Query specs with multiple configurations
|
||||
mpileaks_specs = [s for s in all_specs if s.satisfies("mpileaks")]
|
||||
@ -608,7 +608,7 @@ def test_050_basic_query(database):
|
||||
"""Ensure querying database is consistent with what is installed."""
|
||||
# query everything
|
||||
total_specs = len(spack.store.STORE.db.query())
|
||||
assert total_specs == 19
|
||||
assert total_specs == 20
|
||||
|
||||
# query specs with multiple configurations
|
||||
mpileaks_specs = database.query("mpileaks")
|
||||
@ -827,11 +827,11 @@ def check_unused(roots, deptype, expected):
|
||||
assert set(u.name for u in unused) == set(expected)
|
||||
|
||||
default_dt = dt.LINK | dt.RUN
|
||||
check_unused(None, default_dt, ["cmake", "gcc"])
|
||||
check_unused(None, default_dt, ["cmake", "gcc", "compiler-wrapper"])
|
||||
check_unused(
|
||||
[si, ml_mpich, ml_mpich2, ml_zmpi, externaltest],
|
||||
default_dt,
|
||||
["trivial-smoke-test", "cmake", "gcc"],
|
||||
["trivial-smoke-test", "cmake", "gcc", "compiler-wrapper"],
|
||||
)
|
||||
check_unused(
|
||||
[si, ml_mpich, ml_mpich2, ml_zmpi, externaltest],
|
||||
@ -846,7 +846,15 @@ def check_unused(roots, deptype, expected):
|
||||
check_unused(
|
||||
[si, ml_mpich, ml_mpich2, ml_zmpi],
|
||||
default_dt,
|
||||
["trivial-smoke-test", "cmake", "externaltest", "externaltool", "externalvirtual", "gcc"],
|
||||
[
|
||||
"trivial-smoke-test",
|
||||
"cmake",
|
||||
"externaltest",
|
||||
"externaltool",
|
||||
"externalvirtual",
|
||||
"gcc",
|
||||
"compiler-wrapper",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@ -1080,7 +1088,7 @@ def test_check_parents(spec_str, parent_name, expected_nparents, database):
|
||||
def test_db_all_hashes(database):
|
||||
# ensure we get the right number of hashes without a read transaction
|
||||
hashes = database.all_hashes()
|
||||
assert len(hashes) == 19
|
||||
assert len(hashes) == 20
|
||||
|
||||
# and make sure the hashes match
|
||||
with database.read_transaction():
|
||||
|
@ -54,25 +54,34 @@ def test_ascii_graph_mpileaks(config, mock_packages, monkeypatch):
|
||||
|\
|
||||
| |\
|
||||
| | |\
|
||||
| | | o callpath
|
||||
| |_|/|
|
||||
|/| |/|
|
||||
| |/|/|
|
||||
o | | | mpich
|
||||
|\| | |
|
||||
| |/ /
|
||||
|/| |
|
||||
| | o dyninst
|
||||
| |/|
|
||||
|/|/|
|
||||
| | |\
|
||||
| | | o libdwarf
|
||||
| | | |\
|
||||
| | | | o callpath
|
||||
| |_|_|/|
|
||||
|/| |_|/|
|
||||
| |/| |/|
|
||||
| | |/|/|
|
||||
| | | | o dyninst
|
||||
| | |_|/|
|
||||
| |/| |/|
|
||||
| | |/|/|
|
||||
| | | | |\
|
||||
o | | | | | mpich
|
||||
|\| | | | |
|
||||
|\ \ \ \ \ \
|
||||
| |_|/ / / /
|
||||
|/| | | | |
|
||||
| |/ / / /
|
||||
| | | | o libdwarf
|
||||
| |_|_|/|
|
||||
|/| |_|/|
|
||||
| |/| |/|
|
||||
| | |/|/
|
||||
| | | o libelf
|
||||
| |_|/|
|
||||
|/| |/|
|
||||
| |/|/
|
||||
| | o libelf
|
||||
| |/|
|
||||
|/|/
|
||||
| o | compiler-wrapper
|
||||
| /
|
||||
| o gcc-runtime
|
||||
|/
|
||||
o gcc
|
||||
|
@ -1022,7 +1022,7 @@ def test_install_fail_fast_on_detect(install_mockery, monkeypatch, capsys):
|
||||
b, c = spack.concretize.concretize_one("pkg-b"), spack.concretize.concretize_one("pkg-c")
|
||||
b_id, c_id = inst.package_id(b), inst.package_id(c)
|
||||
|
||||
installer = create_installer([b, c], {"fail_fast": True})
|
||||
installer = create_installer([c, b], {"fail_fast": True})
|
||||
|
||||
# Make sure all packages are identified as failed
|
||||
# This will prevent b from installing, which will cause the build of c to be skipped.
|
||||
@ -1031,7 +1031,7 @@ def test_install_fail_fast_on_detect(install_mockery, monkeypatch, capsys):
|
||||
with pytest.raises(spack.error.InstallError, match="after first install failure"):
|
||||
installer.install()
|
||||
|
||||
assert c_id in installer.failed, "Expected b to be marked as failed"
|
||||
assert c_id in installer.failed
|
||||
assert b_id not in installer.failed, "Expected no attempt to install pkg-c"
|
||||
assert f"{c_id} failed to install" in capsys.readouterr().err
|
||||
|
||||
|
@ -15,12 +15,15 @@
|
||||
|
||||
import pytest
|
||||
|
||||
import spack
|
||||
import spack.binary_distribution
|
||||
import spack.database
|
||||
import spack.deptypes as dt
|
||||
import spack.environment as ev
|
||||
import spack.error
|
||||
import spack.oci.opener
|
||||
import spack.spec
|
||||
import spack.traverse
|
||||
from spack.main import SpackCommand
|
||||
from spack.oci.image import Digest, ImageReference, default_config, default_manifest
|
||||
from spack.oci.oci import blob_exists, get_manifest_and_config, upload_blob, upload_manifest
|
||||
@ -82,7 +85,13 @@ def test_buildcache_tag(install_mockery, mock_fetch, mutable_mock_env_path):
|
||||
name = ImageReference.from_string("example.com/image:full_env")
|
||||
|
||||
with ev.read("test") as e:
|
||||
specs = [x for x in e.all_specs() if not x.external]
|
||||
specs = [
|
||||
x
|
||||
for x in spack.traverse.traverse_nodes(
|
||||
e.concrete_roots(), deptype=dt.LINK | dt.RUN
|
||||
)
|
||||
if not x.external
|
||||
]
|
||||
|
||||
manifest, config = get_manifest_and_config(name)
|
||||
|
||||
@ -99,7 +108,9 @@ def test_buildcache_tag(install_mockery, mock_fetch, mutable_mock_env_path):
|
||||
|
||||
name = ImageReference.from_string("example.com/image:single_spec")
|
||||
manifest, config = get_manifest_and_config(name)
|
||||
assert len(manifest["layers"]) == len([x for x in libelf.traverse() if not x.external])
|
||||
assert len(manifest["layers"]) == len(
|
||||
[x for x in libelf.traverse(deptype=dt.LINK | dt.RUN) if not x.external]
|
||||
)
|
||||
|
||||
|
||||
def test_buildcache_push_with_base_image_command(mutable_database, tmpdir):
|
||||
|
@ -184,6 +184,7 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
[
|
||||
(0, "mpileaks"),
|
||||
(1, "callpath"),
|
||||
(2, "compiler-wrapper"),
|
||||
(2, "dyninst"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
@ -199,23 +200,29 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
[
|
||||
(0, "mpileaks"),
|
||||
(1, "callpath"),
|
||||
(2, "compiler-wrapper"),
|
||||
(2, "dyninst"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(4, "gcc"),
|
||||
(3, "libdwarf"),
|
||||
(4, "compiler-wrapper"),
|
||||
(4, "gcc"),
|
||||
(4, "gcc-runtime"),
|
||||
(4, "libelf"),
|
||||
(5, "compiler-wrapper"),
|
||||
(5, "gcc"),
|
||||
(5, "gcc-runtime"),
|
||||
(3, "libelf"),
|
||||
(2, "gcc"),
|
||||
(2, "gcc-runtime"),
|
||||
(2, "zmpi"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "fake"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(1, "compiler-wrapper"),
|
||||
(1, "gcc"),
|
||||
(1, "gcc-runtime"),
|
||||
(1, "zmpi"),
|
||||
@ -227,19 +234,24 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
[
|
||||
(0, "mpileaks"),
|
||||
(1, "callpath"),
|
||||
(2, "compiler-wrapper"),
|
||||
(2, "dyninst"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(4, "gcc"),
|
||||
(3, "libdwarf"),
|
||||
(4, "compiler-wrapper"),
|
||||
(4, "gcc"),
|
||||
(4, "gcc-runtime"),
|
||||
(5, "gcc"),
|
||||
(4, "libelf"),
|
||||
(5, "compiler-wrapper"),
|
||||
(5, "gcc"),
|
||||
(5, "gcc-runtime"),
|
||||
(6, "gcc"),
|
||||
(3, "libelf"),
|
||||
(4, "compiler-wrapper"),
|
||||
(4, "gcc"),
|
||||
(4, "gcc-runtime"),
|
||||
(5, "gcc"),
|
||||
@ -247,14 +259,17 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
(2, "gcc-runtime"),
|
||||
(3, "gcc"),
|
||||
(2, "zmpi"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "fake"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(4, "gcc"),
|
||||
(1, "compiler-wrapper"),
|
||||
(1, "gcc"),
|
||||
(1, "gcc-runtime"),
|
||||
(2, "gcc"),
|
||||
(1, "zmpi"),
|
||||
(2, "compiler-wrapper"),
|
||||
(2, "fake"),
|
||||
(2, "gcc"),
|
||||
(2, "gcc-runtime"),
|
||||
@ -265,6 +280,7 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
# Postorder node traversal
|
||||
(
|
||||
[
|
||||
(2, "compiler-wrapper"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(4, "libelf"),
|
||||
@ -280,11 +296,15 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
# Postorder edge traversal
|
||||
(
|
||||
[
|
||||
(2, "compiler-wrapper"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "gcc"),
|
||||
(4, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(4, "compiler-wrapper"),
|
||||
(4, "gcc"),
|
||||
(4, "gcc-runtime"),
|
||||
(5, "compiler-wrapper"),
|
||||
(5, "gcc"),
|
||||
(5, "gcc-runtime"),
|
||||
(4, "libelf"),
|
||||
@ -293,11 +313,13 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
(2, "dyninst"),
|
||||
(2, "gcc"),
|
||||
(2, "gcc-runtime"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "fake"),
|
||||
(3, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(2, "zmpi"),
|
||||
(1, "callpath"),
|
||||
(1, "compiler-wrapper"),
|
||||
(1, "gcc"),
|
||||
(1, "gcc-runtime"),
|
||||
(1, "zmpi"),
|
||||
@ -308,17 +330,22 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
# Postorder path traversal
|
||||
(
|
||||
[
|
||||
(2, "compiler-wrapper"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "gcc"),
|
||||
(4, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(4, "compiler-wrapper"),
|
||||
(4, "gcc"),
|
||||
(5, "gcc"),
|
||||
(4, "gcc-runtime"),
|
||||
(5, "compiler-wrapper"),
|
||||
(5, "gcc"),
|
||||
(6, "gcc"),
|
||||
(5, "gcc-runtime"),
|
||||
(4, "libelf"),
|
||||
(3, "libdwarf"),
|
||||
(4, "compiler-wrapper"),
|
||||
(4, "gcc"),
|
||||
(5, "gcc"),
|
||||
(4, "gcc-runtime"),
|
||||
@ -327,15 +354,18 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
(2, "gcc"),
|
||||
(3, "gcc"),
|
||||
(2, "gcc-runtime"),
|
||||
(3, "compiler-wrapper"),
|
||||
(3, "fake"),
|
||||
(3, "gcc"),
|
||||
(4, "gcc"),
|
||||
(3, "gcc-runtime"),
|
||||
(2, "zmpi"),
|
||||
(1, "callpath"),
|
||||
(1, "compiler-wrapper"),
|
||||
(1, "gcc"),
|
||||
(2, "gcc"),
|
||||
(1, "gcc-runtime"),
|
||||
(2, "compiler-wrapper"),
|
||||
(2, "fake"),
|
||||
(2, "gcc"),
|
||||
(3, "gcc"),
|
||||
@ -350,47 +380,53 @@ def test_conflicting_package_constraints(self, set_dependency):
|
||||
def test_traversal(self, pairs, traverse_kwargs, default_mock_concretization):
|
||||
r"""Tests different traversals of the following graph
|
||||
|
||||
o mpileaks
|
||||
o mpileaks@2.3/3qeg7jx
|
||||
|\
|
||||
| |\
|
||||
| | |\
|
||||
| | | |\
|
||||
| | | | o callpath
|
||||
| |_|_|/|
|
||||
|/| |_|/|
|
||||
| |/| |/|
|
||||
| | |/|/|
|
||||
o | | | | zmpi
|
||||
|\| | | |
|
||||
|\ \ \ \ \
|
||||
| |_|/ / /
|
||||
|/| | | |
|
||||
| |\ \ \ \
|
||||
| | |_|/ /
|
||||
| |/| | |
|
||||
| | o | | fake
|
||||
| | / /
|
||||
| | | o dyninst
|
||||
| |_|/|
|
||||
|/| |/|
|
||||
| |/|/|
|
||||
| | | |\
|
||||
| | | | o libdwarf
|
||||
| | | | |\
|
||||
| | | | | o callpath@1.0/4gilijr
|
||||
| |_|_|_|/|
|
||||
|/| |_|_|/|
|
||||
| |/| |_|/|
|
||||
| | |/| |/|
|
||||
| | | |/|/|
|
||||
| | | | | o dyninst@8.2/u4oymb3
|
||||
| | |_|_|/|
|
||||
| |/| |_|/|
|
||||
| | |/| |/|
|
||||
| | | |/|/|
|
||||
| | | | | |\
|
||||
o | | | | | | mpich@3.0.4/g734fu6
|
||||
|\| | | | | |
|
||||
|\ \ \ \ \ \ \
|
||||
| |_|/ / / / /
|
||||
|/| | | | | |
|
||||
| |\ \ \ \ \ \
|
||||
| | |_|/ / / /
|
||||
| |/| | | | |
|
||||
| | |/ / / /
|
||||
| | | | | o libdwarf@20130729/q5r7l2r
|
||||
| |_|_|_|/|
|
||||
|/| |_|_|/|
|
||||
| |/| |_|/|
|
||||
| | |/| |/|
|
||||
| | | |/|/
|
||||
| | | | o libelf@0.8.13/i2x6pya
|
||||
| |_|_|/|
|
||||
|/| |_|/|
|
||||
| |/| |/|
|
||||
| | |/|/
|
||||
| | | o libel
|
||||
| |_|/|
|
||||
|/| |/|
|
||||
| |/|/
|
||||
o | | gcc-runtime
|
||||
| | o | compiler-wrapper@1.0/njdili2
|
||||
| | /
|
||||
o | | gcc-runtime@10.5.0/iyytqeo
|
||||
|\| |
|
||||
| |/
|
||||
|/|
|
||||
o | glibc
|
||||
/
|
||||
o gcc
|
||||
| o gcc@10.5.0/ljeisd4
|
||||
|
|
||||
o glibc@2.31/tbyn33w
|
||||
"""
|
||||
dag = default_mock_concretization("mpileaks ^zmpi")
|
||||
names = [x for _, x in pairs]
|
||||
@ -843,10 +879,10 @@ def test_spec_tree_respect_deptypes(self):
|
||||
"query,expected_length,expected_satisfies",
|
||||
[
|
||||
({"virtuals": ["mpi"]}, 1, ["mpich", "mpi"]),
|
||||
({"depflag": dt.BUILD}, 3, ["mpich", "mpi", "callpath"]),
|
||||
({"depflag": dt.BUILD}, 4, ["mpich", "mpi", "callpath"]),
|
||||
({"depflag": dt.BUILD, "virtuals": ["mpi"]}, 1, ["mpich", "mpi"]),
|
||||
({"depflag": dt.LINK}, 3, ["mpich", "mpi", "callpath"]),
|
||||
({"depflag": dt.BUILD | dt.LINK}, 4, ["mpich", "mpi", "callpath"]),
|
||||
({"depflag": dt.BUILD | dt.LINK}, 5, ["mpich", "mpi", "callpath"]),
|
||||
({"virtuals": ["lapack"]}, 0, []),
|
||||
],
|
||||
)
|
||||
@ -928,7 +964,7 @@ def test_synthetic_construction_of_split_dependencies_from_same_package(mock_pac
|
||||
root.add_dependency_edge(build_spec, depflag=dt.BUILD, virtuals=())
|
||||
|
||||
# Check dependencies from the perspective of root
|
||||
assert len(root.dependencies()) == 4
|
||||
assert len(root.dependencies()) == 5
|
||||
assert len([x for x in root.dependencies() if x.name == "pkg-c"]) == 2
|
||||
|
||||
assert "@2.0" in root.dependencies(name="pkg-c", deptype=dt.BUILD)[0]
|
||||
|
@ -1697,6 +1697,7 @@ def test_spec_trim(mock_packages, config):
|
||||
top.trim("dt-diamond-left")
|
||||
remaining = {x.name for x in top.traverse()}
|
||||
assert {
|
||||
"compiler-wrapper",
|
||||
"dt-diamond",
|
||||
"dt-diamond-right",
|
||||
"dt-diamond-bottom",
|
||||
@ -1706,7 +1707,7 @@ def test_spec_trim(mock_packages, config):
|
||||
|
||||
top.trim("dt-diamond-right")
|
||||
remaining = {x.name for x in top.traverse()}
|
||||
assert {"dt-diamond", "gcc-runtime", "gcc"} == remaining
|
||||
assert {"compiler-wrapper", "dt-diamond", "gcc-runtime", "gcc"} == remaining
|
||||
|
||||
|
||||
@pytest.mark.regression("30861")
|
||||
|
@ -30,7 +30,6 @@ if [[ "$COVERAGE" == "true" ]]; then
|
||||
bashcov=$(realpath ${QA_DIR}/bashcov)
|
||||
|
||||
# instrument scripts requiring shell coverage
|
||||
sed -i "s@#\!/bin/bash@#\!${bashcov}@" "$SPACK_ROOT/lib/spack/env/cc"
|
||||
if [ "$(uname -o)" != "Darwin" ]; then
|
||||
# On darwin, #! interpreters must be binaries, so no sbang for bashcov
|
||||
sed -i "s@#\!/bin/sh@#\!${bashcov}@" "$SPACK_ROOT/bin/sbang"
|
||||
|
1
var/spack/repos/builtin.mock/packages/compiler-wrapper
Symbolic link
1
var/spack/repos/builtin.mock/packages/compiler-wrapper
Symbolic link
@ -0,0 +1 @@
|
||||
../../builtin/packages/compiler-wrapper/
|
@ -39,7 +39,6 @@ readonly params="\
|
||||
SPACK_ENV_PATH
|
||||
SPACK_DEBUG_LOG_DIR
|
||||
SPACK_DEBUG_LOG_ID
|
||||
SPACK_LINKER_ARG
|
||||
SPACK_SHORT_SPEC
|
||||
SPACK_SYSTEM_DIRS
|
||||
SPACK_MANAGED_DIRS"
|
||||
@ -397,7 +396,9 @@ fi
|
||||
#
|
||||
dtags_to_add="${SPACK_DTAGS_TO_ADD}"
|
||||
dtags_to_strip="${SPACK_DTAGS_TO_STRIP}"
|
||||
linker_arg="${SPACK_LINKER_ARG}"
|
||||
|
||||
linker_arg="ERROR: LINKER ARG WAS NOT SET, MAYBE THE PACKAGE DOES NOT DEPEND ON ${comp}?"
|
||||
eval "linker_arg=\${SPACK_${comp}_LINKER_ARG:?${linker_arg}}"
|
||||
|
||||
# Set up rpath variable according to language.
|
||||
rpath="ERROR: RPATH ARG WAS NOT SET, MAYBE THE PACKAGE DOES NOT DEPEND ON ${comp}?"
|
245
var/spack/repos/builtin/packages/compiler-wrapper/package.py
Normal file
245
var/spack/repos/builtin/packages/compiler-wrapper/package.py
Normal file
@ -0,0 +1,245 @@
|
||||
# Copyright Spack Project Developers. See COPYRIGHT file for details.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
import pathlib
|
||||
import shutil
|
||||
from typing import List
|
||||
|
||||
import archspec.cpu
|
||||
|
||||
from llnl.util import lang
|
||||
|
||||
import spack.compilers.libraries
|
||||
import spack.config
|
||||
import spack.package_base
|
||||
from spack.package import *
|
||||
|
||||
|
||||
class CompilerWrapper(Package):
|
||||
"""Spack compiler wrapper script.
|
||||
|
||||
Compiler commands go through this compiler wrapper in Spack builds.
|
||||
The compiler wrapper is a thin layer around the standard compilers.
|
||||
It enables several key pieces of functionality:
|
||||
|
||||
1. It allows Spack to swap compilers into and out of builds easily.
|
||||
2. It adds several options to the compile line so that spack
|
||||
packages can find their dependencies at build time and run time:
|
||||
-I and/or -isystem arguments for dependency /include directories.
|
||||
-L arguments for dependency /lib directories.
|
||||
-Wl,-rpath arguments for dependency /lib directories.
|
||||
"""
|
||||
|
||||
homepage = "https://github.com/spack/spack"
|
||||
url = f"file:///{pathlib.PurePath(__file__).parent}/cc.sh"
|
||||
|
||||
# FIXME (compiler as nodes): use a different tag, since this is only to exclude
|
||||
# this node from auto-generated rules
|
||||
tags = ["runtime"]
|
||||
|
||||
license("Apache-2.0 OR MIT")
|
||||
|
||||
version(
|
||||
"1.0",
|
||||
sha256="92924570efbc0f388bbbeb87188e05537008bc25069529f7b519b4e48d7ddfb6",
|
||||
expand=False,
|
||||
)
|
||||
|
||||
conflicts("platform=windows")
|
||||
|
||||
def bin_dir(self) -> pathlib.Path:
|
||||
# This adds an extra "spack" subdir, so that the script and symlinks don't get
|
||||
# their way to the default view /bin directory in environment
|
||||
return pathlib.Path(str(self.prefix)) / "spack" / "bin"
|
||||
|
||||
def install(self, spec, prefix):
|
||||
cc_script = pathlib.Path(self.stage.source_path) / "cc.sh"
|
||||
bin_dir = self.bin_dir()
|
||||
|
||||
# Copy the script
|
||||
bin_dir.mkdir(parents=True)
|
||||
installed_script = bin_dir / "cc"
|
||||
shutil.copy(cc_script, str(installed_script))
|
||||
set_executable(installed_script)
|
||||
|
||||
# Create links to use the script under different names
|
||||
for name in (
|
||||
"ld.lld",
|
||||
"ld.gold",
|
||||
"ld",
|
||||
"ftn",
|
||||
"fc",
|
||||
"f95",
|
||||
"f90",
|
||||
"f77",
|
||||
"cpp",
|
||||
"c99",
|
||||
"c89",
|
||||
"c++",
|
||||
):
|
||||
(bin_dir / name).symlink_to(installed_script)
|
||||
|
||||
for subdir, name in (
|
||||
("aocc", "clang"),
|
||||
("aocc", "clang++"),
|
||||
("aocc", "flang"),
|
||||
("arm", "armclang"),
|
||||
("arm", "armclang++"),
|
||||
("arm", "armflang"),
|
||||
("case-insensitive", "CC"),
|
||||
("cce", "cc"),
|
||||
("cce", "craycc"),
|
||||
("cce", "crayftn"),
|
||||
("cce", "ftn"),
|
||||
("clang", "clang"),
|
||||
("clang", "clang++"),
|
||||
("clang", "flang"),
|
||||
("fj", "fcc"),
|
||||
("fj", "frt"),
|
||||
("gcc", "gcc"),
|
||||
("gcc", "g++"),
|
||||
("gcc", "gfortran"),
|
||||
("intel", "icc"),
|
||||
("intel", "icpc"),
|
||||
("intel", "ifort"),
|
||||
("nag", "nagfor"),
|
||||
("nvhpc", "nvc"),
|
||||
("nvhpc", "nvc++"),
|
||||
("nvhpc", "nvfortran"),
|
||||
("oneapi", "icx"),
|
||||
("oneapi", "icpx"),
|
||||
("oneapi", "ifx"),
|
||||
("rocmcc", "amdclang"),
|
||||
("rocmcc", "amdclang++"),
|
||||
("rocmcc", "amdflang"),
|
||||
("xl", "xlc"),
|
||||
("xl", "xlc++"),
|
||||
("xl", "xlf"),
|
||||
("xl", "xlf90"),
|
||||
("xl_r", "xlc_r"),
|
||||
("xl_r", "xlc++_r"),
|
||||
("xl_r", "xlf_r"),
|
||||
("xl_r", "xlf90_r"),
|
||||
):
|
||||
(bin_dir / subdir).mkdir(exist_ok=True)
|
||||
(bin_dir / subdir / name).symlink_to(installed_script)
|
||||
|
||||
def setup_dependent_build_environment(self, env, dependent_spec):
|
||||
_var_list = []
|
||||
if dependent_spec.dependencies(virtuals=("c",)):
|
||||
_var_list.append(("c", "cc", "CC", "SPACK_CC"))
|
||||
|
||||
if dependent_spec.dependencies(virtuals=("cxx",)):
|
||||
_var_list.append(("cxx", "cxx", "CXX", "SPACK_CXX"))
|
||||
|
||||
if dependent_spec.dependencies(virtuals=("fortran",)):
|
||||
_var_list.append(("fortran", "fortran", "F77", "SPACK_F77"))
|
||||
_var_list.append(("fortran", "fortran", "FC", "SPACK_FC"))
|
||||
|
||||
# The package is not used as a compiler, so skip this setup
|
||||
if not _var_list:
|
||||
return
|
||||
|
||||
bin_dir = self.bin_dir()
|
||||
implicit_rpaths, env_paths = [], []
|
||||
for language, attr_name, wrapper_var_name, spack_var_name in _var_list:
|
||||
compiler_pkg = dependent_spec[language].package
|
||||
if not hasattr(compiler_pkg, attr_name):
|
||||
continue
|
||||
|
||||
compiler = getattr(compiler_pkg, attr_name)
|
||||
env.set(spack_var_name, compiler)
|
||||
|
||||
if language not in compiler_pkg.link_paths:
|
||||
continue
|
||||
|
||||
wrapper_path = bin_dir / compiler_pkg.link_paths.get(language)
|
||||
|
||||
env.set(wrapper_var_name, str(wrapper_path))
|
||||
env.set(f"SPACK_{wrapper_var_name}_RPATH_ARG", compiler_pkg.rpath_arg)
|
||||
|
||||
uarch = dependent_spec.architecture.target
|
||||
version_number, _ = archspec.cpu.version_components(
|
||||
compiler_pkg.spec.version.dotted_numeric_string
|
||||
)
|
||||
try:
|
||||
isa_arg = uarch.optimization_flags(compiler_pkg.archspec_name(), version_number)
|
||||
except (ValueError, archspec.cpu.UnsupportedMicroarchitecture):
|
||||
isa_arg = ""
|
||||
|
||||
if isa_arg:
|
||||
env.set(f"SPACK_TARGET_ARGS_{attr_name.upper()}", isa_arg)
|
||||
|
||||
# Add spack build environment path with compiler wrappers first in
|
||||
# the path. We add the compiler wrapper path, which includes default
|
||||
# wrappers (cc, c++, f77, f90), AND a subdirectory containing
|
||||
# compiler-specific symlinks. The latter ensures that builds that
|
||||
# are sensitive to the *name* of the compiler see the right name when
|
||||
# we're building with the wrappers.
|
||||
#
|
||||
# Conflicts on case-insensitive systems (like "CC" and "cc") are
|
||||
# handled by putting one in the <bin_dir>/case-insensitive
|
||||
# directory. Add that to the path too.
|
||||
compiler_specific_dir = (bin_dir / compiler_pkg.link_paths[language]).parent
|
||||
|
||||
for item in [bin_dir, compiler_specific_dir]:
|
||||
env_paths.append(item)
|
||||
ci = item / "case-insensitive"
|
||||
if ci.is_dir():
|
||||
env_paths.append(ci)
|
||||
|
||||
env.set(f"SPACK_{wrapper_var_name}_LINKER_ARG", compiler_pkg.linker_arg)
|
||||
|
||||
# Check if this compiler has implicit rpaths
|
||||
implicit_rpaths.extend(_implicit_rpaths(pkg=compiler_pkg))
|
||||
|
||||
if implicit_rpaths:
|
||||
# Implicit rpaths are accumulated across all compilers so, whenever they are mixed,
|
||||
# the compiler used in ccld mode will account for rpaths from other compilers too.
|
||||
implicit_rpaths = lang.dedupe(implicit_rpaths)
|
||||
env.set("SPACK_COMPILER_IMPLICIT_RPATHS", ":".join(implicit_rpaths))
|
||||
|
||||
# Check whether we want to force RPATH or RUNPATH
|
||||
if spack.config.CONFIG.get("config:shared_linking:type") == "rpath":
|
||||
env.set("SPACK_DTAGS_TO_STRIP", self.enable_new_dtags)
|
||||
env.set("SPACK_DTAGS_TO_ADD", self.disable_new_dtags)
|
||||
else:
|
||||
env.set("SPACK_DTAGS_TO_STRIP", self.disable_new_dtags)
|
||||
env.set("SPACK_DTAGS_TO_ADD", self.enable_new_dtags)
|
||||
|
||||
for item in env_paths:
|
||||
env.prepend_path("SPACK_ENV_PATH", item)
|
||||
|
||||
def setup_dependent_package(self, module, dependent_spec):
|
||||
bin_dir = self.bin_dir()
|
||||
|
||||
if dependent_spec.dependencies(virtuals=("c",)):
|
||||
compiler_pkg = dependent_spec["c"].package
|
||||
setattr(module, "spack_cc", str(bin_dir / compiler_pkg.link_paths["c"]))
|
||||
|
||||
if dependent_spec.dependencies(virtuals=("cxx",)):
|
||||
compiler_pkg = dependent_spec["cxx"].package
|
||||
setattr(module, "spack_cxx", str(bin_dir / compiler_pkg.link_paths["cxx"]))
|
||||
|
||||
if dependent_spec.dependencies(virtuals=("fortran",)):
|
||||
compiler_pkg = dependent_spec["fortran"].package
|
||||
setattr(module, "spack_fc", str(bin_dir / compiler_pkg.link_paths["fortran"]))
|
||||
setattr(module, "spack_f77", str(bin_dir / compiler_pkg.link_paths["fortran"]))
|
||||
|
||||
@property
|
||||
def disable_new_dtags(self) -> str:
|
||||
if self.spec.satisfies("platform=darwin"):
|
||||
return ""
|
||||
return "--disable-new-dtags"
|
||||
|
||||
@property
|
||||
def enable_new_dtags(self) -> str:
|
||||
if self.spec.satisfies("platform=darwin"):
|
||||
return ""
|
||||
return "--enable-new-dtags"
|
||||
|
||||
|
||||
def _implicit_rpaths(pkg: spack.package_base.PackageBase) -> List[str]:
|
||||
detector = spack.compilers.libraries.CompilerPropertyDetector(pkg.spec)
|
||||
paths = detector.implicit_rpaths()
|
||||
return paths
|
@ -32,7 +32,6 @@ def install(self, spec, prefix):
|
||||
compiler_version_argument = ""
|
||||
compiler_version_regex = r"([1-9][0-9]*\.[0-9]*\.[0-9]*)"
|
||||
|
||||
# Named wrapper links within build_env_path
|
||||
# Due to the challenges of supporting compiler wrappers
|
||||
# in Windows, we leave these blank, and dynamically compute
|
||||
# based on proper versions of MSVC from there
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
from llnl.util.lang import dedupe
|
||||
|
||||
import spack.paths
|
||||
from spack.build_environment import dso_suffix, stat_suffix
|
||||
from spack.package import *
|
||||
|
||||
@ -1269,6 +1268,9 @@ def setup_dependent_build_environment(self, env, dependent_spec):
|
||||
"""Set PYTHONPATH to include the site-packages directory for the
|
||||
extension and any other python extensions it depends on.
|
||||
"""
|
||||
if sys.platform == "win32":
|
||||
return
|
||||
|
||||
# We need to make sure that the extensions are compiled and linked with
|
||||
# the Spack wrapper. Paths to the executables that are used for these
|
||||
# operations are normally taken from the sysconfigdata file, which we
|
||||
@ -1295,15 +1297,16 @@ def setup_dependent_build_environment(self, env, dependent_spec):
|
||||
if not dependent_spec.dependencies(virtuals=(language,)):
|
||||
continue
|
||||
|
||||
compiler_wrapper_pkg = dependent_spec["compiler-wrapper"].package
|
||||
compiler_pkg = dependent_spec[language].package
|
||||
|
||||
# First, we get the values from the sysconfigdata:
|
||||
config_compile = self.config_vars[compile_var]
|
||||
config_link = self.config_vars[link_var]
|
||||
|
||||
# The dependent environment will have the compilation command set to
|
||||
# the following:
|
||||
new_compile = join_path(
|
||||
spack.paths.build_env_path, dependent_spec[language].package.link_paths[language]
|
||||
)
|
||||
new_compile = str(compiler_wrapper_pkg.bin_dir() / compiler_pkg.link_paths[language])
|
||||
|
||||
# Normally, the link command starts with the compilation command:
|
||||
if config_link.startswith(config_compile):
|
||||
|
1
var/spack/repos/compiler_runtime.test/packages/compiler-wrapper
Symbolic link
1
var/spack/repos/compiler_runtime.test/packages/compiler-wrapper
Symbolic link
@ -0,0 +1 @@
|
||||
../../builtin/packages/compiler-wrapper/
|
1
var/spack/repos/flags.test/packages/compiler-wrapper
Symbolic link
1
var/spack/repos/flags.test/packages/compiler-wrapper
Symbolic link
@ -0,0 +1 @@
|
||||
../../builtin/packages/compiler-wrapper/
|
1
var/spack/repos/requirements.test/packages/compiler-wrapper
Symbolic link
1
var/spack/repos/requirements.test/packages/compiler-wrapper
Symbolic link
@ -0,0 +1 @@
|
||||
../../builtin.mock/packages/compiler-wrapper/
|
Loading…
Reference in New Issue
Block a user