[bug #42125] Static pattern rules do not support multiple targets

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

[bug #42125] Static pattern rules do not support multiple targets

anonymous
URL:
  <http://savannah.gnu.org/bugs/?42125>

                 Summary: Static pattern rules do not support multiple targets
                 Project: make
            Submitted by: None
            Submitted on: Tue 15 Apr 2014 04:02:29 PM UTC
                Severity: 3 - Normal
              Item Group: Bug
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any
       Component Version: 4.0
        Operating System: POSIX-Based
           Fixed Release: None
           Triage Status: None

    _______________________________________________________

Details:

Makefile allows to create pattern rule with multiple targets, like below. This
is very handy for rules which generates multiple files at once.


%.h %.c : %.idl
        touch $(<:%.idl=%.c) $(<:%.idl=%.h)

I tried to build static pattern rule in similar way, but it do not work - make
reports error "multiple target patterns":


$(IDLS:%.idl=%.c) $(IDLS:%.idl=%.h) : %.h %.c : %.idl
        touch $(<:%.idl=%.c) $(<:%.idl=%.h)

I tested this using make 4.0 on Linux. Please fix this.




    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?42125>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/


_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

[bug #42125] Explicit rules do not support multiple targets

anonymous
Update of bug #42125 (project make):

              Item Group:                     Bug => Enhancement            
           Triage Status:                    None => Medium Effort          
                 Summary: Static pattern rules do not support multiple targets
=> Explicit rules do not support multiple targets

    _______________________________________________________

Follow-up Comment #1:

This is not technically a bug.  A static pattern rule is a form of _explicit
rule_, not an implicit rule such as pattern rule.  Explicit rules do not
support multiple targets being created from a single invocation of the recipe,
although this is a long-requested enhancement.  Looking through the bug
tracker I couldn't find an enhancement for it, though, so I'm leaving this one
here as that request.

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?42125>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/


_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

[bug #42125] Explicit rules do not support multiple targets

anonymous
Follow-up Comment #2, bug #42125 (project make):

There is a space of inputs that is currently disallowed that could support
both multiple rule types:
        1. a single target for each of multiple rules, and
        2. a single rule having multiple targets
for both implicit and explicit rules.

The static pattern syntax could be extended to support implicit pattern rules,
changing
        targets …: target-pattern: prereq-patterns … ; recipe
to
        factors …: factors-pattern[=substitutions …]: prereq-patterns … ;
recipe

This would default to the current behaviour when [=substitutions]: is missing
Also, add support for %% at any place which would form implicit rules from
several factors in the same way that static pattern rules do

The meaning of rules of this form would be as follows

  For each factor, one rule will be generated, that rule may have multiple
targets and multiple prerequisites as well as order-only prerequisites.
Double-percent '%%' will appear in the resulting per-factor rule as a single
percent '%' and thus the resulting per-factor rule will be an implicit rules

  For each per-factor rule, its factor is matched against factors-pattern as
normal but the factors-pattern is substituted by the right-hand side of the
'=' sign as in patsubst in order to define one or more targets of that
per-factor rule.

  If an equal sign '=' is not given then the behaviour is as if the equal sign
is given and the substitution is the factors-pattern is repeated to provide a
one-to-one mapping by default (eg "%.o" behaves as "%.o=%.o"). Thus the
default behaviour is the same as for the existing static pattern syntax

  If an explicit rule is generated with multiple targets then the make
database lists each target separately in addition to its rule with a note that
it is a sibling of a multiple target rule in order to facilitate commandline
tab completion. The multiple target rule itself is listed as '# Not a target'
and '# Multiple targets' so that existing commandline tab completion is not
broken. Examples of commandline tab completion includes bash-completion.

eg:
  build/x86-64/main.o build/x86/main.o build/armel/main.o: %.o=%.o: %.c ;
true
  # same as build/x86-64/main.o build/x86/main.o build/armel/main.o: %.o: %.c
; true
  # same as
  #  build/x86-64/main.o: build/x86-64/main.c ; true
  #  build/x86/main.o: build/x86/main.c ; true
  #  build/armel/main.o: build/armel/main.c ; true

  x86-64 x86 armel: %=build/%/main.o: main.c ; true
  # same as
  #  build/x86-64/main.o: main.c ; true
  #  build/x86/main.o: main.c ; true
  #  build/armel/main.o: main.c ; true

  %%.o: %.o=%.o %.log .%.deps %.symbols: %.c ; true
  # same as
  #  %.o %.log .%.deps %.symbols: %.c ; true

  x86-64 x86 armel: %=build/%/%%.o log/%/%%.log .deps/%/%%.d
symbols/%/%%.symbols: %%.c ; true
  # same as
  #  build/x86-64/%.o log/x86-64/%.log .deps/x86-64/%.d
symbols/x86-64/%.symbols: %.c ; true
  #  build/x86/%.o log/x86/%.log .deps/x86/%.d symbols/x86-64/%.symbols: %.c ;
true
  #  build/armel/%.o log/armel/%.log .deps/armel/%.d symbols/x86-64/%.symbols:
%.c ; true

  main.o err.o: %.o=%.o %.log .%.deps %.symbols: %.c ; true
  # same as this where all targets of one rulesare generated in a single step
(as if there is a
  # % sign in there but $* must be the empty string)
  #  main.o main.log .main.deps main.symbols: main.c ; #  err.o err.log
.err.deps err.symbols: err.c ; true

Please consider making each rule defined like this fail if any of the targets
for one factor is not updated unless it is a prerequisite of .PHONY to avoid
incorrect builds due to mistakes. ie, all non-phony targets must be updated by
its rule. I can imagine mistakes in the recipes for multiple simulataneous
outputs causing bad incrmental builds.

I will be happy to do the bulk of the work to implement this, if some guidance
can be provided and help with the hard bits.


    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?42125>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/


_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

[bug #42125] Explicit rules do not support multiple targets

anonymous
Follow-up Comment #3, bug #42125 (project make):

Hi Tristan.  Please move this proposal to the [hidden email] mailing list.
I don't want to have a design discussion in the bug tracker.  Thanks.

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?42125>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/


_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

[bug #42125] Explicit rules do not support multiple targets

anonymous
Follow-up Comment #4, bug #42125 (project make):

(I hope this comment doesn't contribute to an unwanted design discussion.)
Regarding comment #1: _A static pattern rule is a form of explicit rule, not
an implicit rule such as pattern rule._ - While saying that a _static pattern
rule_ is not a _pattern rule_ seems true for the current implementation, I
find this quite counterintuitive and unfortunate. I think, a _static pattern
rule_ should be a _pattern rule_ (in terms of manual section 10.5.1), only
with the set of applicable targets restricted to the specified *targets*.

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?42125>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/


_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

[bug #42125] Explicit rules do not support multiple targets

anonymous
Follow-up Comment #5, bug #42125 (project make):

I understand why you may consider it counterintuitive based on the naming, but
I don't understand why you consider it unfortunate.

Suppose that we made the change in the implementation that you suggest: that
would mean that the targets listed in the static pattern rule would not be
created as known files in make's database; instead they would simply be listed
as a set of names hanging off of that pattern rule that would be checked
before allowing that rule to be applied (as an example implementation).

This would mean two things: first, that those targets won't be considered
"known files" during computations such as intermediate file detection etc.,
and second that make would go through a complete pattern rule search when it
wanted to build those targets, which means make could choose some _other_
pattern rule to build those targets, if that pattern rule matched better.

To me, this latter behavior would be incredibly confusing, and incorrect: I
can't imagine any user would look at the syntax of a static pattern rule and
consider that make would use some OTHER rule, than the one explicitly listed
there, to build that target.

But maybe you had something different in mind: why you want static pattern
rules to be considered pattern rules?

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?42125>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/


_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

[bug #42125] Explicit rules do not support multiple targets

anonymous
Follow-up Comment #6, bug #42125 (project make):

I think maybe the naming is unfortunately confusing. A static pattern rule is
best regarded as a form of shorthand. I think many folks read the semantics of
search into the word "pattern", when in this case it's just substitution.

I'd be much more interested in a feature to support building multiple explicit
targets from one recipe, as mentioned in Paul's comment #1. It's
straightforward to emulate with a macro:

multi-output=$(strip $(eval $(call
multi-output-touch-others-mak,$1))$(firstword $1))

define multi-output-touch-others-mak
$(wordlist 2,$(words $1),$1): $(firstword $1)
        [ -e $$@ ] && touch $$@
endef

$(call multi-output, target1 target2 target3): blah blah blah...

but this requires the user to take extra steps to get the behavior they
usually intend. I'm not sure what syntax you could safely use to distinguish
the two cases, because clearly sometimes the user *does* want the recipe run
once per target.

(I'll further note that make *does* actually effectively support this for
serial builds, in which typically the recipe will be run only once after which
make will notice that the remaining targets are fresh and not-rerun the
recipe. IMO, this makes parallel builds even harder to debug because they
don't even run the same set of recipes as a serial build.)

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?42125>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/


_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

[bug #42125] Explicit rules do not support multiple targets

anonymous
Follow-up Comment #7, bug #42125 (project make):

Regarding comment #5: Thanks for contemplating my suggestion! Indeed I paid
insufficient attention to the implications of allowing some other pattern rule
to be chosen, and I see that this is undesirable and that the static pattern
rule shall be statically chosen for the specified targets.
What I consider unfortunate is that the construct in the original submission
does not work - because (and that's _why_ I'd like _static pattern rules to be
considered pattern rules_, in a sense) I'd need exactly the targeted selection
of the recipe (making sure that no other rule is chosen) combined with this
characteristic of _pattern rules_ from section 10.5.1: _If a pattern rule has
multiple targets, "make" knows that the rule’s recipe is responsible for
making all of the targets. The recipe is executed only once to make all the
targets._

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?42125>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/


_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

[bug #42125] Explicit rules do not support multiple targets

anonymous
Follow-up Comment #8, bug #42125 (project make):

I'm afraid I don't understand: how can a static pattern rule have multiple
targets?  Each pattern in the target needs to match each of the elements of
the static list, so clearly you can't have multiple patterns.  Unless you're
saying that the target section would have only one pattern plus one or more
explicit targets, which seems of fairly limited usefulness.

It sounds to me like you are just looking for exactly what this bug is asking
for: a way to have an explicit rule be marked to generate multiple targets
with one recipe invocation.  That's a very useful feature, but trying to
shoehorn it into static pattern rules doesn't seem like a good fit at all.

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?42125>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/


_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

[bug #42125] Explicit rules do not support multiple targets

anonymous
Follow-up Comment #9, bug #42125 (project make):

_… how can a static pattern rule have multiple targets? Each pattern in the
target needs to match each of the elements of the static list…_ - Currently,
a static pattern rule cannot have multiple "target-pattern"s, but people (at
least the original submitter and I) wish it could; then each of the elements
of the static "targets" list needs to be matched by *one* "target-pattern"
(just as in the original submission, where the resulting rule is e. g. "foo.c
foo.h : %.h %.c : %.idl").
You're right, I'm indeed _just looking for exactly what this bug is asking
for_, though also exactly how the original submission suggests, because I find
this construct intelligible, and that it would make "make"'s syntax more
consistent (the syntax of a _static pattern rule_ being equal to the syntax of
a _pattern rule_ with the static "targets …:" list prepended).
_trying to shoehorn it into static pattern rules doesn't seem like a good fit_
- Of course I may be wrong thinking it would be a good fit; after all, I'm not
enlightened - or dazzled? ;-) - by expert knowledge of "make"'s
implementation.

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?42125>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/


_______________________________________________
Bug-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-make
Reply | Threaded
Open this post in threaded view
|

[bug #42125] Explicit rules do not support multiple targets

anonymous
Update of bug #42125 (project make):

                  Status:                    None => Fixed                  
             Assigned to:                    None => psmith                
             Open/Closed:                    Open => Closed                
           Fixed Release:                    None => SCM                    

    _______________________________________________________

Follow-up Comment #10:

Defining explicit rules that generate multiple targets with a single recipe
invocation has been implemented and will be available in the next release of
GNU make.

Note, that the behavior and syntax of static pattern rules hasn't changed:
there's a different syntax used to engage this feature.  They feature is
referred to as "grouped explicit targets" or "grouped targets".

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?42125>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/