help-make
[Top][All Lists]
Advanced

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

Re: Handling '=' in a filename together with $(eval )


From: Kaz Kylheku
Subject: Re: Handling '=' in a filename together with $(eval )
Date: Tue, 18 Feb 2025 21:50:11 -0800
User-agent: Roundcube Webmail/1.4.15

On 2025-02-13 07:15, Alejandro Colomar wrote:
> Hi Renaud,
> 
> On Thu, Feb 13, 2025 at 04:11:45PM +0100, Renaud Pacalet wrote:
>> On 2/13/25 15:46, Alejandro Colomar wrote:
>> > touch: cannot touch 'obj/asd=fgh': No such file or directory
>>
>> This seams to be a 'touch' error, not 'make'. What shell are you using? Does 
>> it support unquoted '=' in file names? Does the 'obj' directory exist?
> 
> I'm not too worried about the touch error yet.  I'm worried that make(1)
> is misbehaving (I excepted that it would fail due to missing
> prerequisites).


The trick with these = name is never to mention = in the Makefile syntax.
Use pattern rules which only mention an abstract stem.

Obtain the name with equal sign as a piece of data, that is not interpreted
as Makefile code; do not try to $(eval ...) it or anything of the sort.

$ ls
'=.1'   ls.1   Makefile
$ cat Makefile
manfiles := $(wildcard *.1)

manzips := $(patsubst %.1,%.1.gz,$(manfiles))

%.1.gz: %.1
        gzip -c $< > $@

.phony: ALL
ALL: $(manzips)

clean:
        rm -f $(manzips)
$ make
gzip -c ls.1 > ls.1.gz
gzip -c =.1 > =.1.gz
$ make clean
rm -f ls.1.gz =.1.gz

See: this is working. However, we cannot do even so much as to try to select
the =.1.gz target from the command line to isolate it for building:

$ make =.1.gz
make: *** empty variable name.  Stop.

That doesn't stop our "all" phony target from depending on that file,
which was ferrreted out by wildcard and patsubst.
The equal sign doesn't prevent the pattern rule from matching.


Here is another trick which lets us mention the equal sig file name if
we calculate it with a shell echo command:


$ cat Makefile
manfiles := $(wildcard *.1)

manzips := $(patsubst %.1,%.1.gz,$(manfiles))

%.1.gz: %.1
        gzip -c $< > $@

.phony JUST_ONE:
JUST_ONE: $(shell echo =.1.gz)

clean:
        rm -f $(manzips)
$ make
gzip -c =.1 > =.1.gz

Without this $(echo ...) wrapping get the empty variable name error. Why?
Because the right hand side of a rule can be a something called
a target-specific assignment. But text coming out of a $(shell ...)
substitution is not parsed as such; it is dumb text.

This is actually a piece of cake compared to the problem of how to
make a similar trick produce a name with spaces. The text coming
out of $(shell echo) will be broken into items on whitespace;
be glad you don't have that problem (too).




reply via email to

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