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.
|
# Currently only make is supported.
|
||||||
spack.cmd.require_active_env(cmd_name="env depfile")
|
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
|
# 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.
|
# 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
|
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"))
|
template = spack.tengine.make_environment().get_template(os.path.join("depfile", "Makefile"))
|
||||||
model = depfile.MakefileModel.from_env(
|
model = depfile.MakefileModel.from_env(
|
||||||
ev.active_environment(),
|
env,
|
||||||
filter_specs=filter_specs,
|
filter_specs=filter_specs,
|
||||||
pkg_buildcache=depfile.UseBuildCache.from_string(args.use_buildcache[0]),
|
pkg_buildcache=depfile.UseBuildCache.from_string(args.use_buildcache[0]),
|
||||||
dep_buildcache=depfile.UseBuildCache.from_string(args.use_buildcache[1]),
|
dep_buildcache=depfile.UseBuildCache.from_string(args.use_buildcache[1]),
|
||||||
make_prefix=args.make_prefix,
|
make_prefix=args.make_prefix,
|
||||||
jobserver=args.jobserver,
|
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())
|
makefile = template.render(model.to_dict())
|
||||||
|
|
||||||
# Finally write to stdout/file.
|
# Finally write to stdout/file.
|
||||||
|
|
|
@ -232,6 +232,10 @@ def to_dict(self):
|
||||||
"pkg_ids": " ".join(self.all_pkg_identifiers),
|
"pkg_ids": " ".join(self.all_pkg_identifiers),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def empty(self):
|
||||||
|
return len(self.roots) == 0
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_env(
|
def from_env(
|
||||||
env: ev.Environment,
|
env: ev.Environment,
|
||||||
|
@ -254,15 +258,10 @@ def from_env(
|
||||||
jobserver: when enabled, make will invoke Spack with jobserver support. For
|
jobserver: when enabled, make will invoke Spack with jobserver support. For
|
||||||
dry-run this should be disabled.
|
dry-run this should be disabled.
|
||||||
"""
|
"""
|
||||||
# If no specs are provided as a filter, build all the specs in the environment.
|
roots = env.all_matching_specs(*filter_specs) if filter_specs else env.concrete_roots()
|
||||||
if filter_specs:
|
|
||||||
entrypoints = [env.matching_spec(s) for s in filter_specs]
|
|
||||||
else:
|
|
||||||
entrypoints = [s for _, s in env.concretized_specs()]
|
|
||||||
|
|
||||||
visitor = DepfileSpecVisitor(pkg_buildcache, dep_buildcache)
|
visitor = DepfileSpecVisitor(pkg_buildcache, dep_buildcache)
|
||||||
traverse.traverse_breadth_first_with_visitor(
|
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
|
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():
|
def test_unify_when_possible_works_around_conflicts():
|
||||||
e = ev.create("coconcretization")
|
e = ev.create("coconcretization")
|
||||||
e.unify = "when_possible"
|
e.unify = "when_possible"
|
||||||
|
|
|
@ -8,7 +8,7 @@ SPACK_INSTALL_FLAGS ?=
|
||||||
|
|
||||||
{{ all_target }}: {{ env_target }}
|
{{ all_target }}: {{ env_target }}
|
||||||
|
|
||||||
{{ env_target }}: {{ root_install_targets }}
|
{{ env_target }}: {{ root_install_targets }} | {{ dirs_target }}
|
||||||
@touch $@
|
@touch $@
|
||||||
|
|
||||||
{{ dirs_target }}:
|
{{ dirs_target }}:
|
||||||
|
|
Loading…
Reference in a new issue