%% Manoj Srivastava <[EMAIL PROTECTED]> writes: ms> I would claim that the makefile lexer should be string-aware, and ms> not process # characters as comments inside quoted strings. I'm ms> not positive this is a bug, but it seems like one to me.
It's not a bug. Over 20 years of make history, plus various versions of the POSIX and SingleUNIX standards, not to mention hundreds of thousands of makefiles already existing, reaffirm that make is not string-aware. Changing this would not only break huge numbers of makefiles, but it is not even possible. What is a "string"? What is the proper way to escape things inside a string? Remember that make doesn't _HAVE_ to invoke /bin/sh to run commands; you can change the SHELL variable to anything you like and make will invoke that instead. So, assuming Bourne shell semantics, or any other semantics, when dealing with command scripts is completely outside of make's purview. ms> ###################################################################### ms> If a filename contains a space or a dollar, make/its default rules ms> fail to escape or quote the name correctly when invoking the ms> compiler. See above. There is no way make _can_ quote things correctly for you, because there is no way that make can know what the right way to quote things is. Even if it could know what the right quoting is, as I mention below, by the time make gets to this point it doesn't know _itself_ what the right way is to quote the string (except in simple cases like $< and $@ which are single filenames). Make is doing exactly the right thing in each of these cases: it performs its quoting and escaping properly and sends the resulting text string to whatever interpreter is contained in SHELL. Since it cannot know what that interpreter is or how it works, it simply passes exactly what you gave it. _All_ of the failures below are due to the way the _shell_ handles the command line, after make is done with it. ms> cc -c -o pound#file.o pound#file.c ms> Pounds work Hm. This might not work with other shells; the rules about when the shell treats a # as a comment and when it doesn't are sometimes subtlely different between shells. ms> cc -c -o dollar$file.o dollar$file.c ms> cc: dollar.c: No such file or directory Right, because there is no shell variable $file, so "dollar$file.c" is expanded by the shell to just dollar.c. ms> cc -c -o space file.o space file.c ms> cc: cannot specify -o with -c or -S and multiple compilations Right, because there is no quoting here so these are treated as separate words. ms> Things to note: ms> * 'cc dollar$file.o', $file is not set so cc tries to read 'dollar.c' ms> and fails. The $ should have been escaped but there is no way to escape ms> it in the Makefile that will work. Of course there is! If you are going to be dealing with odd filenames like this you have to rewrite the default rule, like this: OUTPUT_OPTION = -o '$@' %.o : %.c $(COMPILE.c) $(OUTPUT_OPTION) '$<' ms> * 'cc space file.c', same thing, the space is not escaped so cc tries ms> to read 'space.c' and fails. Adding an additional \ in the Makefile ms> results in make complaining it cannot find 'space\ file.c'. Again, you rewrite the rule as above. ms> * Putting single or double quotes around the troublesome filenames does ms> not work: make takes them to be part of the file name. Again, instead of changing the filename you rewrite the rule. ms> * Escaping the pound sign works. I'm not sure how make invokes cc (via ms> fork()/exec(), system(), sh?), but it seems no shell is ms> involved since '#' would make the start of the comments. Not necessarily, as above. Make always invokes _all_ commands "as if" they were sent to the interpreter in SHELL. That is, from looking at the results there should be no way to tell if it doesn't. For efficiency make _will_ use a direct fork/exec if SHELL is /bin/sh, and the command is simple enough to not need the shell. To know if the command is simple enough, make has a list of shell-special characters and if any of those characters appears anywhere in the command script, make will use the shell. Otherwise it uses fork/exec. Note that "#" _is_ one of those special characters, so in your example the shell was invoked. ms> * '$' behaves strangely. It is interpreted by make before ms> anything else, including '\'. So '\$' does not work and one must use ms> '$$' (which is documented). This is a bit confusing. Would it break many ms> makefiles if '\' were interpreted first so that '\$' is equivalent to ms> '$$'? It would break thousands and thousands. There are innumerable makefiles with scripts like: echo foo | sed s,foo\$$,bar, > $@ or whatever. As I mentioned above, make's syntax has been essentially set in stone for over 20 years. It's simply not possible to even consider any change which would not be 100% backward-compatible. ms> * Workaround: adding rules like the one below solve this problem: ms> .c.o: ms> cc -c -o '$*.o' '$<' This is the solution, not the workaround. ms> * Optional question: how would one write a generic command to link a ms> bunch of object files containing spaces together? It seems "'$^'" ms> would not work. The short answer is, you cannot productively deal with filenames containing whitespace in make. There are hacks and tricks that can get you part of the way, but they're all gross to use and hard to work with, and they don't solve the entire problem. Fundamentally, make is a string-based utility. It concatenates strings. It doesn't know anything about filenames. The contents of $^ internally to make is just a long string that it inserts into another string (the command script) and then gives to the shell to interpret. The internal value of something like $^ is _NOT_ a discrete list of filenames like ARGV or whatever, such that make can delineate individual filenames. Make was never designed with these kinds of files in mind, and it is far to established (and the syntax is far too forgiving) to allow for fundamental changes at this point. If you need to deal with filenames containing these kinds of special characters on a regular basis, I respectfully submit that perhaps make is not the tool for you. There are a number of other build control utilities out there and some of them do handle these issues much better than make. -- ------------------------------------------------------------------------------- Paul D. Smith <[EMAIL PROTECTED]> Find some GNU make tips at: http://www.gnu.org http://www.paulandlesley.org/gmake/ "Please remain calm...I may be mad, but I am a professional." --Mad Scientist _______________________________________________ Bug-make mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-make