Secondary expansion and pattern rules

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

Secondary expansion and pattern rules

Mike Haboustak
I've been trying to make use of secondary expansion and I ran into some
confusion that I couldn't reconcile with manual. Specifically, The value
of the automatic variable $< is not what I'd expect during the second
expansion of an implicit rule prerequisite.

In the makefile below, foo.o is built via the %.o: %.c pattern rule, and
the value of $< printed by $(info) is foo.o, not foo.c.

If I use an explicit rule, as used for bar.o, the value of $< is bar.c,
as I expect.

It seems that the value of $< is getting defaulted for implicit rules
during second expansion. However, the value of $< is correct in the
recipe.

If this is the expected behavior, is there a way I can use secondary
expansion with implicit rules and get the correct value of $< for foo.o
(foo.c)?

---
--- Example Makefile
MAKEFLAGS += -rR
.SECONDEXPANSION:

.PHONY: all
all: test

test: foo.o bar.o

%.o: %.c
        @echo Turning $< into $@
        @touch $@

foo.o: baz.c
bar.o: bar.c baz.c
        @echo Turning $< into $@
        @touch bar.o

foo.o: $$(info in foo.o\: $$$$< = $$< and $$$$^ = $$^)
bar.o: $$(info in bar.o\: $$$$< = $$< and $$$$^ = $$^)

baz.c:
        @touch baz.c
foo.c:
        @touch foo.c
bar.c:
        @touch bar.c


---
--- Make output
in foo.o: $< = foo.o and $^ = baz.c
in bar.o: $< = bar.c and $^ = bar.c baz.c
Turning foo.c into foo.o
Turning bar.c into bar.o

---
--- foo.o rule from make -p
foo.o: foo.c baz.c
#  Implicit rule search has been done.
#  Implicit/static pattern stem: 'foo'
#  Last modified 2019-02-08 18:57:12.169408599
#  File has been updated.
#  Successfully updated.
# automatic
# @ := foo.o
# automatic
# % :=
# automatic
# * :=
# automatic
# + := baz.c
# automatic
# | :=
# automatic
# < := foo.o
# automatic
# ^ := baz.c
# automatic
# ? :=
# variable set hash-table stats:
# Load=8/32=25%, Rehash=0, Collisions=1/10=10%
#  recipe to execute (from 'Makefile', line 11):
        @echo Turning $< into $@
        @touch $@


- Mike

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: Secondary expansion and pattern rules

Paul Smith-20
On Fri, 2019-02-08 at 14:32 -0500, Mike Haboustak wrote:

> I've been trying to make use of secondary expansion and I ran into some
> confusion that I couldn't reconcile with manual. Specifically, The value
> of the automatic variable $< is not what I'd expect during the second
> expansion of an implicit rule prerequisite.
>
> It seems that the value of $< is getting defaulted for implicit rules
> during second expansion. However, the value of $< is correct in the
> recipe.
>
> If this is the expected behavior, is there a way I can use secondary
> expansion with implicit rules and get the correct value of $< for
> foo.o (foo.c)?

I can't remember the complexity around expanding $< for implicit rules;
it's something to do with when the expansion happens during pattern
matching.

However, for a workaround you can use $$*.c instead of $$< in this
situation and get the same result.


_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: Secondary expansion and pattern rules

Mike Haboustak
On Fri, Feb 08, 2019 at 04:07:08PM -0500, Paul Smith wrote:

> On Fri, 2019-02-08 at 14:32 -0500, Mike Haboustak wrote:
> > It seems that the value of $< is getting defaulted for implicit rules
> > during second expansion. However, the value of $< is correct in the
> > recipe.
> >
> > If this is the expected behavior, is there a way I can use secondary
> > expansion with implicit rules and get the correct value of $< for
> > foo.o (foo.c)?
>
> I can't remember the complexity around expanding $< for implicit rules;
> it's something to do with when the expansion happens during pattern
> matching.
>
> However, for a workaround you can use $$*.c instead of $$< in this
> situation and get the same result.
>

It seems in this case, $$*.c returns ".c", as the star variable is
empty. Building on the previous makefile:
    foo.o: foo.c $$(info in foo.o\: $$$$< = $$< and $$$$^ = $$^ $$$$*.c = $$*.c)

    in foo.o: $< = foo.o and $^ = baz.c $*.c = .c

I was hoping for a more generalizable solution. My ultimate goal is to
trigger the rebuild of a target when conditions beyond timestamp change.
Similar to the if_changed functionality from kbuild, but using conditional
prerequisites rather than conditional recipes. My intent is to emit a
phony prerequisite during second expansion that can trigger a rebuild.
If I am able to do this, then I can cleanly separate the logic of
building the target from evaluating whether the target is up-to-date.
Unfortunately, this requires the automatic file variables to be consistent
between second expansion and the recipe.

I'm interested in looking further into this issue and trying to find a
solution. Do you think that it's worth putting effort into it? Or should
I just follow kbuild's example and implement this in the recipe?

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