[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Handling '=' in a filename together with $(eval )
From: |
Alejandro Colomar |
Subject: |
Re: Handling '=' in a filename together with $(eval ) |
Date: |
Thu, 13 Feb 2025 16:24:17 +0100 |
Hi Paul,
On Thu, Feb 13, 2025 at 10:08:36AM -0500, Paul Smith wrote:
> On Thu, 2025-02-13 at 15:46 +0100, Alejandro Colomar wrote:
> > I'm trying to find a way to correctly handle files with a '=' in
> > their name with make(1). I know I'm doing something in the edge of
> > what's possible, so the answer may very well be "you can't", but if
> > it's possible, I'd like to learn how. The reason is that the file
> > exists in another project, and I'd like to use it with my Makefile; I
> > can't fix the filename.
>
> The correct way to handle most special characters in makefile syntax is
> to hide them behind a make variable.
I'm aware of that trick. However, I think it won't work for me, since
I don't hardcode the filenames in the Makefile, but get them with
$(shell find ...)
instead.
Here's the commit that I applied when I added support for ':', so that
you see the real Makefile code I'm talking about:
<https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit/?id=8a135d7703fa82e9b442ea3c3b1e9d119b25660a>
commit 8a135d7703fa82e9b442ea3c3b1e9d119b25660a
Author: Alejandro Colomar <alx@kernel.org>
Date: Wed Apr 26 01:39:22 2023 +0200
*.mk: Handle pathnames with ':'
Since make(1) uses ':' as a special character in rules, it needs to
be
handled carefully. A way to make it work is to escape it with
'\:'. We
can use sed(1) to do that right when we get the pathnames. The only
problem with ':' is in rules' targets and prerequisites: everywhere
else
it's fine; so let's discuss what needs to be done in those places:
- In the targets, it's as easy as escaping.
- In prerequisites, we can't second-expand variables containing
such
pathnames, as the '\' would not be used by make(1) to escape the
':',
but it would be interpreted as part of the pathname. This means
we
need to expand rules written using second expansion into several
rules that only expand their variables once.
- $(wildcard ...) also performs the escape, so after using it the
pathnames are not escaped. If we used those variables in
targets, we
would need to escape the ':'s again, but since we don't we can
skip
that. The trick to make this work is to second-expand these
variables.
Link: <https://stackoverflow.com/a/76096683/6872717>
Cc: GNU Make <bug-make@gnu.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
> This works:
>
> EQ = =
>
> all: foo$(EQ)bar
>
> foo$(EQ)bar: ; @echo $@
>
> gives:
>
> foo=bar
Hmmm, it seems it doesn't work with $(eval ...). I do need to $(eval ).
alx@devuan:~/tmp/symbolds$ cat Makefile
EQ = =
obj := obj/asd$(EQ)fgh
all: $(obj)
$(info $(obj) : obj/% : src/%)
$(eval $(obj) : obj/% : src/%)
$(obj):
touch $@
alx@devuan:~/tmp/symbolds$ make
obj/asd=fgh : obj/% : src/%
touch obj/asd=fgh
touch: cannot touch 'obj/asd=fgh': No such file or directory
make: *** [Makefile:10: obj/asd=fgh] Error 1
>
> This works because make will chop up a line into sections before it
> expands variables.
Here's the exact $(eval) code I need to use:
$(foreach s, $(MANSECTIONS), \
$(eval MAN$(s)PAGES := \
$(filter-out $(MANINTROPAGES), \
$(filter $(MAN$(s)DIR)/%, \
$(filter %.$(s), \
$(MANPAGES))))))
That code allows me to generate one variable per directory that I find
under man/. That means that if I run my build system on a system with
man10/, even if I didn't anticipate that directory, it will work.
If I find out that it's impossible to make it work, I guess I'll
hard-code the subdirectories instead of this eval loop. That would
probably make it work.
Thanks for the help!
Have a lovely day!
Alex
--
<https://www.alejandro-colomar.es/>
signature.asc
Description: PGP signature
Re: Handling '=' in a filename together with $(eval ), Renaud Pacalet, 2025/02/13