[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Evaluation and expansion
From: |
Bartłomiej Wójcik |
Subject: |
Re: Evaluation and expansion |
Date: |
Wed, 7 Jun 2023 09:37:10 +0200 |
Hi,
Thank you for the response. I think that I understand that, but still not
catching the part with other things. What is the term *evaluation*, when
does it happen (in which phase) and how is it related
to parsing, expanding?
Regards,
Bartek
śr., 7 cze 2023 o 09:08 Kaz Kylheku <kaz@kylheku.com> napisał(a):
> 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.
>
>