build systems: import from spack.package (#50541)

This commit is contained in:
Harmen Stoppels 2025-05-19 12:18:36 +02:00 committed by GitHub
parent da9fa24d15
commit 6227bd7986
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 361 additions and 437 deletions

View File

@ -7,11 +7,9 @@
import llnl.util.lang import llnl.util.lang
import spack.builder import spack.builder
import spack.error
import spack.phase_callbacks
import spack.relocate import spack.relocate
import spack.spec
import spack.store import spack.store
from spack.package import InstallError, Spec, run_after
def sanity_check_prefix(builder: spack.builder.Builder): def sanity_check_prefix(builder: spack.builder.Builder):
@ -34,7 +32,7 @@ def check_paths(path_list, filetype, predicate):
if not predicate(abs_path): if not predicate(abs_path):
msg = "Install failed for {0}. No such {1} in prefix: {2}" msg = "Install failed for {0}. No such {1} in prefix: {2}"
msg = msg.format(pkg.name, filetype, path) msg = msg.format(pkg.name, filetype, path)
raise spack.error.InstallError(msg) raise InstallError(msg)
check_paths(pkg.sanity_check_is_file, "file", os.path.isfile) check_paths(pkg.sanity_check_is_file, "file", os.path.isfile)
check_paths(pkg.sanity_check_is_dir, "directory", os.path.isdir) check_paths(pkg.sanity_check_is_dir, "directory", os.path.isdir)
@ -42,7 +40,7 @@ def check_paths(path_list, filetype, predicate):
ignore_file = llnl.util.lang.match_predicate(spack.store.STORE.layout.hidden_file_regexes) ignore_file = llnl.util.lang.match_predicate(spack.store.STORE.layout.hidden_file_regexes)
if all(map(ignore_file, os.listdir(pkg.prefix))): if all(map(ignore_file, os.listdir(pkg.prefix))):
msg = "Install failed for {0}. Nothing was installed!" msg = "Install failed for {0}. Nothing was installed!"
raise spack.error.InstallError(msg.format(pkg.name)) raise InstallError(msg.format(pkg.name))
def apply_macos_rpath_fixups(builder: spack.builder.Builder): def apply_macos_rpath_fixups(builder: spack.builder.Builder):
@ -62,9 +60,7 @@ def apply_macos_rpath_fixups(builder: spack.builder.Builder):
spack.relocate.fixup_macos_rpaths(builder.spec) spack.relocate.fixup_macos_rpaths(builder.spec)
def ensure_build_dependencies_or_raise( def ensure_build_dependencies_or_raise(spec: Spec, dependencies: List[str], error_msg: str):
spec: spack.spec.Spec, dependencies: List[str], error_msg: str
):
"""Ensure that some build dependencies are present in the concrete spec. """Ensure that some build dependencies are present in the concrete spec.
If not, raise a RuntimeError with a helpful error message. If not, raise a RuntimeError with a helpful error message.
@ -131,4 +127,4 @@ class BuilderWithDefaults(spack.builder.Builder):
"""Base class for all specific builders with common callbacks registered.""" """Base class for all specific builders with common callbacks registered."""
# Check that self.prefix is there after installation # Check that self.prefix is there after installation
spack.phase_callbacks.run_after("install")(sanity_check_prefix) run_after("install")(sanity_check_prefix)

View File

@ -3,12 +3,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os import os
import llnl.util.filesystem as fs from spack.package import Executable, Prefix, Spec, extends, filter_file
import spack.directives
import spack.spec
import spack.util.executable
import spack.util.prefix
from .autotools import AutotoolsBuilder, AutotoolsPackage from .autotools import AutotoolsBuilder, AutotoolsPackage
@ -20,16 +15,13 @@ class AspellBuilder(AutotoolsBuilder):
""" """
def configure( def configure(
self, self, pkg: "AspellDictPackage", spec: Spec, prefix: Prefix # type: ignore[override]
pkg: "AspellDictPackage", # type: ignore[override]
spec: spack.spec.Spec,
prefix: spack.util.prefix.Prefix,
): ):
aspell = spec["aspell"].prefix.bin.aspell aspell = spec["aspell"].prefix.bin.aspell
prezip = spec["aspell"].prefix.bin.prezip prezip = spec["aspell"].prefix.bin.prezip
destdir = prefix destdir = prefix
sh = spack.util.executable.Executable("/bin/sh") sh = Executable("/bin/sh")
sh("./configure", "--vars", f"ASPELL={aspell}", f"PREZIP={prezip}", f"DESTDIR={destdir}") sh("./configure", "--vars", f"ASPELL={aspell}", f"PREZIP={prezip}", f"DESTDIR={destdir}")
@ -42,7 +34,7 @@ def configure(
class AspellDictPackage(AutotoolsPackage): class AspellDictPackage(AutotoolsPackage):
"""Specialized class for building aspell dictionairies.""" """Specialized class for building aspell dictionairies."""
spack.directives.extends("aspell", when="build_system=autotools") extends("aspell", when="build_system=autotools")
#: Override the default autotools builder #: Override the default autotools builder
AutotoolsBuilder = AspellBuilder AutotoolsBuilder = AspellBuilder
@ -54,5 +46,5 @@ def patch(self):
datadir = aspell("dump", "config", "data-dir", output=str).strip() datadir = aspell("dump", "config", "data-dir", output=str).strip()
dictdir = os.path.relpath(dictdir, aspell_spec.prefix) dictdir = os.path.relpath(dictdir, aspell_spec.prefix)
datadir = os.path.relpath(datadir, aspell_spec.prefix) datadir = os.path.relpath(datadir, aspell_spec.prefix)
fs.filter_file(r"^dictdir=.*$", f"dictdir=/{dictdir}", "configure") filter_file(r"^dictdir=.*$", f"dictdir=/{dictdir}", "configure")
fs.filter_file(r"^datadir=.*$", f"datadir=/{datadir}", "configure") filter_file(r"^datadir=.*$", f"datadir=/{datadir}", "configure")

View File

@ -12,17 +12,30 @@
import spack.build_environment import spack.build_environment
import spack.builder import spack.builder
import spack.compilers.libraries import spack.compilers.libraries
import spack.error
import spack.package_base import spack.package_base
import spack.phase_callbacks
import spack.spec
import spack.util.environment
import spack.util.prefix
from spack.directives import build_system, conflicts, depends_on
from spack.multimethod import when
from spack.operating_systems.mac_os import macos_version from spack.operating_systems.mac_os import macos_version
from spack.util.executable import Executable from spack.package import (
from spack.version import Version EnvironmentModifications,
Executable,
FileFilter,
InstallError,
Prefix,
Spec,
Version,
build_system,
conflicts,
copy,
depends_on,
find,
force_remove,
is_exe,
keep_modification_time,
mkdirp,
run_after,
run_before,
when,
working_dir,
)
from ._checks import ( from ._checks import (
BuilderWithDefaults, BuilderWithDefaults,
@ -192,7 +205,7 @@ def archive_files(self) -> List[str]:
files.append(self._removed_la_files_log) files.append(self._removed_la_files_log)
return files return files
@spack.phase_callbacks.run_after("autoreconf") @run_after("autoreconf")
def _do_patch_config_files(self) -> None: def _do_patch_config_files(self) -> None:
"""Some packages ship with older config.guess/config.sub files and need to """Some packages ship with older config.guess/config.sub files and need to
have these updated when installed on a newer architecture. have these updated when installed on a newer architecture.
@ -230,7 +243,7 @@ def runs_ok(script_abs_path):
return True return True
# Get the list of files that needs to be patched # Get the list of files that needs to be patched
to_be_patched = fs.find(self.pkg.stage.path, files=["config.sub", "config.guess"]) to_be_patched = find(self.pkg.stage.path, files=["config.sub", "config.guess"])
to_be_patched = [f for f in to_be_patched if not runs_ok(f)] to_be_patched = [f for f in to_be_patched if not runs_ok(f)]
# If there are no files to be patched, return early # If there are no files to be patched, return early
@ -249,13 +262,13 @@ def runs_ok(script_abs_path):
# An external gnuconfig may not not have a prefix. # An external gnuconfig may not not have a prefix.
if gnuconfig_dir is None: if gnuconfig_dir is None:
raise spack.error.InstallError( raise InstallError(
"Spack could not find substitutes for GNU config files because no " "Spack could not find substitutes for GNU config files because no "
"prefix is available for the `gnuconfig` package. Make sure you set a " "prefix is available for the `gnuconfig` package. Make sure you set a "
"prefix path instead of modules for external `gnuconfig`." "prefix path instead of modules for external `gnuconfig`."
) )
candidates = fs.find(gnuconfig_dir, files=to_be_found, recursive=False) candidates = find(gnuconfig_dir, files=to_be_found, recursive=False)
# For external packages the user may have specified an incorrect prefix. # For external packages the user may have specified an incorrect prefix.
# otherwise the installation is just corrupt. # otherwise the installation is just corrupt.
@ -269,7 +282,7 @@ def runs_ok(script_abs_path):
msg += ( msg += (
" or the `gnuconfig` package prefix is misconfigured as" " an external package" " or the `gnuconfig` package prefix is misconfigured as" " an external package"
) )
raise spack.error.InstallError(msg) raise InstallError(msg)
# Filter working substitutes # Filter working substitutes
candidates = [f for f in candidates if runs_ok(f)] candidates = [f for f in candidates if runs_ok(f)]
@ -294,29 +307,29 @@ def runs_ok(script_abs_path):
and set the prefix to the directory containing the `config.guess` and and set the prefix to the directory containing the `config.guess` and
`config.sub` files. `config.sub` files.
""" """
raise spack.error.InstallError(msg.format(", ".join(to_be_found), self.pkg.name)) raise InstallError(msg.format(", ".join(to_be_found), self.pkg.name))
# Copy the good files over the bad ones # Copy the good files over the bad ones
for abs_path in to_be_patched: for abs_path in to_be_patched:
name = os.path.basename(abs_path) name = os.path.basename(abs_path)
mode = os.stat(abs_path).st_mode mode = os.stat(abs_path).st_mode
os.chmod(abs_path, stat.S_IWUSR) os.chmod(abs_path, stat.S_IWUSR)
fs.copy(substitutes[name], abs_path) copy(substitutes[name], abs_path)
os.chmod(abs_path, mode) os.chmod(abs_path, mode)
@spack.phase_callbacks.run_before("configure") @run_before("configure")
def _patch_usr_bin_file(self) -> None: def _patch_usr_bin_file(self) -> None:
"""On NixOS file is not available in /usr/bin/file. Patch configure """On NixOS file is not available in /usr/bin/file. Patch configure
scripts to use file from path.""" scripts to use file from path."""
if self.spec.os.startswith("nixos"): if self.spec.os.startswith("nixos"):
x = fs.FileFilter( x = FileFilter(
*filter(fs.is_exe, fs.find(self.build_directory, "configure", recursive=True)) *filter(is_exe, find(self.build_directory, "configure", recursive=True))
) )
with fs.keep_modification_time(*x.filenames): with keep_modification_time(*x.filenames):
x.filter(regex="/usr/bin/file", repl="file", string=True) x.filter(regex="/usr/bin/file", repl="file", string=True)
@spack.phase_callbacks.run_before("configure") @run_before("configure")
def _set_autotools_environment_variables(self) -> None: def _set_autotools_environment_variables(self) -> None:
"""Many autotools builds use a version of mknod.m4 that fails when """Many autotools builds use a version of mknod.m4 that fails when
running as root unless FORCE_UNSAFE_CONFIGURE is set to 1. running as root unless FORCE_UNSAFE_CONFIGURE is set to 1.
@ -330,7 +343,7 @@ def _set_autotools_environment_variables(self) -> None:
""" """
os.environ["FORCE_UNSAFE_CONFIGURE"] = "1" os.environ["FORCE_UNSAFE_CONFIGURE"] = "1"
@spack.phase_callbacks.run_before("configure") @run_before("configure")
def _do_patch_libtool_configure(self) -> None: def _do_patch_libtool_configure(self) -> None:
"""Patch bugs that propagate from libtool macros into "configure" and """Patch bugs that propagate from libtool macros into "configure" and
further into "libtool". Note that patches that can be fixed by patching further into "libtool". Note that patches that can be fixed by patching
@ -341,14 +354,12 @@ def _do_patch_libtool_configure(self) -> None:
if not self.patch_libtool: if not self.patch_libtool:
return return
x = fs.FileFilter( x = FileFilter(*filter(is_exe, find(self.build_directory, "configure", recursive=True)))
*filter(fs.is_exe, fs.find(self.build_directory, "configure", recursive=True))
)
# There are distributed automatically generated files that depend on the configure script # There are distributed automatically generated files that depend on the configure script
# and require additional tools for rebuilding. # and require additional tools for rebuilding.
# See https://github.com/spack/spack/pull/30768#issuecomment-1219329860 # See https://github.com/spack/spack/pull/30768#issuecomment-1219329860
with fs.keep_modification_time(*x.filenames): with keep_modification_time(*x.filenames):
# Fix parsing of compiler output when collecting predeps and postdeps # Fix parsing of compiler output when collecting predeps and postdeps
# https://lists.gnu.org/archive/html/bug-libtool/2016-03/msg00003.html # https://lists.gnu.org/archive/html/bug-libtool/2016-03/msg00003.html
x.filter(regex=r'^(\s*if test x-L = )("\$p" \|\|\s*)$', repl=r"\1x\2") x.filter(regex=r'^(\s*if test x-L = )("\$p" \|\|\s*)$', repl=r"\1x\2")
@ -365,7 +376,7 @@ def _do_patch_libtool_configure(self) -> None:
# 82f7f52123e4e7e50721049f7fa6f9b870e09c9d. # 82f7f52123e4e7e50721049f7fa6f9b870e09c9d.
x.filter("lt_cv_apple_cc_single_mod=no", "lt_cv_apple_cc_single_mod=yes", string=True) x.filter("lt_cv_apple_cc_single_mod=no", "lt_cv_apple_cc_single_mod=yes", string=True)
@spack.phase_callbacks.run_after("configure") @run_after("configure")
def _do_patch_libtool(self) -> None: def _do_patch_libtool(self) -> None:
"""If configure generates a "libtool" script that does not correctly """If configure generates a "libtool" script that does not correctly
detect the compiler (and patch_libtool is set), patch in the correct detect the compiler (and patch_libtool is set), patch in the correct
@ -387,9 +398,7 @@ def _do_patch_libtool(self) -> None:
if not self.patch_libtool: if not self.patch_libtool:
return return
x = fs.FileFilter( x = FileFilter(*filter(is_exe, find(self.build_directory, "libtool", recursive=True)))
*filter(fs.is_exe, fs.find(self.build_directory, "libtool", recursive=True))
)
# Exit early if there is nothing to patch: # Exit early if there is nothing to patch:
if not x.filenames: if not x.filenames:
@ -545,10 +554,10 @@ def build_directory(self) -> str:
build_dir = os.path.join(self.pkg.stage.source_path, build_dir) build_dir = os.path.join(self.pkg.stage.source_path, build_dir)
return build_dir return build_dir
@spack.phase_callbacks.run_before("autoreconf") @run_before("autoreconf")
def _delete_configure_to_force_update(self) -> None: def _delete_configure_to_force_update(self) -> None:
if self.force_autoreconf: if self.force_autoreconf:
fs.force_remove(self.configure_abs_path) force_remove(self.configure_abs_path)
@property @property
def autoreconf_search_path_args(self) -> List[str]: def autoreconf_search_path_args(self) -> List[str]:
@ -558,7 +567,7 @@ def autoreconf_search_path_args(self) -> List[str]:
spack dependencies.""" spack dependencies."""
return _autoreconf_search_path_args(self.spec) return _autoreconf_search_path_args(self.spec)
@spack.phase_callbacks.run_after("autoreconf") @run_after("autoreconf")
def _set_configure_or_die(self) -> None: def _set_configure_or_die(self) -> None:
"""Ensure the presence of a "configure" script, or raise. If the "configure" """Ensure the presence of a "configure" script, or raise. If the "configure"
is found, a module level attribute is set. is found, a module level attribute is set.
@ -582,9 +591,7 @@ def configure_args(self) -> List[str]:
""" """
return [] return []
def autoreconf( def autoreconf(self, pkg: AutotoolsPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: AutotoolsPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Not needed usually, configure should be already there""" """Not needed usually, configure should be already there"""
# If configure exists nothing needs to be done # If configure exists nothing needs to be done
@ -603,7 +610,7 @@ def autoreconf(
tty.warn("* If the default procedure fails, consider implementing *") tty.warn("* If the default procedure fails, consider implementing *")
tty.warn("* a custom AUTORECONF phase in the package *") tty.warn("* a custom AUTORECONF phase in the package *")
tty.warn("*********************************************************") tty.warn("*********************************************************")
with fs.working_dir(self.configure_directory): with working_dir(self.configure_directory):
# This line is what is needed most of the time # This line is what is needed most of the time
# --install, --verbose, --force # --install, --verbose, --force
autoreconf_args = ["-ivf"] autoreconf_args = ["-ivf"]
@ -611,9 +618,7 @@ def autoreconf(
autoreconf_args += self.autoreconf_extra_args autoreconf_args += self.autoreconf_extra_args
self.pkg.module.autoreconf(*autoreconf_args) self.pkg.module.autoreconf(*autoreconf_args)
def configure( def configure(self, pkg: AutotoolsPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: AutotoolsPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run "configure", with the arguments specified by the builder and an """Run "configure", with the arguments specified by the builder and an
appropriately set prefix. appropriately set prefix.
""" """
@ -621,31 +626,27 @@ def configure(
options += ["--prefix={0}".format(prefix)] options += ["--prefix={0}".format(prefix)]
options += self.configure_args() options += self.configure_args()
with fs.working_dir(self.build_directory, create=True): with working_dir(self.build_directory, create=True):
pkg.module.configure(*options) pkg.module.configure(*options)
def build( def build(self, pkg: AutotoolsPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: AutotoolsPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run "make" on the build targets specified by the builder.""" """Run "make" on the build targets specified by the builder."""
# See https://autotools.io/automake/silent.html # See https://autotools.io/automake/silent.html
params = ["V=1"] params = ["V=1"]
params += self.build_targets params += self.build_targets
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.make(*params) pkg.module.make(*params)
def install( def install(self, pkg: AutotoolsPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: AutotoolsPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run "make" on the install targets specified by the builder.""" """Run "make" on the install targets specified by the builder."""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.make(*self.install_targets) pkg.module.make(*self.install_targets)
spack.phase_callbacks.run_after("build")(execute_build_time_tests) run_after("build")(execute_build_time_tests)
def check(self) -> None: def check(self) -> None:
"""Run "make" on the ``test`` and ``check`` targets, if found.""" """Run "make" on the ``test`` and ``check`` targets, if found."""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
self.pkg._if_make_target_execute("test") self.pkg._if_make_target_execute("test")
self.pkg._if_make_target_execute("check") self.pkg._if_make_target_execute("check")
@ -713,7 +714,7 @@ def _activate_or_not(
Raises: Raises:
KeyError: if name is not among known variants KeyError: if name is not among known variants
""" """
spec: spack.spec.Spec = self.pkg.spec spec: Spec = self.pkg.spec
args: List[str] = [] args: List[str] = []
if activation_value == "prefix": if activation_value == "prefix":
@ -824,14 +825,14 @@ def enable_or_disable(
""" """
return self._activate_or_not(name, "enable", "disable", activation_value, variant) return self._activate_or_not(name, "enable", "disable", activation_value, variant)
spack.phase_callbacks.run_after("install")(execute_install_time_tests) run_after("install")(execute_install_time_tests)
def installcheck(self) -> None: def installcheck(self) -> None:
"""Run "make" on the ``installcheck`` target, if found.""" """Run "make" on the ``installcheck`` target, if found."""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
self.pkg._if_make_target_execute("installcheck") self.pkg._if_make_target_execute("installcheck")
@spack.phase_callbacks.run_after("install") @run_after("install")
def _remove_libtool_archives(self) -> None: def _remove_libtool_archives(self) -> None:
"""Remove all .la files in prefix sub-folders if the package sets """Remove all .la files in prefix sub-folders if the package sets
``install_libtool_archives`` to be False. ``install_libtool_archives`` to be False.
@ -841,25 +842,23 @@ def _remove_libtool_archives(self) -> None:
return return
# Remove the files and create a log of what was removed # Remove the files and create a log of what was removed
libtool_files = fs.find(str(self.pkg.prefix), "*.la", recursive=True) libtool_files = find(str(self.pkg.prefix), "*.la", recursive=True)
with fs.safe_remove(*libtool_files): with fs.safe_remove(*libtool_files):
fs.mkdirp(os.path.dirname(self._removed_la_files_log)) mkdirp(os.path.dirname(self._removed_la_files_log))
with open(self._removed_la_files_log, mode="w", encoding="utf-8") as f: with open(self._removed_la_files_log, mode="w", encoding="utf-8") as f:
f.write("\n".join(libtool_files)) f.write("\n".join(libtool_files))
def setup_build_environment( def setup_build_environment(self, env: EnvironmentModifications) -> None:
self, env: spack.util.environment.EnvironmentModifications
) -> None:
if self.spec.platform == "darwin" and macos_version() >= Version("11"): if self.spec.platform == "darwin" and macos_version() >= Version("11"):
# Many configure files rely on matching '10.*' for macOS version # Many configure files rely on matching '10.*' for macOS version
# detection and fail to add flags if it shows as version 11. # detection and fail to add flags if it shows as version 11.
env.set("MACOSX_DEPLOYMENT_TARGET", "10.16") env.set("MACOSX_DEPLOYMENT_TARGET", "10.16")
# On macOS, force rpaths for shared library IDs and remove duplicate rpaths # On macOS, force rpaths for shared library IDs and remove duplicate rpaths
spack.phase_callbacks.run_after("install", when="platform=darwin")(apply_macos_rpath_fixups) run_after("install", when="platform=darwin")(apply_macos_rpath_fixups)
def _autoreconf_search_path_args(spec: spack.spec.Spec) -> List[str]: def _autoreconf_search_path_args(spec: Spec) -> List[str]:
dirs_seen: Set[Tuple[int, int]] = set() dirs_seen: Set[Tuple[int, int]] = set()
flags_spack: List[str] = [] flags_spack: List[str] = []
flags_external: List[str] = [] flags_external: List[str] = []

View File

@ -2,8 +2,8 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import spack.builder import spack.builder
import spack.directives
import spack.package_base import spack.package_base
from spack.package import Prefix, Spec, build_system
class BundlePackage(spack.package_base.PackageBase): class BundlePackage(spack.package_base.PackageBase):
@ -19,12 +19,12 @@ class BundlePackage(spack.package_base.PackageBase):
#: Bundle packages do not have associated source or binary code. #: Bundle packages do not have associated source or binary code.
has_code = False has_code = False
spack.directives.build_system("bundle") build_system("bundle")
@spack.builder.builder("bundle") @spack.builder.builder("bundle")
class BundleBuilder(spack.builder.Builder): class BundleBuilder(spack.builder.Builder):
phases = ("install",) phases = ("install",)
def install(self, pkg, spec, prefix): def install(self, pkg: BundlePackage, spec: Spec, prefix: Prefix) -> None:
pass pass

View File

@ -7,14 +7,7 @@
import re import re
from typing import Optional, Tuple from typing import Optional, Tuple
import llnl.util.filesystem as fs from spack.package import Prefix, Spec, depends_on, install, mkdirp, run_after, tty, which_string
import llnl.util.tty as tty
import spack.phase_callbacks
import spack.spec
import spack.util.prefix
from spack.directives import depends_on
from spack.util.executable import which_string
from .cmake import CMakeBuilder, CMakePackage from .cmake import CMakeBuilder, CMakePackage
@ -375,9 +368,7 @@ def initconfig_package_entries(self):
"""This method is to be overwritten by the package""" """This method is to be overwritten by the package"""
return [] return []
def initconfig( def initconfig(self, pkg: "CachedCMakePackage", spec: Spec, prefix: Prefix) -> None:
self, pkg: "CachedCMakePackage", spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
cache_entries = ( cache_entries = (
self.std_initconfig_entries() self.std_initconfig_entries()
+ self.initconfig_compiler_entries() + self.initconfig_compiler_entries()
@ -397,10 +388,10 @@ def std_cmake_args(self):
args.extend(["-C", self.cache_path]) args.extend(["-C", self.cache_path])
return args return args
@spack.phase_callbacks.run_after("install") @run_after("install")
def install_cmake_cache(self): def install_cmake_cache(self):
fs.mkdirp(self.pkg.spec.prefix.share.cmake) mkdirp(self.pkg.spec.prefix.share.cmake)
fs.install(self.cache_path, self.pkg.spec.prefix.share.cmake) install(self.cache_path, self.pkg.spec.prefix.share.cmake)
class CachedCMakePackage(CMakePackage): class CachedCMakePackage(CMakePackage):

View File

@ -2,16 +2,19 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import llnl.util.filesystem as fs
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.phase_callbacks from spack.package import (
import spack.spec EnvironmentModifications,
import spack.util.environment Prefix,
import spack.util.prefix Spec,
from spack.directives import build_system, depends_on build_system,
from spack.multimethod import when depends_on,
install_tree,
run_after,
when,
working_dir,
)
from ._checks import BuilderWithDefaults, execute_install_time_tests from ._checks import BuilderWithDefaults, execute_install_time_tests
@ -87,30 +90,24 @@ def check_args(self):
"""Argument for ``cargo test`` during check phase""" """Argument for ``cargo test`` during check phase"""
return [] return []
def setup_build_environment( def setup_build_environment(self, env: EnvironmentModifications) -> None:
self, env: spack.util.environment.EnvironmentModifications
) -> None:
env.set("CARGO_HOME", self.stage.path) env.set("CARGO_HOME", self.stage.path)
def build( def build(self, pkg: CargoPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: CargoPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Runs ``cargo install`` in the source directory""" """Runs ``cargo install`` in the source directory"""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.cargo( pkg.module.cargo(
"install", "--root", "out", "--path", ".", *self.std_build_args, *self.build_args "install", "--root", "out", "--path", ".", *self.std_build_args, *self.build_args
) )
def install( def install(self, pkg: CargoPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: CargoPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Copy build files into package prefix.""" """Copy build files into package prefix."""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
fs.install_tree("out", prefix) install_tree("out", prefix)
spack.phase_callbacks.run_after("install")(execute_install_time_tests) run_after("install")(execute_install_time_tests)
def check(self): def check(self):
"""Run "cargo test".""" """Run "cargo test"."""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
self.pkg.module.cargo("test", *self.check_args) self.pkg.module.cargo("test", *self.check_args)

View File

@ -10,20 +10,25 @@
from itertools import chain from itertools import chain
from typing import Any, List, Optional, Tuple from typing import Any, List, Optional, Tuple
import llnl.util.filesystem as fs
from llnl.util import tty
from llnl.util.lang import stable_partition from llnl.util.lang import stable_partition
import spack.builder import spack.builder
import spack.deptypes as dt import spack.deptypes as dt
import spack.error
import spack.package_base import spack.package_base
import spack.phase_callbacks
import spack.spec
import spack.util.prefix
from spack import traverse from spack import traverse
from spack.directives import build_system, conflicts, depends_on, variant from spack.package import (
from spack.multimethod import when InstallError,
Prefix,
Spec,
build_system,
conflicts,
depends_on,
run_after,
tty,
variant,
when,
working_dir,
)
from spack.util.environment import filter_system_paths from spack.util.environment import filter_system_paths
from ._checks import BuilderWithDefaults, execute_build_time_tests from ._checks import BuilderWithDefaults, execute_build_time_tests
@ -382,7 +387,7 @@ def std_args(
msg = "Invalid CMake generator: '{0}'\n".format(generator) msg = "Invalid CMake generator: '{0}'\n".format(generator)
msg += "CMakePackage currently supports the following " msg += "CMakePackage currently supports the following "
msg += "primary generators: '{0}'".format("', '".join(valid_primary_generators)) msg += "primary generators: '{0}'".format("', '".join(valid_primary_generators))
raise spack.error.InstallError(msg) raise InstallError(msg)
try: try:
build_type = pkg.spec.variants["build_type"].value build_type = pkg.spec.variants["build_type"].value
@ -454,9 +459,7 @@ def cmake_args(self) -> List[str]:
""" """
return [] return []
def cmake( def cmake(self, pkg: CMakePackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: CMakePackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Runs ``cmake`` in the build directory""" """Runs ``cmake`` in the build directory"""
if spec.is_develop: if spec.is_develop:
@ -480,37 +483,33 @@ def cmake(
options = self.std_cmake_args options = self.std_cmake_args
options += self.cmake_args() options += self.cmake_args()
options.append(os.path.abspath(self.root_cmakelists_dir)) options.append(os.path.abspath(self.root_cmakelists_dir))
with fs.working_dir(self.build_directory, create=True): with working_dir(self.build_directory, create=True):
pkg.module.cmake(*options) pkg.module.cmake(*options)
def build( def build(self, pkg: CMakePackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: CMakePackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Make the build targets""" """Make the build targets"""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
if self.generator == "Unix Makefiles": if self.generator == "Unix Makefiles":
pkg.module.make(*self.build_targets) pkg.module.make(*self.build_targets)
elif self.generator == "Ninja": elif self.generator == "Ninja":
self.build_targets.append("-v") self.build_targets.append("-v")
pkg.module.ninja(*self.build_targets) pkg.module.ninja(*self.build_targets)
def install( def install(self, pkg: CMakePackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: CMakePackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Make the install targets""" """Make the install targets"""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
if self.generator == "Unix Makefiles": if self.generator == "Unix Makefiles":
pkg.module.make(*self.install_targets) pkg.module.make(*self.install_targets)
elif self.generator == "Ninja": elif self.generator == "Ninja":
pkg.module.ninja(*self.install_targets) pkg.module.ninja(*self.install_targets)
spack.phase_callbacks.run_after("build")(execute_build_time_tests) run_after("build")(execute_build_time_tests)
def check(self) -> None: def check(self) -> None:
"""Search the CMake-generated files for the targets ``test`` and ``check``, """Search the CMake-generated files for the targets ``test`` and ``check``,
and runs them if found. and runs them if found.
""" """
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
if self.generator == "Unix Makefiles": if self.generator == "Unix Makefiles":
self.pkg._if_make_target_execute("test", jobs_env="CTEST_PARALLEL_LEVEL") self.pkg._if_make_target_execute("test", jobs_env="CTEST_PARALLEL_LEVEL")
self.pkg._if_make_target_execute("check") self.pkg._if_make_target_execute("check")

View File

@ -8,13 +8,11 @@
import sys import sys
from typing import Dict, List, Optional, Sequence, Tuple, Union from typing import Dict, List, Optional, Sequence, Tuple, Union
import llnl.util.tty as tty
from llnl.util.lang import classproperty, memoized from llnl.util.lang import classproperty, memoized
import spack
import spack.compilers.error import spack.compilers.error
import spack.package_base import spack.package_base
import spack.util.executable from spack.package import Executable, ProcessError, Spec, tty, which_string
# Local "type" for type hints # Local "type" for type hints
Path = Union[str, pathlib.Path] Path = Union[str, pathlib.Path]
@ -52,7 +50,7 @@ class CompilerPackage(spack.package_base.PackageBase):
#: Flags for generating debug information #: Flags for generating debug information
debug_flags: Sequence[str] = [] debug_flags: Sequence[str] = []
def __init__(self, spec: "spack.spec.Spec"): def __init__(self, spec: Spec):
super().__init__(spec) super().__init__(spec)
msg = f"Supported languages for {spec} are not a subset of possible supported languages" msg = f"Supported languages for {spec} are not a subset of possible supported languages"
msg += f" supports: {self.supported_languages}, valid values: {self.compiler_languages}" msg += f" supports: {self.supported_languages}, valid values: {self.compiler_languages}"
@ -97,7 +95,7 @@ def determine_version(cls, exe: Path) -> str:
match = re.search(cls.compiler_version_regex, output) match = re.search(cls.compiler_version_regex, output)
if match: if match:
return ".".join(match.groups()) return ".".join(match.groups())
except spack.util.executable.ProcessError: except ProcessError:
pass pass
except Exception as e: except Exception as e:
tty.debug( tty.debug(
@ -230,7 +228,7 @@ def _compiler_output(
compiler_path: path of the compiler to be invoked compiler_path: path of the compiler to be invoked
version_argument: the argument used to extract version information version_argument: the argument used to extract version information
""" """
compiler = spack.util.executable.Executable(compiler_path) compiler = Executable(compiler_path)
if not version_argument: if not version_argument:
return compiler( return compiler(
output=str, error=str, ignore_errors=ignore_errors, timeout=120, fail_on_error=True output=str, error=str, ignore_errors=ignore_errors, timeout=120, fail_on_error=True
@ -253,7 +251,7 @@ def compiler_output(
# not just executable name. If we don't do this, and the path changes # not just executable name. If we don't do this, and the path changes
# (e.g., during testing), we can get incorrect results. # (e.g., during testing), we can get incorrect results.
if not os.path.isabs(compiler_path): if not os.path.isabs(compiler_path):
compiler_path = spack.util.executable.which_string(str(compiler_path), required=True) compiler_path = which_string(str(compiler_path), required=True)
return _compiler_output( return _compiler_output(
compiler_path, version_argument=version_argument, ignore_errors=ignore_errors compiler_path, version_argument=version_argument, ignore_errors=ignore_errors

View File

@ -5,9 +5,7 @@
import re import re
from typing import Iterable, List from typing import Iterable, List
import spack.variant from spack.package import any_combination_of, conflicts, depends_on, variant, when
from spack.directives import conflicts, depends_on, variant
from spack.multimethod import when
from spack.package_base import PackageBase from spack.package_base import PackageBase
@ -71,7 +69,7 @@ class CudaPackage(PackageBase):
variant( variant(
"cuda_arch", "cuda_arch",
description="CUDA architecture", description="CUDA architecture",
values=spack.variant.any_combination_of(*cuda_arch_values), values=any_combination_of(*cuda_arch_values),
sticky=True, sticky=True,
when="+cuda", when="+cuda",
) )

View File

@ -4,11 +4,8 @@
from typing import Tuple from typing import Tuple
import spack.builder import spack.builder
import spack.directives
import spack.package_base import spack.package_base
import spack.phase_callbacks from spack.package import Prefix, Spec, build_system, run_after
import spack.spec
import spack.util.prefix
from ._checks import BuilderWithDefaults, apply_macos_rpath_fixups, execute_install_time_tests from ._checks import BuilderWithDefaults, apply_macos_rpath_fixups, execute_install_time_tests
@ -24,7 +21,7 @@ class Package(spack.package_base.PackageBase):
#: Legacy buildsystem attribute used to deserialize and install old specs #: Legacy buildsystem attribute used to deserialize and install old specs
legacy_buildsystem = "generic" legacy_buildsystem = "generic"
spack.directives.build_system("generic") build_system("generic")
@spack.builder.builder("generic") @spack.builder.builder("generic")
@ -46,12 +43,10 @@ class GenericBuilder(BuilderWithDefaults):
install_time_test_callbacks = [] install_time_test_callbacks = []
# On macOS, force rpaths for shared library IDs and remove duplicate rpaths # On macOS, force rpaths for shared library IDs and remove duplicate rpaths
spack.phase_callbacks.run_after("install", when="platform=darwin")(apply_macos_rpath_fixups) run_after("install", when="platform=darwin")(apply_macos_rpath_fixups)
# unconditionally perform any post-install phase tests # unconditionally perform any post-install phase tests
spack.phase_callbacks.run_after("install")(execute_install_time_tests) run_after("install")(execute_install_time_tests)
def install( def install(self, pkg: Package, spec: Spec, prefix: Prefix) -> None:
self, pkg: Package, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
raise NotImplementedError raise NotImplementedError

View File

@ -2,16 +2,21 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import llnl.util.filesystem as fs
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.phase_callbacks from spack.package import (
import spack.spec EnvironmentModifications,
import spack.util.environment Prefix,
import spack.util.prefix Spec,
from spack.directives import build_system, depends_on build_system,
from spack.multimethod import when depends_on,
install,
join_path,
mkdirp,
run_after,
when,
working_dir,
)
from ._checks import BuilderWithDefaults, execute_install_time_tests from ._checks import BuilderWithDefaults, execute_install_time_tests
@ -69,12 +74,10 @@ class GoBuilder(BuilderWithDefaults):
#: Callback names for install-time test #: Callback names for install-time test
install_time_test_callbacks = ["check"] install_time_test_callbacks = ["check"]
def setup_build_environment( def setup_build_environment(self, env: EnvironmentModifications) -> None:
self, env: spack.util.environment.EnvironmentModifications
) -> None:
env.set("GO111MODULE", "on") env.set("GO111MODULE", "on")
env.set("GOTOOLCHAIN", "local") env.set("GOTOOLCHAIN", "local")
env.set("GOPATH", fs.join_path(self.pkg.stage.path, "go")) env.set("GOPATH", join_path(self.pkg.stage.path, "go"))
@property @property
def build_directory(self): def build_directory(self):
@ -100,24 +103,20 @@ def check_args(self):
"""Argument for ``go test`` during check phase""" """Argument for ``go test`` during check phase"""
return [] return []
def build( def build(self, pkg: GoPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: GoPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Runs ``go build`` in the source directory""" """Runs ``go build`` in the source directory"""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.go("build", *self.build_args) pkg.module.go("build", *self.build_args)
def install( def install(self, pkg: GoPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: GoPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Install built binaries into prefix bin.""" """Install built binaries into prefix bin."""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
fs.mkdirp(prefix.bin) mkdirp(prefix.bin)
fs.install(pkg.name, prefix.bin) install(pkg.name, prefix.bin)
spack.phase_callbacks.run_after("install")(execute_install_time_tests) run_after("install")(execute_install_time_tests)
def check(self): def check(self):
"""Run ``go test .`` in the source directory""" """Run ``go test .`` in the source directory"""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
self.pkg.module.go("test", *self.check_args) self.pkg.module.go("test", *self.check_args)

View File

@ -7,12 +7,16 @@
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.spec from spack.package import (
import spack.util.environment EnvironmentModifications,
import spack.util.executable Executable,
import spack.util.prefix Prefix,
from spack.directives import build_system, depends_on, extends Spec,
from spack.multimethod import when build_system,
depends_on,
extends,
when,
)
class LuaPackage(spack.package_base.PackageBase): class LuaPackage(spack.package_base.PackageBase):
@ -40,11 +44,11 @@ class LuaPackage(spack.package_base.PackageBase):
@property @property
def lua(self): def lua(self):
return spack.util.executable.Executable(self.spec["lua-lang"].prefix.bin.lua) return Executable(self.spec["lua-lang"].prefix.bin.lua)
@property @property
def luarocks(self): def luarocks(self):
lr = spack.util.executable.Executable(self.spec["lua-lang"].prefix.bin.luarocks) lr = Executable(self.spec["lua-lang"].prefix.bin.luarocks)
return lr return lr
@ -58,9 +62,7 @@ class LuaBuilder(spack.builder.Builder):
#: Names associated with package attributes in the old build-system format #: Names associated with package attributes in the old build-system format
legacy_attributes = () legacy_attributes = ()
def unpack( def unpack(self, pkg: LuaPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: LuaPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
if os.path.splitext(pkg.stage.archive_file)[1] == ".rock": if os.path.splitext(pkg.stage.archive_file)[1] == ".rock":
directory = pkg.luarocks("unpack", pkg.stage.archive_file, output=str) directory = pkg.luarocks("unpack", pkg.stage.archive_file, output=str)
dirlines = directory.split("\n") dirlines = directory.split("\n")
@ -71,9 +73,7 @@ def unpack(
def _generate_tree_line(name, prefix): def _generate_tree_line(name, prefix):
return """{{ name = "{name}", root = "{prefix}" }};""".format(name=name, prefix=prefix) return """{{ name = "{name}", root = "{prefix}" }};""".format(name=name, prefix=prefix)
def generate_luarocks_config( def generate_luarocks_config(self, pkg: LuaPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: LuaPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
spec = self.pkg.spec spec = self.pkg.spec
table_entries = [] table_entries = []
for d in spec.traverse(deptype=("build", "run")): for d in spec.traverse(deptype=("build", "run")):
@ -92,18 +92,14 @@ def generate_luarocks_config(
) )
) )
def preprocess( def preprocess(self, pkg: LuaPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: LuaPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Override this to preprocess source before building with luarocks""" """Override this to preprocess source before building with luarocks"""
pass pass
def luarocks_args(self): def luarocks_args(self):
return [] return []
def install( def install(self, pkg: LuaPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: LuaPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
rock = "." rock = "."
specs = find(".", "*.rockspec", recursive=False) specs = find(".", "*.rockspec", recursive=False)
if specs: if specs:
@ -115,7 +111,5 @@ def install(
def _luarocks_config_path(self): def _luarocks_config_path(self):
return os.path.join(self.pkg.stage.source_path, "spack_luarocks.lua") return os.path.join(self.pkg.stage.source_path, "spack_luarocks.lua")
def setup_build_environment( def setup_build_environment(self, env: EnvironmentModifications) -> None:
self, env: spack.util.environment.EnvironmentModifications
) -> None:
env.set("LUAROCKS_CONFIG", self._luarocks_config_path()) env.set("LUAROCKS_CONFIG", self._luarocks_config_path())

View File

@ -3,15 +3,18 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
from typing import List from typing import List
import llnl.util.filesystem as fs
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.phase_callbacks from spack.package import (
import spack.spec Prefix,
import spack.util.prefix Spec,
from spack.directives import build_system, conflicts, depends_on build_system,
from spack.multimethod import when conflicts,
depends_on,
run_after,
when,
working_dir,
)
from ._checks import ( from ._checks import (
BuilderWithDefaults, BuilderWithDefaults,
@ -97,42 +100,36 @@ def build_directory(self) -> str:
"""Return the directory containing the main Makefile.""" """Return the directory containing the main Makefile."""
return self.pkg.stage.source_path return self.pkg.stage.source_path
def edit( def edit(self, pkg: MakefilePackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: MakefilePackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Edit the Makefile before calling make. The default is a no-op.""" """Edit the Makefile before calling make. The default is a no-op."""
pass pass
def build( def build(self, pkg: MakefilePackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: MakefilePackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run "make" on the build targets specified by the builder.""" """Run "make" on the build targets specified by the builder."""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.make(*self.build_targets) pkg.module.make(*self.build_targets)
def install( def install(self, pkg: MakefilePackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: MakefilePackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run "make" on the install targets specified by the builder.""" """Run "make" on the install targets specified by the builder."""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.make(*self.install_targets) pkg.module.make(*self.install_targets)
spack.phase_callbacks.run_after("build")(execute_build_time_tests) run_after("build")(execute_build_time_tests)
def check(self) -> None: def check(self) -> None:
"""Run "make" on the ``test`` and ``check`` targets, if found.""" """Run "make" on the ``test`` and ``check`` targets, if found."""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
self.pkg._if_make_target_execute("test") self.pkg._if_make_target_execute("test")
self.pkg._if_make_target_execute("check") self.pkg._if_make_target_execute("check")
spack.phase_callbacks.run_after("install")(execute_install_time_tests) run_after("install")(execute_install_time_tests)
def installcheck(self) -> None: def installcheck(self) -> None:
"""Searches the Makefile for an ``installcheck`` target """Searches the Makefile for an ``installcheck`` target
and runs it if found. and runs it if found.
""" """
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
self.pkg._if_make_target_execute("installcheck") self.pkg._if_make_target_execute("installcheck")
# On macOS, force rpaths for shared library IDs and remove duplicate rpaths # On macOS, force rpaths for shared library IDs and remove duplicate rpaths
spack.phase_callbacks.run_after("install", when="platform=darwin")(apply_macos_rpath_fixups) run_after("install", when="platform=darwin")(apply_macos_rpath_fixups)

View File

@ -1,15 +1,18 @@
# Copyright Spack Project Developers. See COPYRIGHT file for details. # Copyright Spack Project Developers. See COPYRIGHT file for details.
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import llnl.util.filesystem as fs
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.spec from spack.package import (
import spack.util.prefix Prefix,
from spack.directives import build_system, depends_on Spec,
from spack.multimethod import when build_system,
from spack.util.executable import which depends_on,
install_tree,
when,
which,
working_dir,
)
from ._checks import BuilderWithDefaults from ._checks import BuilderWithDefaults
@ -60,20 +63,16 @@ def build_args(self):
"""List of args to pass to build phase.""" """List of args to pass to build phase."""
return [] return []
def build( def build(self, pkg: MavenPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: MavenPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Compile code and package into a JAR file.""" """Compile code and package into a JAR file."""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
mvn = which("mvn", required=True) mvn = which("mvn", required=True)
if self.pkg.run_tests: if self.pkg.run_tests:
mvn("verify", *self.build_args()) mvn("verify", *self.build_args())
else: else:
mvn("package", "-DskipTests", *self.build_args()) mvn("package", "-DskipTests", *self.build_args())
def install( def install(self, pkg: MavenPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: MavenPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Copy to installation prefix.""" """Copy to installation prefix."""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
fs.install_tree(".", prefix) install_tree(".", prefix)

View File

@ -4,15 +4,19 @@
import os import os
from typing import List from typing import List
import llnl.util.filesystem as fs
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.phase_callbacks from spack.package import (
import spack.spec Prefix,
import spack.util.prefix Spec,
from spack.directives import build_system, conflicts, depends_on, variant build_system,
from spack.multimethod import when conflicts,
depends_on,
run_after,
variant,
when,
working_dir,
)
from ._checks import BuilderWithDefaults, execute_build_time_tests from ._checks import BuilderWithDefaults, execute_build_time_tests
@ -190,9 +194,7 @@ def meson_args(self) -> List[str]:
""" """
return [] return []
def meson( def meson(self, pkg: MesonPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: MesonPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run ``meson`` in the build directory""" """Run ``meson`` in the build directory"""
options = [] options = []
if self.spec["meson"].satisfies("@0.64:"): if self.spec["meson"].satisfies("@0.64:"):
@ -200,29 +202,25 @@ def meson(
options.append(os.path.abspath(self.root_mesonlists_dir)) options.append(os.path.abspath(self.root_mesonlists_dir))
options += self.std_meson_args options += self.std_meson_args
options += self.meson_args() options += self.meson_args()
with fs.working_dir(self.build_directory, create=True): with working_dir(self.build_directory, create=True):
pkg.module.meson(*options) pkg.module.meson(*options)
def build( def build(self, pkg: MesonPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: MesonPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Make the build targets""" """Make the build targets"""
options = ["-v"] options = ["-v"]
options += self.build_targets options += self.build_targets
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.ninja(*options) pkg.module.ninja(*options)
def install( def install(self, pkg: MesonPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: MesonPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Make the install targets""" """Make the install targets"""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.ninja(*self.install_targets) pkg.module.ninja(*self.install_targets)
spack.phase_callbacks.run_after("build")(execute_build_time_tests) run_after("build")(execute_build_time_tests)
def check(self) -> None: def check(self) -> None:
"""Search Meson-generated files for the target ``test`` and run it if found.""" """Search Meson-generated files for the target ``test`` and run it if found."""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
self.pkg._if_ninja_target_execute("test") self.pkg._if_ninja_target_execute("test")
self.pkg._if_ninja_target_execute("check") self.pkg._if_ninja_target_execute("check")

View File

@ -7,9 +7,7 @@
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.spec from spack.package import Prefix, Spec, build_system, conflicts, working_dir
import spack.util.prefix
from spack.directives import build_system, conflicts
from ._checks import BuilderWithDefaults from ._checks import BuilderWithDefaults
@ -105,23 +103,19 @@ def msbuild_install_args(self):
as `msbuild_args` by default.""" as `msbuild_args` by default."""
return self.msbuild_args() return self.msbuild_args()
def build( def build(self, pkg: MSBuildPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: MSBuildPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run "msbuild" on the build targets specified by the builder.""" """Run "msbuild" on the build targets specified by the builder."""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.msbuild( pkg.module.msbuild(
*self.std_msbuild_args, *self.std_msbuild_args,
*self.msbuild_args(), *self.msbuild_args(),
self.define_targets(*self.build_targets), self.define_targets(*self.build_targets),
) )
def install( def install(self, pkg: MSBuildPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: MSBuildPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run "msbuild" on the install targets specified by the builder. """Run "msbuild" on the install targets specified by the builder.
This is INSTALL by default""" This is INSTALL by default"""
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.msbuild( pkg.module.msbuild(
*self.msbuild_install_args(), self.define_targets(*self.install_targets) *self.msbuild_install_args(), self.define_targets(*self.install_targets)
) )

View File

@ -7,9 +7,7 @@
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.spec from spack.package import Prefix, Spec, build_system, conflicts, working_dir
import spack.util.prefix
from spack.directives import build_system, conflicts
from ._checks import BuilderWithDefaults from ._checks import BuilderWithDefaults
@ -125,20 +123,16 @@ def nmake_install_args(self):
Individual packages should override to specify NMake args to command line""" Individual packages should override to specify NMake args to command line"""
return [] return []
def build( def build(self, pkg: NMakePackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: NMakePackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run "nmake" on the build targets specified by the builder.""" """Run "nmake" on the build targets specified by the builder."""
opts = self.std_nmake_args opts = self.std_nmake_args
opts += self.nmake_args() opts += self.nmake_args()
if self.makefile_name: if self.makefile_name:
opts.append("/F{}".format(self.makefile_name)) opts.append("/F{}".format(self.makefile_name))
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.nmake(*opts, *self.build_targets, ignore_quotes=self.ignore_quotes) pkg.module.nmake(*opts, *self.build_targets, ignore_quotes=self.ignore_quotes)
def install( def install(self, pkg: NMakePackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: NMakePackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run "nmake" on the install targets specified by the builder. """Run "nmake" on the install targets specified by the builder.
This is INSTALL by default""" This is INSTALL by default"""
opts = self.std_nmake_args opts = self.std_nmake_args
@ -147,5 +141,5 @@ def install(
if self.makefile_name: if self.makefile_name:
opts.append("/F{}".format(self.makefile_name)) opts.append("/F{}".format(self.makefile_name))
opts.append(self.define("PREFIX", fs.windows_sfn(prefix))) opts.append(self.define("PREFIX", fs.windows_sfn(prefix)))
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.nmake(*opts, *self.install_targets, ignore_quotes=self.ignore_quotes) pkg.module.nmake(*opts, *self.install_targets, ignore_quotes=self.ignore_quotes)

View File

@ -3,11 +3,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.spec from spack.package import EnvironmentModifications, Prefix, Spec, build_system, extends, when
import spack.util.environment
import spack.util.prefix
from spack.directives import build_system, extends
from spack.multimethod import when
from ._checks import BuilderWithDefaults from ._checks import BuilderWithDefaults
@ -45,9 +41,7 @@ class OctaveBuilder(BuilderWithDefaults):
#: Names associated with package attributes in the old build-system format #: Names associated with package attributes in the old build-system format
legacy_attributes = () legacy_attributes = ()
def install( def install(self, pkg: OctavePackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: OctavePackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Install the package from the archive file""" """Install the package from the archive file"""
pkg.module.octave( pkg.module.octave(
"--quiet", "--quiet",
@ -58,9 +52,7 @@ def install(
"pkg prefix %s; pkg install %s" % (prefix, self.pkg.stage.archive_file), "pkg prefix %s; pkg install %s" % (prefix, self.pkg.stage.archive_file),
) )
def setup_build_environment( def setup_build_environment(self, env: EnvironmentModifications) -> None:
self, env: spack.util.environment.EnvironmentModifications
) -> None:
# octave does not like those environment variables to be set: # octave does not like those environment variables to be set:
env.unset("CC") env.unset("CC")
env.unset("CXX") env.unset("CXX")

View File

@ -7,16 +7,25 @@
import shutil import shutil
from os.path import basename, isdir from os.path import basename, isdir
from llnl.util import tty
from llnl.util.filesystem import HeaderList, LibraryList, find_libraries, join_path, mkdirp
from llnl.util.link_tree import LinkTree from llnl.util.link_tree import LinkTree
import spack.util.path import spack.util.path
from spack.build_environment import dso_suffix from spack.build_environment import dso_suffix
from spack.directives import conflicts, license, redistribute, variant from spack.package import (
from spack.error import InstallError EnvironmentModifications,
from spack.util.environment import EnvironmentModifications Executable,
from spack.util.executable import Executable HeaderList,
InstallError,
LibraryList,
conflicts,
find_libraries,
join_path,
license,
mkdirp,
redistribute,
tty,
variant,
)
from .generic import Package from .generic import Package

View File

@ -4,18 +4,24 @@
import os import os
from typing import Iterable from typing import Iterable
from llnl.util.filesystem import filter_file, find
from llnl.util.lang import memoized from llnl.util.lang import memoized
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.phase_callbacks from spack.package import (
import spack.spec Executable,
import spack.util.prefix Prefix,
from spack.directives import build_system, depends_on, extends SkipTest,
from spack.install_test import SkipTest, test_part Spec,
from spack.multimethod import when build_system,
from spack.util.executable import Executable depends_on,
extends,
filter_file,
find,
run_after,
test_part,
when,
)
from ._checks import BuilderWithDefaults, execute_build_time_tests from ._checks import BuilderWithDefaults, execute_build_time_tests
@ -151,9 +157,7 @@ def configure_args(self):
""" """
return [] return []
def configure( def configure(self, pkg: PerlPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: PerlPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run Makefile.PL or Build.PL with arguments consisting of """Run Makefile.PL or Build.PL with arguments consisting of
an appropriate installation base directory followed by the an appropriate installation base directory followed by the
list returned by :py:meth:`~.PerlBuilder.configure_args`. list returned by :py:meth:`~.PerlBuilder.configure_args`.
@ -170,28 +174,24 @@ def configure(
# Build.PL may be too long causing the build to fail. Patching the shebang # Build.PL may be too long causing the build to fail. Patching the shebang
# does not happen until after install so set '/usr/bin/env perl' here in # does not happen until after install so set '/usr/bin/env perl' here in
# the Build script. # the Build script.
@spack.phase_callbacks.run_after("configure") @run_after("configure")
def fix_shebang(self): def fix_shebang(self):
if self.build_method == "Build.PL": if self.build_method == "Build.PL":
pattern = "#!{0}".format(self.spec["perl"].command.path) pattern = "#!{0}".format(self.spec["perl"].command.path)
repl = "#!/usr/bin/env perl" repl = "#!/usr/bin/env perl"
filter_file(pattern, repl, "Build", backup=False) filter_file(pattern, repl, "Build", backup=False)
def build( def build(self, pkg: PerlPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: PerlPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Builds a Perl package.""" """Builds a Perl package."""
self.build_executable() self.build_executable()
# Ensure that tests run after build (if requested): # Ensure that tests run after build (if requested):
spack.phase_callbacks.run_after("build")(execute_build_time_tests) run_after("build")(execute_build_time_tests)
def check(self): def check(self):
"""Runs built-in tests of a Perl package.""" """Runs built-in tests of a Perl package."""
self.build_executable("test") self.build_executable("test")
def install( def install(self, pkg: PerlPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: PerlPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Installs a Perl package.""" """Installs a Perl package."""
self.build_executable("install") self.build_executable("install")

View File

@ -13,27 +13,37 @@
import archspec import archspec
import llnl.util.filesystem as fs import llnl.util.filesystem as fs
import llnl.util.tty as tty
from llnl.util.filesystem import HeaderList, LibraryList, join_path
from llnl.util.lang import ClassProperty, classproperty, match_predicate from llnl.util.lang import ClassProperty, classproperty, match_predicate
import spack.builder import spack.builder
import spack.config import spack.config
import spack.deptypes as dt import spack.deptypes as dt
import spack.detection import spack.detection
import spack.multimethod
import spack.package_base import spack.package_base
import spack.phase_callbacks
import spack.platforms import spack.platforms
import spack.repo import spack.repo
import spack.spec import spack.spec
import spack.store import spack.store
import spack.util.prefix from spack.package import (
from spack.directives import build_system, depends_on, extends HeaderList,
from spack.error import NoHeadersError, NoLibrariesError LibraryList,
from spack.install_test import test_part NoHeadersError,
from spack.spec import Spec NoLibrariesError,
from spack.util.prefix import Prefix Prefix,
Spec,
build_system,
depends_on,
extends,
filter_file,
find,
find_all_headers,
join_path,
run_after,
test_part,
tty,
when,
working_dir,
)
from ._checks import BuilderWithDefaults, execute_install_time_tests from ._checks import BuilderWithDefaults, execute_install_time_tests
@ -86,7 +96,7 @@ def import_modules(self) -> Iterable[str]:
# Some Python libraries are packages: collections of modules # Some Python libraries are packages: collections of modules
# distributed in directories containing __init__.py files # distributed in directories containing __init__.py files
for path in fs.find(root, "__init__.py", recursive=True): for path in find(root, "__init__.py", recursive=True):
modules.append( modules.append(
path.replace(root + os.sep, "", 1) path.replace(root + os.sep, "", 1)
.replace(os.sep + "__init__.py", "") .replace(os.sep + "__init__.py", "")
@ -95,7 +105,7 @@ def import_modules(self) -> Iterable[str]:
# Some Python libraries are modules: individual *.py files # Some Python libraries are modules: individual *.py files
# found in the site-packages directory # found in the site-packages directory
for path in fs.find(root, "*.py", recursive=False): for path in find(root, "*.py", recursive=False):
modules.append( modules.append(
path.replace(root + os.sep, "", 1).replace(".py", "").replace("/", ".") path.replace(root + os.sep, "", 1).replace(".py", "").replace("/", ".")
) )
@ -180,7 +190,7 @@ def add_files_to_view(self, view, merge_map, skip_if_exists=True):
if (s.st_mode & 0b111) and fs.has_shebang(src): if (s.st_mode & 0b111) and fs.has_shebang(src):
copied_files[(s.st_dev, s.st_ino)] = dst copied_files[(s.st_dev, s.st_ino)] = dst
shutil.copy2(src, dst) shutil.copy2(src, dst)
fs.filter_file( filter_file(
python.prefix, os.path.abspath(view.get_projection_for_spec(self.spec)), dst python.prefix, os.path.abspath(view.get_projection_for_spec(self.spec)), dst
) )
else: else:
@ -362,7 +372,7 @@ class PythonPackage(PythonExtension):
build_system("python_pip") build_system("python_pip")
with spack.multimethod.when("build_system=python_pip"): with when("build_system=python_pip"):
extends("python") extends("python")
depends_on("py-pip", type="build") depends_on("py-pip", type="build")
# FIXME: technically wheel is only needed when building from source, not when # FIXME: technically wheel is only needed when building from source, not when
@ -395,7 +405,7 @@ def headers(self) -> HeaderList:
platlib = self.prefix.join(python.package.platlib).join(name) platlib = self.prefix.join(python.package.platlib).join(name)
purelib = self.prefix.join(python.package.purelib).join(name) purelib = self.prefix.join(python.package.purelib).join(name)
headers_list = map(fs.find_all_headers, [include, platlib, purelib]) headers_list = map(find_all_headers, [include, platlib, purelib])
headers = functools.reduce(operator.add, headers_list) headers = functools.reduce(operator.add, headers_list)
if headers: if headers:
@ -543,7 +553,7 @@ def install(self, pkg: PythonPackage, spec: Spec, prefix: Prefix) -> None:
else: else:
args.append(".") args.append(".")
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
pip(*args) pip(*args)
spack.phase_callbacks.run_after("install")(execute_install_time_tests) run_after("install")(execute_install_time_tests)

View File

@ -5,10 +5,7 @@
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.phase_callbacks from spack.package import Prefix, Spec, build_system, depends_on, run_after
import spack.spec
import spack.util.prefix
from spack.directives import build_system, depends_on
from ._checks import BuilderWithDefaults, execute_build_time_tests from ._checks import BuilderWithDefaults, execute_build_time_tests
@ -64,23 +61,17 @@ def qmake_args(self):
"""List of arguments passed to qmake.""" """List of arguments passed to qmake."""
return [] return []
def qmake( def qmake(self, pkg: QMakePackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: QMakePackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Run ``qmake`` to configure the project and generate a Makefile.""" """Run ``qmake`` to configure the project and generate a Makefile."""
with working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.qmake(*self.qmake_args()) pkg.module.qmake(*self.qmake_args())
def build( def build(self, pkg: QMakePackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: QMakePackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Make the build targets""" """Make the build targets"""
with working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.make() pkg.module.make()
def install( def install(self, pkg: QMakePackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: QMakePackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Make the install targets""" """Make the install targets"""
with working_dir(self.build_directory): with working_dir(self.build_directory):
pkg.module.make("install") pkg.module.make("install")
@ -90,4 +81,4 @@ def check(self):
with working_dir(self.build_directory): with working_dir(self.build_directory):
self.pkg._if_make_target_execute("check") self.pkg._if_make_target_execute("check")
spack.phase_callbacks.run_after("build")(execute_build_time_tests) run_after("build")(execute_build_time_tests)

View File

@ -3,10 +3,9 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
from typing import Optional, Tuple from typing import Optional, Tuple
from llnl.util.filesystem import mkdirp
from llnl.util.lang import ClassProperty, classproperty from llnl.util.lang import ClassProperty, classproperty
from spack.directives import extends from spack.package import extends, mkdirp
from .generic import GenericBuilder, Package from .generic import GenericBuilder, Package

View File

@ -4,19 +4,24 @@
import os import os
from typing import Optional, Tuple from typing import Optional, Tuple
import llnl.util.filesystem as fs
import llnl.util.tty as tty
from llnl.util.lang import ClassProperty, classproperty from llnl.util.lang import ClassProperty, classproperty
import spack.builder import spack.builder
import spack.spec
import spack.util.prefix
from spack.build_environment import SPACK_NO_PARALLEL_MAKE from spack.build_environment import SPACK_NO_PARALLEL_MAKE
from spack.config import determine_number_of_jobs from spack.package import (
from spack.directives import build_system, extends, maintainers Executable,
Prefix,
ProcessError,
Spec,
build_system,
determine_number_of_jobs,
extends,
maintainers,
tty,
working_dir,
)
from spack.package_base import PackageBase from spack.package_base import PackageBase
from spack.util.environment import env_flag from spack.util.environment import env_flag
from spack.util.executable import Executable, ProcessError
def _homepage(cls: "RacketPackage") -> Optional[str]: def _homepage(cls: "RacketPackage") -> Optional[str]:
@ -76,12 +81,10 @@ def build_directory(self):
ret = os.path.join(ret, self.subdirectory) ret = os.path.join(ret, self.subdirectory)
return ret return ret
def install( def install(self, pkg: RacketPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: RacketPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Install everything from build directory.""" """Install everything from build directory."""
raco = Executable("raco") raco = Executable("raco")
with fs.working_dir(self.build_directory): with working_dir(self.build_directory):
parallel = pkg.parallel and (not env_flag(SPACK_NO_PARALLEL_MAKE)) parallel = pkg.parallel and (not env_flag(SPACK_NO_PARALLEL_MAKE))
name = pkg.racket_name name = pkg.racket_name
assert name is not None, "Racket package name is not set" assert name is not None, "Racket package name is not set"

View File

@ -76,10 +76,14 @@
import os import os
import spack.variant from spack.package import (
from spack.directives import conflicts, depends_on, variant EnvironmentModifications,
any_combination_of,
conflicts,
depends_on,
variant,
)
from spack.package_base import PackageBase from spack.package_base import PackageBase
from spack.util.environment import EnvironmentModifications
class ROCmPackage(PackageBase): class ROCmPackage(PackageBase):
@ -135,7 +139,7 @@ class ROCmPackage(PackageBase):
variant( variant(
"amdgpu_target", "amdgpu_target",
description="AMD GPU architecture", description="AMD GPU architecture",
values=spack.variant.any_combination_of(*amdgpu_targets), values=any_combination_of(*amdgpu_targets),
sticky=True, sticky=True,
when="+rocm", when="+rocm",
) )

View File

@ -5,9 +5,7 @@
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.spec from spack.package import Prefix, Spec, build_system, extends, maintainers
import spack.util.prefix
from spack.directives import build_system, extends, maintainers
from ._checks import BuilderWithDefaults from ._checks import BuilderWithDefaults
@ -44,9 +42,7 @@ class RubyBuilder(BuilderWithDefaults):
#: Names associated with package attributes in the old build-system format #: Names associated with package attributes in the old build-system format
legacy_attributes = () legacy_attributes = ()
def build( def build(self, pkg: RubyPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: RubyPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Build a Ruby gem.""" """Build a Ruby gem."""
# ruby-rake provides both rake.gemspec and Rakefile, but only # ruby-rake provides both rake.gemspec and Rakefile, but only
@ -62,9 +58,7 @@ def build(
# Some Ruby packages only ship `*.gem` files, so nothing to build # Some Ruby packages only ship `*.gem` files, so nothing to build
pass pass
def install( def install(self, pkg: RubyPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: RubyPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Install a Ruby gem. """Install a Ruby gem.
The ruby package sets ``GEM_HOME`` to tell gem where to install to.""" The ruby package sets ``GEM_HOME`` to tell gem where to install to."""

View File

@ -3,10 +3,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.phase_callbacks from spack.package import Prefix, Spec, build_system, depends_on, run_after
import spack.spec
import spack.util.prefix
from spack.directives import build_system, depends_on
from ._checks import BuilderWithDefaults, execute_build_time_tests from ._checks import BuilderWithDefaults, execute_build_time_tests
@ -61,9 +58,7 @@ def build_args(self, spec, prefix):
"""Arguments to pass to build.""" """Arguments to pass to build."""
return [] return []
def build( def build(self, pkg: SConsPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: SConsPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Build the package.""" """Build the package."""
pkg.module.scons(*self.build_args(spec, prefix)) pkg.module.scons(*self.build_args(spec, prefix))
@ -71,9 +66,7 @@ def install_args(self, spec, prefix):
"""Arguments to pass to install.""" """Arguments to pass to install."""
return [] return []
def install( def install(self, pkg: SConsPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: SConsPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Install the package.""" """Install the package."""
pkg.module.scons("install", *self.install_args(spec, prefix)) pkg.module.scons("install", *self.install_args(spec, prefix))
@ -85,4 +78,4 @@ def build_test(self):
""" """
pass pass
spack.phase_callbacks.run_after("build")(execute_build_time_tests) run_after("build")(execute_build_time_tests)

View File

@ -4,18 +4,22 @@
import os import os
import re import re
import llnl.util.tty as tty
from llnl.util.filesystem import find, working_dir
import spack.builder import spack.builder
import spack.install_test
import spack.package_base import spack.package_base
import spack.phase_callbacks from spack.package import (
import spack.spec Executable,
import spack.util.prefix Prefix,
from spack.directives import build_system, depends_on, extends Spec,
from spack.multimethod import when build_system,
from spack.util.executable import Executable depends_on,
extends,
find,
run_after,
test_part,
tty,
when,
working_dir,
)
from ._checks import BuilderWithDefaults, execute_install_time_tests from ._checks import BuilderWithDefaults, execute_install_time_tests
@ -96,7 +100,7 @@ def test_imports(self):
# Make sure we are importing the installed modules, # Make sure we are importing the installed modules,
# not the ones in the source directory # not the ones in the source directory
for module in self.import_modules: for module in self.import_modules:
with spack.install_test.test_part( with test_part(
self, self,
"test_imports_{0}".format(module), "test_imports_{0}".format(module),
purpose="checking import of {0}".format(module), purpose="checking import of {0}".format(module),
@ -133,9 +137,7 @@ class SIPBuilder(BuilderWithDefaults):
build_directory = "build" build_directory = "build"
def configure( def configure(self, pkg: SIPPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: SIPPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Configure the package.""" """Configure the package."""
# https://www.riverbankcomputing.com/static/Docs/sip/command_line_tools.html # https://www.riverbankcomputing.com/static/Docs/sip/command_line_tools.html
@ -153,9 +155,7 @@ def configure_args(self):
"""Arguments to pass to configure.""" """Arguments to pass to configure."""
return [] return []
def build( def build(self, pkg: SIPPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: SIPPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Build the package.""" """Build the package."""
args = self.build_args() args = self.build_args()
@ -166,9 +166,7 @@ def build_args(self):
"""Arguments to pass to build.""" """Arguments to pass to build."""
return [] return []
def install( def install(self, pkg: SIPPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: SIPPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Install the package.""" """Install the package."""
args = self.install_args() args = self.install_args()
@ -179,4 +177,4 @@ def install_args(self):
"""Arguments to pass to install.""" """Arguments to pass to install."""
return [] return []
spack.phase_callbacks.run_after("install")(execute_install_time_tests) run_after("install")(execute_install_time_tests)

View File

@ -5,10 +5,7 @@
import spack.builder import spack.builder
import spack.package_base import spack.package_base
import spack.phase_callbacks from spack.package import Prefix, Spec, build_system, depends_on, run_after
import spack.spec
import spack.util.prefix
from spack.directives import build_system, depends_on
from ._checks import BuilderWithDefaults, execute_build_time_tests, execute_install_time_tests from ._checks import BuilderWithDefaults, execute_build_time_tests, execute_install_time_tests
@ -99,9 +96,7 @@ def waf(self, *args, **kwargs):
with working_dir(self.build_directory): with working_dir(self.build_directory):
self.python("waf", "-j{0}".format(jobs), *args, **kwargs) self.python("waf", "-j{0}".format(jobs), *args, **kwargs)
def configure( def configure(self, pkg: WafPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: WafPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Configures the project.""" """Configures the project."""
args = ["--prefix={0}".format(self.pkg.prefix)] args = ["--prefix={0}".format(self.pkg.prefix)]
args += self.configure_args() args += self.configure_args()
@ -112,9 +107,7 @@ def configure_args(self):
"""Arguments to pass to configure.""" """Arguments to pass to configure."""
return [] return []
def build( def build(self, pkg: WafPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: WafPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Executes the build.""" """Executes the build."""
args = self.build_args() args = self.build_args()
@ -124,9 +117,7 @@ def build_args(self):
"""Arguments to pass to build.""" """Arguments to pass to build."""
return [] return []
def install( def install(self, pkg: WafPackage, spec: Spec, prefix: Prefix) -> None:
self, pkg: WafPackage, spec: spack.spec.Spec, prefix: spack.util.prefix.Prefix
) -> None:
"""Installs the targets on the system.""" """Installs the targets on the system."""
args = self.install_args() args = self.install_args()
@ -144,7 +135,7 @@ def build_test(self):
""" """
pass pass
spack.phase_callbacks.run_after("build")(execute_build_time_tests) run_after("build")(execute_build_time_tests)
def install_test(self): def install_test(self):
"""Run unit tests after install. """Run unit tests after install.
@ -154,4 +145,4 @@ def install_test(self):
""" """
pass pass
spack.phase_callbacks.run_after("install")(execute_install_time_tests) run_after("install")(execute_install_time_tests)