Re: Conditional recipe execution

2015-01-18 Thread SF Markus Elfring
 Would use cases around the standard command split be concrete enough
 for further clarification?
 https://en.wikipedia.org/wiki/Split_%28Unix%29
 
 No.

I am bit surprised that you find such a tool as an unclear example
at the moment.

I am using my Python script which I developed as a contribution for
a discussion around the topic 'Splitting search results from a find -print0'.
http://lists.gnu.org/archive/html/coreutils/2015-01/msg00023.html


 You need to describe your situation.  Use words, but with detail.

I would like to perform some file searches. The found files should be
analysed by dedicated programs.

A couple of programs which I use for corresponding data processing
are still single-threaded. But I want to get all processor cores
working on the search result.
So I split it into smaller files which I can give to each core
as a work unit. Is this approach just an ordinary parallel work flow?


 It sounds to me like you what you mean is you have a single recipe which
 generates multiple output files and you want those files to be
 prerequisites of other targets.

Yes, exactly.


 There are two possibilities.  The best case is that the generated files
 and the input file(s) are all related to each other through some aspect
 of the filename:

I have found that there are some software development challenges to consider
for safe parallel data processing.


 in that case you can use pattern rules and everything is simple.

I noticed a situation where such a special case needs to be detected.

A recipe was executed multiple times by the tool make for each
passed target.


 So for example the bison parser generator takes a file foo.y and
 generates foo.tab.h and foo.tab.c: the names of the output files are
 related to the name of the input file through the foo prefix.

This is another well-known use case.


 Now listing foo.tab.c or foo.tab.h as a prerequisite will cause this
 rule to be run one time, with foo.y as the prerequisite and make knows
 both files are generated by a single invocation.

Are there any cases left over where the make tool will interpret a rule
specification in the way that a single invocation is not sufficient?


 The other possibility is that the names of the generated files have no
 relationship to the names of the input files.

There is a relationship of course. But make file pattern operators can
be inappropriate in some cases of my build scripts.


 In this case you'll have to use a sentinel file:
 
 output list: .sentinel ;

I would interpret this specification as a rule with an empty recipe.
How does this approach help?

Regards,
Markus

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: Conditional recipe execution

2015-01-18 Thread Paul Smith
On Mon, 2015-01-19 at 00:08 +0100, SF Markus Elfring wrote:
  * I need to split an input file into several smaller files.
  
  I don't see any way that $(eval ...) is needed or helpful for any of
  those things.
 
 Can a make variable be set by this function within a recipe?

Yes, I've already said it can.  But I can see no way that this ability
is helpful or needed in the situations you listed.  If you give examples
of what you're actually trying to do, instead of just providing very
general questions and abstract situations, then we can use concrete
examples to explain.

 How should it be achieved that a recipe will only be executed for its first
 run despite of the detail that multiple targets were specified for
 a specific rule?

  There are other possibilities, but without a specific use-case we can't
  say which one(s) are appropriate.
 
 Would use cases around the standard command split be concrete enough
 for further clarification?
 https://en.wikipedia.org/wiki/Split_%28Unix%29

No.  You need to describe your situation.  Use words, but with detail.
I have a command foo that takes as input bar and generates as output
baz.  Then I have another command that takes baz as input and generates
a widget, and I need to figure out how to ..., etc.  If you have
implemented a rule and it doesn't work, then paste the rule into your
email and cut/paste the output you're getting, and describe why that
output is wrong / what you wanted to happen instead.  If it's very
complicated, then write a small example makefile that does the same type
of thing and shows the same problem, and put that in your email.

Just writing down what you're trying to do like this in an email can
often help you figure things out for yourself, before you even send it.


It sounds to me like you what you mean is you have a single recipe which
generates multiple output files and you want those files to be
prerequisites of other targets.

There are two possibilities.  The best case is that the generated files
and the input file(s) are all related to each other through some aspect
of the filename: in that case you can use pattern rules and everything
is simple.

So for example the bison parser generator takes a file foo.y and
generates foo.tab.h and foo.tab.c: the names of the output files are
related to the name of the input file through the foo prefix.  In this
case you can use:

%.tab.h %.tab.c : %.y
command ...

replacing the common part with % as a wildcard.  Now listing
foo.tab.c or foo.tab.h as a prerequisite will cause this rule to be
run one time, with foo.y as the prerequisite and make knows both files
are generated by a single invocation.

The other possibility is that the names of the generated files have no
relationship to the names of the input files.  In this case you'll have
to use a sentinel file:

