help-make
[Top][All Lists]
Advanced

[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.






reply via email to

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