Allow 'spack external find' to find executables on the system path (#22091)
Co-authored-by: Lou Lawrence <lou.lawrence@kitware.com>
This commit is contained in:
committed by
Peter Scheibel
parent
fb0e91c534
commit
d4d101f57e
@@ -9,8 +9,10 @@
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
|
||||
import llnl.util.filesystem
|
||||
import llnl.util.tty
|
||||
|
||||
@@ -73,6 +75,8 @@ def by_executable(packages_to_check, path_hints=None):
|
||||
for pkg in packages_to_check:
|
||||
if hasattr(pkg, 'executables'):
|
||||
for exe in pkg.executables:
|
||||
if sys.platform == 'win32':
|
||||
exe = exe.replace('$', r'\.exe$')
|
||||
exe_pattern_to_pkgs[exe].append(pkg)
|
||||
|
||||
pkg_to_found_exes = collections.defaultdict(set)
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
import llnl.util.lock as lk
|
||||
import llnl.util.tty as tty
|
||||
from llnl.util.tty.color import colorize
|
||||
from llnl.util.tty.log import log_output
|
||||
from llnl.util.tty.log import log_output, winlog
|
||||
|
||||
import spack.binary_distribution as binary_distribution
|
||||
import spack.compilers
|
||||
@@ -1936,61 +1936,80 @@ def _real_install(self):
|
||||
|
||||
# Spawn a daemon that reads from a pipe and redirects
|
||||
# everything to log_path, and provide the phase for logging
|
||||
for i, (phase_name, phase_attr) in enumerate(zip(
|
||||
pkg.phases, pkg._InstallPhase_phases)):
|
||||
if sys.platform != 'win32':
|
||||
for i, (phase_name, phase_attr) in enumerate(zip(
|
||||
pkg.phases, pkg._InstallPhase_phases)):
|
||||
|
||||
# Keep a log file for each phase
|
||||
log_dir = os.path.dirname(pkg.log_path)
|
||||
log_file = "spack-build-%02d-%s-out.txt" % (
|
||||
i + 1, phase_name.lower()
|
||||
)
|
||||
log_file = os.path.join(log_dir, log_file)
|
||||
|
||||
try:
|
||||
# DEBUGGING TIP - to debug this section, insert an IPython
|
||||
# embed here, and run the sections below without log capture
|
||||
log_contextmanager = log_output(
|
||||
log_file,
|
||||
self.echo,
|
||||
True,
|
||||
env=self.unmodified_env,
|
||||
filter_fn=self.filter_fn
|
||||
# Keep a log file for each phase
|
||||
log_dir = os.path.dirname(pkg.log_path)
|
||||
log_file = "spack-build-%02d-%s-out.txt" % (
|
||||
i + 1, phase_name.lower()
|
||||
)
|
||||
log_file = os.path.join(log_dir, log_file)
|
||||
|
||||
with log_contextmanager as logger:
|
||||
with logger.force_echo():
|
||||
inner_debug_level = tty.debug_level()
|
||||
tty.set_debug(debug_level)
|
||||
tty.msg(
|
||||
"{0} Executing phase: '{1}'" .format(
|
||||
self.pre,
|
||||
phase_name
|
||||
try:
|
||||
# DEBUGGING TIP - to debug this section, insert an IPython
|
||||
# embed here, and run the sections below without log capture
|
||||
log_contextmanager = log_output(
|
||||
log_file,
|
||||
self.echo,
|
||||
True,
|
||||
env=self.unmodified_env,
|
||||
filter_fn=self.filter_fn
|
||||
)
|
||||
|
||||
with log_contextmanager as logger:
|
||||
with logger.force_echo():
|
||||
inner_debug_level = tty.debug_level()
|
||||
tty.set_debug(debug_level)
|
||||
tty.msg(
|
||||
"{0} Executing phase: '{1}'" .format(
|
||||
self.pre,
|
||||
phase_name
|
||||
)
|
||||
)
|
||||
)
|
||||
tty.set_debug(inner_debug_level)
|
||||
tty.set_debug(inner_debug_level)
|
||||
|
||||
# Redirect stdout and stderr to daemon pipe
|
||||
phase = getattr(pkg, phase_attr)
|
||||
self.timer.phase(phase_name)
|
||||
|
||||
# Catch any errors to report to logging
|
||||
phase(pkg.spec, pkg.prefix)
|
||||
spack.hooks.on_phase_success(pkg, phase_name, log_file)
|
||||
|
||||
except BaseException:
|
||||
combine_phase_logs(pkg.phase_log_files, pkg.log_path)
|
||||
spack.hooks.on_phase_error(pkg, phase_name, log_file)
|
||||
|
||||
# phase error indicates install error
|
||||
spack.hooks.on_install_failure(pkg.spec)
|
||||
raise
|
||||
|
||||
# We assume loggers share echo True/False
|
||||
self.echo = logger.echo
|
||||
else:
|
||||
with winlog(pkg.log_path, True, True,
|
||||
env=self.unmodified_env) as logger:
|
||||
|
||||
for phase_name, phase_attr in zip(
|
||||
pkg.phases, pkg._InstallPhase_phases):
|
||||
|
||||
# with logger.force_echo():
|
||||
# inner_debug_level = tty.debug_level()
|
||||
# tty.set_debug(debug_level)
|
||||
# tty.msg("{0} Executing phase: '{1}'"
|
||||
# .format(pre, phase_name))
|
||||
# tty.set_debug(inner_debug_level)
|
||||
|
||||
# Redirect stdout and stderr to daemon pipe
|
||||
phase = getattr(pkg, phase_attr)
|
||||
self.timer.phase(phase_name)
|
||||
|
||||
# Catch any errors to report to logging
|
||||
phase(pkg.spec, pkg.prefix)
|
||||
spack.hooks.on_phase_success(pkg, phase_name, log_file)
|
||||
|
||||
except BaseException:
|
||||
combine_phase_logs(pkg.phase_log_files, pkg.log_path)
|
||||
spack.hooks.on_phase_error(pkg, phase_name, log_file)
|
||||
|
||||
# phase error indicates install error
|
||||
spack.hooks.on_install_failure(pkg.spec)
|
||||
raise
|
||||
|
||||
# We assume loggers share echo True/False
|
||||
self.echo = logger.echo
|
||||
|
||||
# After log, we can get all output/error files from the package stage
|
||||
combine_phase_logs(pkg.phase_log_files, pkg.log_path)
|
||||
log(pkg)
|
||||
if sys.platform != 'win32':
|
||||
# After log, we can get all output/error files from the package stage
|
||||
combine_phase_logs(pkg.phase_log_files, pkg.log_path)
|
||||
log(pkg)
|
||||
|
||||
|
||||
def build_process(pkg, install_args):
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
import llnl.util.tty as tty
|
||||
import llnl.util.tty.colify
|
||||
import llnl.util.tty.color as color
|
||||
from llnl.util.tty.log import log_output
|
||||
from llnl.util.tty.log import log_output, winlog
|
||||
|
||||
import spack
|
||||
import spack.cmd
|
||||
@@ -494,6 +494,7 @@ def setup_main_options(args):
|
||||
|
||||
# debug must be set first so that it can even affect behavior of
|
||||
# errors raised by spack.config.
|
||||
tty.debug(spack.config.config)
|
||||
if args.debug:
|
||||
spack.error.debug = True
|
||||
spack.util.debug.register_interrupt_handler()
|
||||
@@ -611,9 +612,14 @@ def __call__(self, *argv, **kwargs):
|
||||
|
||||
out = StringIO()
|
||||
try:
|
||||
with log_output(out):
|
||||
self.returncode = _invoke_command(
|
||||
self.command, self.parser, args, unknown)
|
||||
if sys.platform == 'win32':
|
||||
with winlog(out):
|
||||
self.returncode = _invoke_command(
|
||||
self.command, self.parser, args, unknown)
|
||||
else:
|
||||
with log_output(out):
|
||||
self.returncode = _invoke_command(
|
||||
self.command, self.parser, args, unknown)
|
||||
|
||||
except SystemExit as e:
|
||||
self.returncode = e.code
|
||||
|
||||
@@ -22,6 +22,8 @@ class Executable(object):
|
||||
"""Class representing a program that can be run on the command line."""
|
||||
|
||||
def __init__(self, name):
|
||||
if sys.platform == 'win32':
|
||||
name = name.replace('\\', '/')
|
||||
self.exe = shlex.split(str(name))
|
||||
self.default_env = {}
|
||||
from spack.util.environment import EnvironmentModifications # no cycle
|
||||
|
||||
Reference in New Issue
Block a user