Hi, I began, for automatic variables containing only one filename, to put them between simple quotes, and to try to escape my filenames in my makefiles, so that if one day someone tries to use my makefiles for files with special chars in them like spaces or quotes.
Also, using quotes is especially useful to get more meaningful errors: for instance, recently, I tried to put together some (probably unrelated) gnustep makefile and the makefile of the first World Wide Web Browser (Nexus), and this line caused the following error (ignoring the existence of --warn-undefined-variables, that isn’t known enough):
$(ECHO_NOTHING_RECURSIVE_MAKE)$(MAKE) -f $(MAKEFILE_NAME) --no-print-directory --no-keep-going \
make[1]: --no-print-directory: No such file or directory make[1]: *** No rule to make target '--no-print-directory'. Stop. make: *** [internal-all] Error 2
So before to uglily add “MAKEFILE_NAME = $(lastword $(MAKEFILE_LIST))” in the main makefile, since this variable didn’t exist, -f took “--no-print-directory” as its argument and found this file didn’t exist, while with quote -f would have get its argument, but void, and just said:
make: the '-f' option requires a non-empty string argument […]
Then I implemented some escape functions to do this more properly, and finding out I had to do it without side effects to get it working anywhere in the makefile (or I would just get a side-effect-only procedure defining a variable), and doing it recursively, I found out I needed some lastwords functions to be to firstword what cdr is to car:
#!/usr/bin/make -f none = # escape_spc = $(subst $(none) ,\ ,$(1)) escape_char = $(subst $(1),$(1),$(2)) # I add the right quotes inside comments # so emacs syntax coloring disworks less escape_quot = $(call escape_char,','\'') #' lastwords = $(wordlist 2,$(words $(1)),$(1)) escape_chars = $(if $(1),$(call escape_chars,$(call \ lastwords,$(1)),$(call escape_char,$(firstword $(1)),$(2))),$(2)) # it is important that the escape char (antislash, \) is first, other # wise escapings will be escaped escape = $(call escape_spc,$(call escape_chars,\ & ( ) ; < > ? | \ ' " `,$(1))) #' # same thing all:; echo $(call escape,'zero' (one) & "two" <thee> ? `cmd` \o/ |o|)
Also I was wondering… would there be some possible mechanism so that a filename with spaces in it might be appropriatedly treated by implicit rules? or is it intrinsic to, say, automatic variables splitting with spaces? PS: the right MIME type for makefiles is text/x-makefile right? because text/plain looks a bit poor and reductive to me…
_______________________________________________ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make