depfile: deal with empty / non-concrete env (#40816)
This commit is contained in:
parent
dbf21bf843
commit
8b0ab67de4
4 changed files with 36 additions and 10 deletions
|
@ -672,18 +672,31 @@ def env_depfile(args):
|
|||
# Currently only make is supported.
|
||||
spack.cmd.require_active_env(cmd_name="env depfile")
|
||||
|
||||
env = ev.active_environment()
|
||||
|
||||
# What things do we build when running make? By default, we build the
|
||||
# root specs. If specific specs are provided as input, we build those.
|
||||
filter_specs = spack.cmd.parse_specs(args.specs) if args.specs else None
|
||||
template = spack.tengine.make_environment().get_template(os.path.join("depfile", "Makefile"))
|
||||
model = depfile.MakefileModel.from_env(
|
||||
ev.active_environment(),
|
||||
env,
|
||||
filter_specs=filter_specs,
|
||||
pkg_buildcache=depfile.UseBuildCache.from_string(args.use_buildcache[0]),
|
||||
dep_buildcache=depfile.UseBuildCache.from_string(args.use_buildcache[1]),
|
||||
make_prefix=args.make_prefix,
|
||||
jobserver=args.jobserver,
|
||||
)
|
||||
|
||||
# Warn in case we're generating a depfile for an empty environment. We don't automatically
|
||||
# concretize; the user should do that explicitly. Could be changed in the future if requested.
|
||||
if model.empty:
|
||||
if not env.user_specs:
|
||||
tty.warn("no specs in the environment")
|
||||
elif filter_specs is not None:
|
||||
tty.warn("no concrete matching specs found in environment")
|
||||
else:
|
||||
tty.warn("environment is not concretized. Run `spack concretize` first")
|
||||
|
||||
makefile = template.render(model.to_dict())
|
||||
|
||||
# Finally write to stdout/file.
|
||||
|
|
|
@ -232,6 +232,10 @@ def to_dict(self):
|
|||
"pkg_ids": " ".join(self.all_pkg_identifiers),
|
||||
}
|
||||
|
||||
@property
|
||||
def empty(self):
|
||||
return len(self.roots) == 0
|
||||
|
||||
@staticmethod
|
||||
def from_env(
|
||||
env: ev.Environment,
|
||||
|
@ -254,15 +258,10 @@ def from_env(
|
|||
jobserver: when enabled, make will invoke Spack with jobserver support. For
|
||||
dry-run this should be disabled.
|
||||
"""
|
||||
# If no specs are provided as a filter, build all the specs in the environment.
|
||||
if filter_specs:
|
||||
entrypoints = [env.matching_spec(s) for s in filter_specs]
|
||||
else:
|
||||
entrypoints = [s for _, s in env.concretized_specs()]
|
||||
|
||||
roots = env.all_matching_specs(*filter_specs) if filter_specs else env.concrete_roots()
|
||||
visitor = DepfileSpecVisitor(pkg_buildcache, dep_buildcache)
|
||||
traverse.traverse_breadth_first_with_visitor(
|
||||
entrypoints, traverse.CoverNodesVisitor(visitor, key=lambda s: s.dag_hash())
|
||||
roots, traverse.CoverNodesVisitor(visitor, key=lambda s: s.dag_hash())
|
||||
)
|
||||
|
||||
return MakefileModel(env, entrypoints, visitor.adjacency_list, make_prefix, jobserver)
|
||||
return MakefileModel(env, roots, visitor.adjacency_list, make_prefix, jobserver)
|
||||
|
|
|
@ -3382,6 +3382,20 @@ def test_spack_package_ids_variable(tmpdir, mock_packages):
|
|||
assert "post-install: {}".format(s.dag_hash()) in out
|
||||
|
||||
|
||||
def test_depfile_empty_does_not_error(tmp_path):
|
||||
# For empty environments Spack should create a depfile that does nothing
|
||||
make = Executable("make")
|
||||
makefile = str(tmp_path / "Makefile")
|
||||
|
||||
env("create", "test")
|
||||
with ev.read("test"):
|
||||
env("depfile", "-o", makefile)
|
||||
|
||||
make("-f", makefile)
|
||||
|
||||
assert make.returncode == 0
|
||||
|
||||
|
||||
def test_unify_when_possible_works_around_conflicts():
|
||||
e = ev.create("coconcretization")
|
||||
e.unify = "when_possible"
|
||||
|
|
|
@ -8,7 +8,7 @@ SPACK_INSTALL_FLAGS ?=
|
|||
|
||||
{{ all_target }}: {{ env_target }}
|
||||
|
||||
{{ env_target }}: {{ root_install_targets }}
|
||||
{{ env_target }}: {{ root_install_targets }} | {{ dirs_target }}
|
||||
@touch $@
|
||||
|
||||
{{ dirs_target }}:
|
||||
|
|
Loading…
Reference in a new issue