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: 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: 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