help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Evaluation and expansion


From: Kaz Kylheku
Subject: Re: Evaluation and expansion
Date: Wed, 07 Jun 2023 00:08:22 -0700
User-agent: Roundcube Webmail/1.4.13

On 2023-06-06 15:14, Bartłomiej Wójcik wrote:
> Hi,
> 
> I would like to ask you for help with clarifying the idea of evaluation and
> expansion related to makefile. As I understand, expansion refers to
> replacing macro reference by its value and there are two possible ways of
> expansion - *immediate* and *deferred* which depends on the construction
> itself. I also found that in the *immediate* context the expansion is done
> before evaluation, and for the *deferred* context, it is the opposite. But
> it is also stated that in the *immediate *context, the expansion is done
> while parsing, which would be contradictory, because as I understand the
> evaluation is the process of parsing and internalizating.

The terms "eager" and "lazy" could be used.

   # eager/immediate: $(bar) is expanded, combined with abc, and assigned to foo
   foo := $(bar) abc

   # lazy/deferred: foo is assigned the unexpanded right hand side.
   foo = $(bar) abc

   # eager/immediate: here, the variable is not in the right hand side
   # of a lazy definition's assignment; its value is required
   # immediately, just like in the right hand side of :=
   target: prerequisite $(foo)
     build step

Outside the right side of an assignment, everything is immediate:
when the value of a variable is needed, it is replaced by its
content, which is fully expanded, as necessary.

Mostly, the syntax determines whether the right hand side of
an assignment is expanded immediately or deferred. Except
that certain kinds of assignments like += rely on whether the
variable was previously the target of a deferred or immediate
assignment. For the purpose of these operators, variables have
to track the style in which they were most recently assigned.
That attribute can optimize expansion. If we know that we
need the value of $(foo), and we know that it was assignned using
IMMEDIATE := IMMEDIATE, then we know we don't have to run an expansion
pass on it; just dump the content where we need it.

The documentation has a diagram like this:

     IMMEDIATE = DEFERRED
     IMMEDIATE ?= DEFERRED
     IMMEDIATE := IMMEDIATE
     IMMEDIATE ::= IMMEDIATE
     IMMEDIATE += DEFERRED or IMMEDIATE
     IMMEDIATE != IMMEDIATE

     define IMMEDIATE
       DEFERRED
     endef

     # ... etc ... not going to reproduce all of it

Why is there IMMEDIATE on the left hand sides? Because
left hand sides can contain expansions too: computed
variables. Things like:

  OBJS_$(this_file) = foo.o bar.o

The above diagram tells us that this is IMMEDIATE = DEFERRED
which tells us that OBJS_$(this_file) is expanded immediately
in order to determine the name of the variable which receives
the right hand side body.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]