xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH for-4.7] docs/build: Work around apparent bug with multi-target rules
@ 2016-04-25 13:00 Andrew Cooper
  2016-04-25 13:35 ` Ian Jackson
  0 siblings, 1 reply; 5+ messages in thread
From: Andrew Cooper @ 2016-04-25 13:00 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Ian Jackson, Wei Liu

The `make` manual documents that a rule of the form

  target1 target2: prereq
  	recipe

is equivilent to

  target1: prereq
  	recipe
  target2: prereq
  	recipe

This is correct if only target1 or target2 is wanted, but is not the case if
both target1 and target2 are wanted to be rebuilt in the same pass.  In such a
case, executing the recipe to generate target1 causes the entire rule to be
considered complete, short circuiting the search to regenerate target2.

This bug can be demonstrated with the generation of documentation from pandoc
source.

  ./xen.git$ touch docs/features/templace.pandoc
  ./xen.git$ make -C docs/
  # Regenerates html/features/template.html
  ./xen.git$ make -C docs/
  # Regenerates txt/features/template.txt
  ./xen.git$ make -C docs/
  # Regenerates pdf/features/template.pdf

To work around this, there need to be three distinct rules, so the execution
of one recipe doesn't short ciruit the others.  To avoid copy&paste
duplication, introduce a metarule, and evalute it for each document target.

As $(PANDOC) is used to generate documentation from different source types,
the metarule can be extended to also encompas the rule to create pdfs from
markdown.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
---
 docs/Makefile | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/docs/Makefile b/docs/Makefile
index b9da605..e2537e8 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -180,22 +180,24 @@ txt/%.txt: %.markdown
 	@$(INSTALL_DIR) $(@D)
 	$(INSTALL_DATA) $< $@
 
-pdf/%.pdf: %.markdown
-ifneq ($(PANDOC),)
-	@$(INSTALL_DIR) $(@D)
-	$(PANDOC) --number-sections --toc --standalone $< --output $@
-else
-	@echo "pandoc not installed; skipping $@"
-endif
+# Metarule for generating pandoc rules.
+define GENERATE_PANDOC_RULE
+# $(1) is the target documentation format. $(2) is the source format.
 
-pdf/%.pdf txt/%.txt html/%.html: %.pandoc
+$(1)/%.$(1): %.$(2)
 ifneq ($(PANDOC),)
-	@$(INSTALL_DIR) $(@D)
-	$(PANDOC) --number-sections --toc --standalone $< --output $@
+	@$(INSTALL_DIR) $$(@D)
+	$(PANDOC) --number-sections --toc --standalone $$< --output $$@
 else
-	@echo "pandoc not installed; skipping $@"
+	@echo "pandoc not installed; skipping $$@"
 endif
 
+endef
+$(eval $(call GENERATE_PANDOC_RULE,pdf,pandoc))   # pdf/%.pdf: %.pandoc
+$(eval $(call GENERATE_PANDOC_RULE,txt,pandoc))   # txt/%.txt: %.pandoc
+$(eval $(call GENERATE_PANDOC_RULE,html,pandoc))  # html/%.html: %.pandoc
+$(eval $(call GENERATE_PANDOC_RULE,pdf,markdown)) # pdf/%.pdf: %.markdown
+
 ifeq (,$(findstring clean,$(MAKECMDGOALS)))
 $(XEN_ROOT)/config/Docs.mk:
 	$(error You have to run ./configure before building docs)
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH for-4.7] docs/build: Work around apparent bug with multi-target rules
  2016-04-25 13:00 [PATCH for-4.7] docs/build: Work around apparent bug with multi-target rules Andrew Cooper
@ 2016-04-25 13:35 ` Ian Jackson
  2016-04-25 13:50   ` Wei Liu
  2016-04-25 15:01   ` Andrew Cooper
  0 siblings, 2 replies; 5+ messages in thread
From: Ian Jackson @ 2016-04-25 13:35 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Wei Liu, Xen-devel

Andrew Cooper writes ("[PATCH for-4.7] docs/build: Work around apparent bug with multi-target rules"):
> The `make` manual documents that a rule of the form
> 
>   target1 target2: prereq
>   	recipe
> 
> is equivilent to
> 
>   target1: prereq
>   	recipe
>   target2: prereq
>   	recipe
> 
> This is correct if only target1 or target2 is wanted, but is not the
> case if both target1 and target2 are wanted to be rebuilt in the
> same pass.  In such a case, executing the recipe to generate target1
> causes the entire rule to be considered complete, short circuiting
> the search to regenerate target2.

