Function not returning result

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

Function not returning result

zxuiji
This is my function as it is

> define STAT_MODIFIED
> $(eval $(info $($(0)_SYS)-$(0),$(1)))
> $(eval $(0)_SH=$(call $($(0)_SYS)_$(0),$(1)))
> $(eval $(info $(0)_SH=$($(0)_SH)))
> $(eval $(0)_FAIL=0)
> $(eval $(info $(0)_FAIL=$($(0)_FAIL)))
> $(eval $(0)_VAL=$(if $(wildcard $(1)),SH,FAIL))
> $(eval $(info $(0)_VAL=$($(0)_VAL)))
> $(eval $(0)_RESULT=$(call $($(0)_SYS)_$(0)_STRIP,$(shell
> $($(0)_$($(0)_VAL)))))
> $(eval $(info $(0)_RESULT=$($(0)_RESULT)))
> $($(0)_RESULT)
> endef
>
I thought it would return the correct result via the $($(0)_RESULT)
statement at the bottom but for some reason when I try this:

> $(eval $(0)_LASTMOD=$(call STAT_MODIFIED,$($(0)_SRC)))
> $(eval $(info $(0)_LASTMOD=$($(0)_LASTMOD)))
>
‚ÄčThe LASTMOD‚Äč comes out empty despite $(eval $(info
$(0)_RESULT=$($(0)_RESULT))) displaying an actual value. I'm sure it's
something simple but for the life of me I cannot think of what it is right
now, I'm off to work soon so I figured I'd try my luck here and see if the
experts can help me at all.

--
We will die a permanent death unless we trust in Jesus Christ our saviour
and repent our sinful ways
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: Function not returning result

Philip Guenther-2
On Thu, Jul 28, 2016 at 3:44 AM, Lee Shallis <[hidden email]> wrote:
> This is my function as it is
>
>> define STAT_MODIFIED
>> $(eval $(info $($(0)_SYS)-$(0),$(1)))

The expansion of $(info ...) is the empty string, so the $(eval) is
doing nothing there expect make this harder to read and understand.
Ditto for the other $(eval $(info ...)) uses, of course.


>> $(eval $(0)_SH=$(call $($(0)_SYS)_$(0),$(1)))
>> $(eval $(info $(0)_SH=$($(0)_SH)))
>> $(eval $(0)_FAIL=0)
>> $(eval $(info $(0)_FAIL=$($(0)_FAIL)))
>> $(eval $(0)_VAL=$(if $(wildcard $(1)),SH,FAIL))
>> $(eval $(info $(0)_VAL=$($(0)_VAL)))
>> $(eval $(0)_RESULT=$(call $($(0)_SYS)_$(0)_STRIP,$(shell
>> $($(0)_$($(0)_VAL)))))
>> $(eval $(info $(0)_RESULT=$($(0)_RESULT)))
>> $($(0)_RESULT)
>> endef
>>
> I thought it would return the correct result via the $($(0)_RESULT)
> statement at the bottom but for some reason when I try this:
>
>> $(eval $(0)_LASTMOD=$(call STAT_MODIFIED,$($(0)_SRC)))

The expansion of $(call STAT_MODIFIED, ...) includes the newlines at
the end of each line.  For example, consider this simpler version:

----
define foo
$(eval bar=1)
$(info bar = ${bar})
bar=${bar}
endef

$(info >>$(call foo, 1)<<)
baz = $(call foo, 1)
$(info >>baz = ${baz}<<)

$(eval quux = $(call foo, 1))
$(info >>quux = ${quux}<<)

all:
        @:
----

$ gmake
bar = 1
>>

bar=1<<
bar = 1
>>baz =

bar=1<<
bar = 1
>>quux = <<
$

See how the ${baz} value contains newlines?  For the "$(eval quux =
$(call foo, 1))" assignment, those newlines would be treated as
makefile line separators and make parses this:
---
quux=

bar=1
---
That sure looks like an assignment of the empty string to quux,
followed by assigning 1 to bar.  Make sense?


When building these complicated $(eval) setups you almost always see
evaluation happening *too often*, or *too soon*.  Remember: when using
$(eval) the argument has variable expansion happen *twice*, once when
make it figuring out what was passed to $(eval) and once when $(eval)
reparses the value as makefile content.

In my experience, you often don't need or want the first expansion, so
you should suppress it by doubling the dollar-signs in the argument to
$(eval).  That would solve the problem here by delaying the $(call)
processing where the newlines come from until the second expansion in
$(eval).  For example, if we change the quux assignment to "$(eval
quux=$$(call foo,1))" then the problem goes away and quux contains the
newlines:
...
$(eval quux = $$(call foo, 1))
$(info >>quux = ${quux}<<)
...
>>quux =

bar=1<<


Oh, you don't want the newlines in the expansion of that $(call)?
Then you need to strip them out, such as by wrapping all the leading
lines in a $(strip) whose closing paren is at the start of the last
line.

So that fixes the "too soon" and "newlines" points; that leaves the
"too often" concern.  I won't go into the details, but I strongly
suspect you should write that macro with the expansions inside the
$(eval)s suppressed except for $0 and $1, ala:

define STAT_MODIFIED
$(strip
$(info $($(0)_SYS)-$(0),$(1))
$(eval $(0)_SH=$$(call $$($(0)_SYS)_$(0),$(1)))
$(info $(0)_SH=$($(0)_SH))
$(eval $(0)_FAIL=0)
$(info $(0)_FAIL=$($(0)_FAIL))
$(eval $(0)_VAL=$$(if $$(wildcard $(1)),SH,FAIL))
$(info $(0)_VAL=$$($(0)_VAL))
$(eval $(0)_RESULT=$$(call $$($(0)_SYS)_$(0)_STRIP,$$(shell
$$($(0)_$$($(0)_VAL)))))
$(info $(0)_RESULT=$$($(0)_RESULT))
)$($(0)_RESULT)
endef


Just Say No To Multiple Expansions!


Philip Guenther

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make