bugmake - Bugs: bug #42125, Explicit rules do not support...

 
 

bug #42125: Explicit rules do not support multiple targets

Submitter:  None
Submitted:  Tue 15 Apr 2014 04:02:29 PM UTC
Votes: 1
 
Severity:  3 - Normal Item Group:  Enhancement
Status:  Fixed Privacy:  Public
Assigned to:  psmith Open/Closed:  Closed
Component Version:  4.0 Operating System:  POSIX-Based
Fixed Release:  4.3 Triage Status:  Medium Effort
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Fri 03 Jan 2020 08:02:11 PM UTC, 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".

Paul D. Smith <psmith>
Group administrator
Thu 09 Mar 2017 08:39:17 AM UTC, comment #9: 

… 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.

Dietmar Schindler <armali>
Wed 08 Mar 2017 01:36:58 PM UTC, comment #8: 

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.

Paul D. Smith <psmith>
Group administrator
Tue 07 Mar 2017 08:33:18 AM UTC, comment #7: 

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.

Dietmar Schindler <armali>
Fri 03 Mar 2017 04:14:20 PM UTC, comment #6: 

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.)

Kyle Rose <squarooticus>
Fri 03 Mar 2017 03:49:51 PM UTC, comment #5: 

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?

Paul D. Smith <psmith>
Group administrator
Fri 03 Mar 2017 03:07:03 PM UTC, comment #4: 

(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.

Dietmar Schindler <armali>
Sun 17 Apr 2016 06:21:27 PM UTC, comment #3: 

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

Paul D. Smith <psmith>
Group administrator
Sun 17 Apr 2016 03:33:24 PM UTC, comment #2: 

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.

Tristan Wibberley <codeshot>
Tue 15 Apr 2014 04:21:58 PM UTC, 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.

Paul D. Smith <psmith>
Group administrator
Tue 15 Apr 2014 04:02:29 PM UTC, original submission:  

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.

Anonymous

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by squarooticus (Posted a comment)
  • -email is unavailable- added by armali (Posted a comment)
  • -email is unavailable- added by armali (Voted in favor of this item)
  • -email is unavailable- added by codeshot (Posted a comment)
  • -email is unavailable- added by psmith (Posted a comment)
  •  

    There is 1 vote so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 8 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2020-01-03 psmith Assigned toNone psmith
        Open/ClosedOpen Closed
        Fixed ReleaseNone 4.3
    2020-01-03 psmith StatusNone Fixed
    2017-03-03 armali Carbon-Copy- Added armali
    2014-04-15 psmith Item GroupBug Enhancement
        Triage StatusNone Medium Effort
        SummaryStatic pattern rules do not support multiple targets Explicit rules do not support multiple targets

    Back to the top

    Powered by Savane 3.13-d3ae.
    Corresponding source code