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 <a...@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-m...@gnu.org> Signed-off-by: Alejandro Colomar <a...@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