From bfa54da2929a6dfea14e04eca036b9409a5aa68b Mon Sep 17 00:00:00 2001 From: Peter Scheibel Date: Thu, 11 May 2023 00:17:16 -0700 Subject: Allow clingo to enforce flags when they appear in requirements (#37584) Flags are encoded differently from other variants, and they need a choice rule to ensure clingo has a choice to impose (or not) a constraint. --- lib/spack/spack/solver/asp.py | 11 ++++++++--- lib/spack/spack/solver/concretize.lp | 13 +++++++++++++ lib/spack/spack/test/concretize_requirements.py | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 816ce660be..359684db47 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -2463,11 +2463,16 @@ class SpecBuilder(object): # add flags from each source, lowest to highest precedence for name in sorted_sources: - source = self._specs[name] if name in self._hash_specs else cmd_specs[name] - extend_flag_list(from_sources, source.compiler_flags.get(flag_type, [])) + all_src_flags = list() + per_pkg_sources = [self._specs[name]] + if name in cmd_specs: + per_pkg_sources.append(cmd_specs[name]) + for source in per_pkg_sources: + all_src_flags.extend(source.compiler_flags.get(flag_type, [])) + extend_flag_list(from_sources, all_src_flags) # compiler flags from compilers config are lowest precedence - ordered_compiler_flags = from_compiler + from_sources + ordered_compiler_flags = list(llnl.util.lang.dedupe(from_compiler + from_sources)) compiler_flags = spec.compiler_flags.get(flag_type, []) msg = "%s does not equal %s" % (set(compiler_flags), set(ordered_compiler_flags)) diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp index e96e108e0e..0821b68f72 100644 --- a/lib/spack/spack/solver/concretize.lp +++ b/lib/spack/spack/solver/concretize.lp @@ -494,6 +494,19 @@ requirement_group_satisfied(Package, X) :- activate_requirement(Package, X), requirement_group(Package, X). +% TODO: the following two choice rules allow the solver to add compiler +% flags if their only source is from a requirement. This is overly-specific +% and should use a more-generic approach like in https://github.com/spack/spack/pull/37180 +{ attr("node_flag", A1, A2, A3) } :- + requirement_group_member(Y, Package, X), + activate_requirement(Package, X), + imposed_constraint(Y,"node_flag_set", A1, A2, A3). + +{ attr("node_flag_source", A1, A2, A3) } :- + requirement_group_member(Y, Package, X), + activate_requirement(Package, X), + imposed_constraint(Y,"node_flag_source", A1, A2, A3). + requirement_weight(Package, Group, W) :- W = #min { Z : requirement_has_weight(Y, Z), condition_holds(Y), requirement_group_member(Y, Package, Group); diff --git a/lib/spack/spack/test/concretize_requirements.py b/lib/spack/spack/test/concretize_requirements.py index 255447c909..52e831ca01 100644 --- a/lib/spack/spack/test/concretize_requirements.py +++ b/lib/spack/spack/test/concretize_requirements.py @@ -381,6 +381,22 @@ packages: assert s2.satisfies("%gcc+shared") +@pytest.mark.regression("34241") +def test_require_cflags(concretize_scope, test_repo): + """Ensures that flags can be required from configuration.""" + if spack.config.get("config:concretizer") == "original": + pytest.skip("Original concretizer does not support configuration" " requirements") + + conf_str = """\ +packages: + y: + require: cflags="-g" +""" + update_packages_config(conf_str) + spec = Spec("y").concretized() + assert spec.satisfies("cflags=-g") + + def test_requirements_for_package_that_is_not_needed(concretize_scope, test_repo): """Specify requirements for specs that are not concretized or a dependency of a concretized spec (in other words, none of -- cgit v1.2.3-70-g09d2