This is not a bug in make.  From the manual I have here (wheezy):

     Suppose you would like to vary the prerequisites according to the
   target, much as the variable `$@' allows you to vary the commands.
   You cannot do this with multiple targets in an ordinary rule, but
   you can do it with a "static pattern rule".  *Note Static Pattern
   Rules: Static Pattern.

and (from `Pattern Intro'):

     Pattern rules may have more than one target.  Unlike normal
   rules, this does not act as many different rules with the same
   prerequisites and commands.  If a pattern rule has multiple
   targets, `make' knows that the rule's commands are responsible for
   making all of the targets.  The commands are executed only once to
   make all the targets.

So this is a bug in the Makefile.  Your patch looks like a right
approach to me.  A static pattern rule would be the other option.

Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH for-4.7] docs/build: Work around apparent bug with multi-target rules
  2016-04-25 13:50   ` Wei Liu
@ 2016-04-25 13:49     ` Andrew Cooper
  0 siblings, 0 replies; 5+ messages in thread
From: Andrew Cooper @ 2016-04-25 13:49 UTC (permalink / raw)
  To: Wei Liu, Ian Jackson; +Cc: Xen-devel

On 25/04/16 14:50, Wei Liu wrote:
> On Mon, Apr 25, 2016 at 02:35:56PM +0100, Ian Jackson wrote:
>> Andrew Cooper writes ("[PATCH for-4.7] docs/build: Work around apparent bug with multi-target rules"):
>>> The `make` manual documents that a rule of the form
>>>
>>>   target1 target2: prereq
>>>   	recipe
>>>
>>> is equivilent to
>>>
>>>   target1: prereq
>>>   	recipe
>>>   target2: prereq
>>>   	recipe
>>>
>>> This is correct if only target1 or target2 is wanted, but is not the
>>> case if both target1 and target2 are wanted to be rebuilt in the
>>> same pass.  In such a case, executing the recipe to generate target1
>>> causes the entire rule to be considered complete, short circuiting
>>> the search to regenerate target2.
>> This is not a bug in make.  From the manual I have here (wheezy):
>>
>>      Suppose you would like to vary the prerequisites according to the
>>    target, much as the variable `$@' allows you to vary the commands.
>>    You cannot do this with multiple targets in an ordinary rule, but
>>    you can do it with a "static pattern rule".  *Note Static Pattern
>>    Rules: Static Pattern.
>>
>> and (from `Pattern Intro'):
>>
>>      Pattern rules may have more than one target.  Unlike normal
>>    rules, this does not act as many different rules with the same
>>    prerequisites and commands.  If a pattern rule has multiple
>>    targets, `make' knows that the rule's commands are responsible for
>>    making all of the targets.  The commands are executed only once to
>>    make all the targets.
>>
>> So this is a bug in the Makefile.  Your patch looks like a right
>> approach to me.  A static pattern rule would be the other option.
>>
>> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
>>
> Release-acked-by: Wei Liu <wei.liu2@citrix.com>
>
> Thank you both for handling this.
>
> Andrew, I think you need to resubmit with updated subject line and
> commit message.

I will adjust and roll it into a short series with the cpuid feature
doc.  (Guess what I was doing to find this issue...)

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH for-4.7] docs/build: Work around apparent bug with multi-target rules
  2016-04-25 13:35 ` Ian Jackson
@ 2016-04-25 13:50   ` Wei Liu
  2016-04-25 13:49     ` Andrew Cooper
  2016-04-25 15:01   ` Andrew Cooper
  1 sibling, 1 reply; 5+ messages in thread
From: Wei Liu @ 2016-04-25 13:50 UTC (permalink / raw)
  To: Ian Jackson; +Cc: Andrew Cooper, Wei Liu, Xen-devel