output list: .sentinel ;

.sentinel: input files
command ...
touch $@



___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: Difficulties from the combination of functions call and eval

2015-01-18 Thread Norbert Thiebaud
On Sun, Jan 18, 2015 at 6:31 AM, SF Markus Elfring
elfr...@users.sourceforge.net wrote:

 Yes. - The evaluated variable should produce shell commands for recipes.
 I try to reuse it as a subfunction.

then use $(call  -- or possibly $$(call, if you want to defer the call
to when the recipe get invoked)
not $(eval

 It's just _part_ of a recipe?

 It is a fragment for the reuse by another variable expansion.


 Then $(eval) is the Wrong Thing.

 I hope not …

hope is not relevant... $(eval) _is_ the Wrong Thing(tm) for what you
seems to want to do

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: Difficulties from the combination of functions call and eval

2015-01-18 Thread Tim Murphy
With eval and call one can get confused quite easily. Try changing eval to
info and then inspect the output to see if it makes sense as a makefile.
Write small test makefiles that do small aspects of what you want and build
them up step by step until you get the result you want when you introduce
an error you will know exactly what change made it

Most of all, don't dump the full complexity of your problem on other people
because makefiles are brain twisting and hard to understand even when they
are simplified.  Simplifying the example will help you and help us help you
too. :)

Regards,

Tim
On 18 Jan 2015 21:07, Norbert Thiebaud nthieb...@gmail.com wrote:

 On Sun, Jan 18, 2015 at 6:31 AM, SF Markus Elfring
 elfr...@users.sourceforge.net wrote:
 
  Yes. - The evaluated variable should produce shell commands for recipes.
  I try to reuse it as a subfunction.

 then use $(call  -- or possibly $$(call, if you want to defer the call
 to when the recipe get invoked)
 not $(eval

  It's just _part_ of a recipe?
 
  It is a fragment for the reuse by another variable expansion.
 
 
  Then $(eval) is the Wrong Thing.
 
  I hope not …

 hope is not relevant... $(eval) _is_ the Wrong Thing(tm) for what you
 seems to want to do

 ___
 Bug-make mailing list
 Bug-make@gnu.org
 https://lists.gnu.org/mailman/listinfo/bug-make

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: Difficulties from the combination of functions call and eval

2015-01-18 Thread Paul Smith
On Sun, 2015-01-18 at 13:07 -0600, Norbert Thiebaud wrote:
  Then $(eval) is the Wrong Thing.
 
  I hope not …
 
 hope is not relevant... $(eval) _is_ the Wrong Thing(tm) for what you
 seems to want to do

The rule of thumb is, if you're using $(eval ...) inside a recipe,
you're doing something wrong.  $(eval ...) is for parsing MAKEFILE
content.  The recipe is passed to the SHELL.


There is only one situation I can think of where it _might_ make sense
to use $(eval ...) inside a recipe: if you want to assign a make
variable when the recipe is invoked.  But a real need for this is rare;
usually there are simpler and more straightforward ways to get the
result you're looking for.



___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: Difficulties from the combination of functions call and eval

2015-01-18 Thread SF Markus Elfring
 Try changing eval to info

This introspection approach will not work in the moment
when I stumble on the mentioned error messages.


 and then inspect the output to see if it makes sense as a makefile.

The result should become components for recipes in my use case.


 Write small test makefiles that do small aspects of what you want
 and build them up step by step until you get the result you want
 when you introduce an error you will know exactly what change made it

I can also try this approach once more.


 Most of all, don't dump the full complexity of your problem
 on other people because makefiles are brain twisting
 and hard to understand even when they are simplified.

I hope that there are more experienced software developers around
who can spot programming mistakes within make statements eventually
a bit easier than me.


 Simplifying the example will help you and help us help you too. :)

Should I explain the involved design patterns a bit more
so that a common understanding can be achieved easier?

Regards,
Markus

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: $ ignores order-only prerequisites

2015-01-18 Thread Paul Smith
On Fri, 2015-01-16 at 12:52 -0800, Parke wrote:
 It appears that if there are no normal prerequisites, $ will ignore
 any order-only prerequisites.
 
 This is not the behavior I expected, and I could not find
 documentation describing this behavior.

I agree it should be documented explicitly, but I don't necessarily
think it's wrong.

You may note that the $^ variable doesn't contain order-only
prerequisites either.  The idea is that prerequisites that are
order-only are qualitatively different than normal prerequisites;
they're there only to ensure things happen in a particular order.  The
manual gives a hint:

http://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html

when it says that order-only prerequisites don't create a dependency
relationship; because of this they aren't included in the normal
dependency variables like $^ and $.

If the prerequisite needed to be both ordered AND create a dependency
relationship, then it would be a normal prerequisite not an order-only
prerequisite.

 foo bar:
 @ echo $@ $

If you really want this behavior, you can write:

foo bar:
@ echo $@ $(firstword $ $|)



___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: Difficulties from the combination of functions call and eval

2015-01-18 Thread SF Markus Elfring
 The result should become components for recipes in my use case.
 
 As described before, this is not right.  $(eval ...) is used to
 internalize make syntax.  The result of expanding $(eval ...) is the
 _empty string_, so putting it in a recipe results in NOTHING being added
 to the recipe.

Thanks for your reminder.

I am going restructure the affected build rules.

Regards,
Markus

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: Conditional recipe execution

2015-01-18 Thread SF Markus Elfring
 * I need to split an input file into several smaller files.
 
 I don't see any way that $(eval ...) is needed or helpful for any of
 those things.

Can a make variable be set by this function within a recipe?


 I imagine that conditional evaluation of recipes will be possible somehow,
 wont it?
 
 I don't know what you mean by this question; if you mean that a recipe
 should make a decision and do different things, then typically you would
 use _shell_ conditional statements for this:

How should it be achieved that a recipe will only be executed for its first
run despite of the detail that multiple targets were specified for
a specific rule?


 There are other possibilities, but without a specific use-case we can't
 say which one(s) are appropriate.

Would use cases around the standard command split be concrete enough
for further clarification?
https://en.wikipedia.org/wiki/Split_%28Unix%29

Regards,
Markus

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: Difficulties from the combination of functions call and eval

2015-01-18 Thread Paul Smith
On Sun, 2015-01-18 at 22:28 +0100, SF Markus Elfring wrote:
  Without knowing exactly what you mean by handling of rules with
  multiple output files I can't say for sure, but I think it's unlikely
  that $(eval ...) can help with this.
 
 A lot of rules can come into the situation to fiddle with multiple
 output files easily.
 
 Examples:
 * Specification of standard output files and standard error channels
   for shell commands
 
 * The database SQLite can create its storage file while also
   exporting data to another file.
 
 * I need to split an input file into several smaller files.

I don't see any way that $(eval ...) is needed or helpful for any of
those things.

  This means the ONLY time setting a variable from within a recipe is
  helpful is if the only place you need to use that variable is INSIDE
  some other recipe that has not been run yet.
 
 I imagine that conditional evaluation of recipes will be possible somehow,
 wont it?

I don't know what you mean by this question; if you mean that a recipe
should make a decision and do different things, then typically you would
use _shell_ conditional statements for this:

foo:
if [ -f somefile ]; then \
do one thing; \
else \
do a different thing; \
fi

There are other possibilities, but without a specific use-case we can't
say which one(s) are appropriate.


Here's my advice: forget about $(eval ...) completely.  Just stop using
it and pretend it doesn't exist.  From what we've seen, you don't need
it and your attempts to force your makefiles to use it are
unquestionably causing confusion and errors.

$(eval ...) is a (relatively) recently implemented, very advanced
feature that exists only in GNU make: no other implementation of make
has anything like it (that I'm aware of).

At the same time, people have been writing sophisticated, complex,
capable build systems based on make for decades before $(eval ...)
existed, and still do so today with other implementations of make that
don't have it.

So you really just don't need $(eval ...), except in rare situations
where you really do need it.  Nothing you've shown us so far really
needs it.  So just forget about it.

If you get stuck trying to do something in the future, then you can come
back and ask a detailed question, and if $(eval ...) is needed to solve
that problem we'll let you know.


___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: Difficulties from the combination of functions call and eval

2015-01-18 Thread SF Markus Elfring
 Without knowing exactly what you mean by handling of rules with
 multiple output files I can't say for sure, but I think it's unlikely
 that $(eval ...) can help with this.

A lot of rules can come into the situation to fiddle with multiple
output files easily.

Examples:
* Specification of standard output files and standard error channels
  for shell commands

* The database SQLite can create its storage file while also
  exporting data to another file.

* I need to split an input file into several smaller files.


 Just to be clear, you cannot create new rules, or add to the targets or
 prerequisites of existing rules, using $(eval ...) _inside a recipe_.

I'm sorry that I needed a bit longer to realise this fact.


 This means the ONLY time setting a variable from within a recipe is
 helpful is if the only place you need to use that variable is INSIDE
 some other recipe that has not been run yet.

I imagine that conditional evaluation of recipes will be possible somehow,
wont it?

Regards,
Markus

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: Difficulties from the combination of functions call and eval

2015-01-18 Thread Paul Smith
On Sun, 2015-01-18 at 20:50 +0100, SF Markus Elfring wrote:
  The rule of thumb is, if you're using $(eval ...) inside a recipe,
  you're doing something wrong.
 
 Which make function should be used for recipe generation instead then?

If you just want to expand inside a recipe, you can use $(call ...) (as
has already been suggested).

  $(eval ...) is for parsing MAKEFILE content.
 
 Do recipes belong also to each make script?

I don't understand this question.

  There is only one situation I can think of where it _might_ make sense
  to use $(eval ...) inside a recipe: if you want to assign a make
  variable when the recipe is invoked.
 
 I want to use also exactly this functionality.

Possible, but I'm skeptical.

  But a real need for this is rare;
 
 I have got an opposite experience.
 
 I need this immediately for the handling of rules with multiple
 output files.

Without knowing exactly what you mean by handling of rules with
multiple output files I can't say for sure, but I think it's unlikely
that $(eval ...) can help with this.

Just to be clear, you cannot create new rules, or add to the targets or
prerequisites of existing rules, using $(eval ...) _inside a recipe_.
Recipes are only expanded after all makefiles have been read in, and
once all makefiles have been read in it's not possible to create more
targets or change prerequisites of targets.

Also, the entire recipe is expanded before any part of the recipe is
invoked in the shell.  So, you cannot assign any output from the recipe,
or use any other result of running the recipe, including things like
running $(wildcard ...) to see what files were created, etc.

This means the ONLY time setting a variable from within a recipe is
helpful is if the only place you need to use that variable is INSIDE
some other recipe that has not been run yet.

  usually there are simpler and more straightforward ways
  to get the result you're looking for.
 
 I would like to know them so that I can optimise my make
 source code more.

Well, if you tell us specifically what result you're looking for we
might be able to help.


___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make


Re: Difficulties from the combination of functions call and eval

2015-01-18 Thread Philip Guenther
To home in on one key point here...


On Sun, Jan 18, 2015 at 4:31 AM, SF Markus Elfring
elfr...@users.sourceforge.net wrote:
...
 Lines 183 - 203:
 define RESULT_CHECK
 for part in $(1); do \
 if test x$$( $$part) != x0; then \
 $(PRINTF) $$(TEXT3) '$$part'; \
 exit 12; \
 fi; \
 done \
  $$(TOUCH) '$(2)'
 endef

 That looks like it expands to shell text when used with $(call), so
 just call it in a recipe!

 Yes. - The evaluated variable should produce shell commands for recipes.
 I try to reuse it as a subfunction.

You use the word evaluated there, which I think reflects an
incorrect view of make's operation. To define the words as they're
used in the make documentation:

-  make _expands_ variables and functions, as marked with a leading
dollar-sign.  This
-  make _executes_ recipes and the argument of the $(shell) function
by passing the _expanded_ text to the shell
-  make _evaluates_ the its own input, the makefile, files that it
includes, the argument of the --eval CLI option, and the _expanded_
argument to the $(eval) function

You do not need $(eval) to get expansion to do its job of creating the
final string to pass to the shell in a recipe, for example.

define STUFF
# some shell commands here
sort inputs | uniq -c outputs
endef

define MORESTUFF
# do something, then do STUFF
create_inputs inputs
${STUFF}
endef

all:
${MORESTUFF}

When 'all' is built, ${MORESTUFF} will be expanded (which will involve
expanding the ${STUFF} inside it) to get a final string, which will
then be passed to the shell.  No need for ${STUFF} or ${MORESTUFF} to
explicitly say execute this or evaluate this.

That's true even when you use $(call):

# Generate file $2 from file $1
define STUFF
# some shell commands here
sort $1 | uniq -c $2
endef

# Generate $1
define MORESTUFF
# do something, then do STUFF
create_inputs inputs
$(call STUFF,inputs,$1)
endef

all:
$(call MORESTUFF,output)

When building 'all', make will expand $(call MORESTUFF,output) by
temporarily setting $1 to 'output' then expanding MORESTUFF.  The
$(call STUFF,inputs,$1) inside that will temporarily override that by
setting $1 to 'inputs' and $2 to 'output' then expanding STUFF.  The
result will be the same as the earlier example.


That distinction between expansion, execution and evaluation make sense?


Philip Guenther

___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make