[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Ignoring the whitespaces
From: |
Kaz Kylheku |
Subject: |
Re: Ignoring the whitespaces |
Date: |
Wed, 07 Jun 2023 10:40:15 -0700 |
User-agent: |
Roundcube Webmail/1.4.13 |
On 2023-06-07 03:23, Bartłomiej Wójcik wrote:
> Hi,
> The GNU make documentation states:
>
> *define myrule
> target:
> echo built
> endef
>
> $(myrule)
> *
>
> *The above makefile results in the definition of a target ‘target’ with
> prerequisites ‘echo’ and ‘built’, as if the makefile contained target: echo
> built, rather than a rule with a recipe. Newlines still present in a line
> after expansion is complete are ignored as normal whitespace.*
The documentation around that example treats it as a line separation
issue.
It can be explained like this: the result of an expansion at the top-level
is not automatically treated as Make syntax.
For instance, the following example also doesn't work, yet does not have
any line ending issue:
ASSIGNMENT := A := B
$(info $(ASSIGNMENT)) # prints A := B
$(ASSIGNMENT)
$(info $(A)) # hoping to see B printed
Instead, the curious error message is produced against the $(ASSIGNMENT)
line:
A := B
Makefile:5: *** empty variable name. Stop.
If you wish the expansion of $(...) syntax to be correctly treated as
Makefile syntax and incorporated into the compilation, you must use
the $(eval) operator:
ASSIGNMENT := A := B
$(info $(ASSIGNMENT)) # prints A := B
$(eval $(ASSIGNMENT))
$(info $(A)) # hoping to see B printed
Now the output is:
A := B
B
make: *** No targets. Stop.
The documentation does state that the way to do it $(eval).
The thing with the newlines and the recipe line being confused as a
prerequisite is correct, of course, but in a way secondary.
The main concept is that simply by evaluating a variable, or
other expansion, outside of any construct, you do not induce
re-evaluation of syntax. You must evaluate the $(eval ...)
specifically.
Expansions do substitute into syntax, but only in specific
places under control of that syntax. So this won't work
either:
ASSIGNMENT_OP = :=
A $(ASSIGNMENT_OP) B
$(info $(A))
Although $(ASSIGNMENT_OP) evaluates to :=, by the time that
happens it is too late; the A $(ASSIGNMENT_OP) B line was
not recognized as being assignment syntax.