On Mon, Apr 25, 2016 at 02:35:56PM +0100, Ian Jackson wrote:
> Andrew Cooper writes ("[PATCH for-4.7] docs/build: Work around apparent bug with multi-target rules"):
> > The `make` manual documents that a rule of the form
> > 
> >   target1 target2: prereq
> >   	recipe
> > 
> > is equivilent to
> > 
> >   target1: prereq
> >   	recipe
> >   target2: prereq
> >   	recipe
> > 
> > This is correct if only target1 or target2 is wanted, but is not the
> > case if both target1 and target2 are wanted to be rebuilt in the
> > same pass.  In such a case, executing the recipe to generate target1
> > causes the entire rule to be considered complete, short circuiting
> > the search to regenerate target2.
> 
> This is not a bug in make.  From the manual I have here (wheezy):
> 
>      Suppose you would like to vary the prerequisites according to the
>    target, much as the variable `$@' allows you to vary the commands.
>    You cannot do this with multiple targets in an ordinary rule, but
>    you can do it with a "static pattern rule".  *Note Static Pattern
>    Rules: Static Pattern.
> 
> and (from `Pattern Intro'):
> 
>      Pattern rules may have more than one target.  Unlike normal
>    rules, this does not act as many different rules with the same
>    prerequisites and commands.  If a pattern rule has multiple
>    targets, `make' knows that the rule's commands are responsible for
>    making all of the targets.  The commands are executed only once to
>    make all the targets.
> 
> So this is a bug in the Makefile.  Your patch looks like a right
> approach to me.  A static pattern rule would be the other option.
> 
> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
> 

Release-acked-by: Wei Liu <wei.liu2@citrix.com>

Thank you both for handling this.

Andrew, I think you need to resubmit with updated subject line and
commit message.

Wei.

> Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH for-4.7] docs/build: Work around apparent bug with multi-target rules
  2016-04-25 13:35 ` Ian Jackson
  2016-04-25 13:50   ` Wei Liu
@ 2016-04-25 15:01   ` Andrew Cooper
  1 sibling, 0 replies; 5+ messages in thread
From: Andrew Cooper @ 2016-04-25 15:01 UTC (permalink / raw)
  To: Ian Jackson; +Cc: Wei Liu, Xen-devel

On 25/04/16 14:35, Ian Jackson wrote:
> Andrew Cooper writes ("[PATCH for-4.7] docs/build: Work around apparent bug with multi-target rules"):
>> The `make` manual documents that a rule of the form
>>
>>   target1 target2: prereq
>>   	recipe
>>
>> is equivilent to
>>
>>   target1: prereq
>>   	recipe
>>   target2: prereq
>>   	recipe
>>
>> This is correct if only target1 or target2 is wanted, but is not the
>> case if both target1 and target2 are wanted to be rebuilt in the
>> same pass.  In such a case, executing the recipe to generate target1
>> causes the entire rule to be considered complete, short circuiting
>> the search to regenerate target2.
> This is not a bug in make.  From the manual I have here (wheezy):
>
>      Suppose you would like to vary the prerequisites according to the
>    target, much as the variable `$@' allows you to vary the commands.
>    You cannot do this with multiple targets in an ordinary rule, but
>    you can do it with a "static pattern rule".  *Note Static Pattern
>    Rules: Static Pattern.

But we don't want to vary the prerequisite with the target.  We want the
single (Patterned) prerequisite to cause a regeneration of each three of
the (Patterned) targets using the same recipe, as the $@ and $< are
sufficiently expressive for our needs.

i.e. I only chose to do it like that originally to avoid copy&pasting
the recipe.

>
> and (from `Pattern Intro'):
>
>      Pattern rules may have more than one target.  Unlike normal
>    rules, this does not act as many different rules with the same
>    prerequisites and commands.  If a pattern rule has multiple
>    targets, `make' knows that the rule's commands are responsible for
>    making all of the targets.  The commands are executed only once to
>    make all the targets.

This is the bit of documentation that I missed.  IMO, this is at least a
documentation bug, and that the multi-target documentation should
warning that multi-target pattern rules behave differently.

`make' knows, does it...  How can that possibly be the sensible choice? 
There is no automatic variable which encompasses multiple targets, and
using $* still requires you to hand-code the non-stem parts of the
targets.  This smells like a bug which was documented around.

>
> So this is a bug in the Makefile.  Your patch looks like a right
> approach to me.  A static pattern rule would be the other option.

However, a static pattern rule wouldn't avoid the repetition of the recipe.

> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

Thanks.  I will see about adjusting the commit message, but the patch
itself doesn't need to change.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-04-25 15:01 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-25 13:00 [PATCH for-4.7] docs/build: Work around apparent bug with multi-target rules Andrew Cooper
2016-04-25 13:35 ` Ian Jackson
2016-04-25 13:50   ` Wei Liu
2016-04-25 13:49     ` Andrew Cooper
2016-04-25 15:01   ` Andrew Cooper

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).