views:

58

answers:

2

Hello,

Could you explain me, why Makefile rule:

clean:
    rm -f foo.{bar1,bar2,bar3}

does not result in removing files: foo.bar1 foo.bar2 and foo.bar3? I believe I saw pattern like that many times in various Makefiles, but I'm currently writing my own Makefile and can't make that rule work correctly (no files are removed).

I'm using:

  • gnu make 3.81
  • gnu bash 4.1.5

Bash evals that pattern as I suspect:

$ echo test.{a,b,c}
test.a test.b test.c

Thanks!

UPDATE

Thank to David's hint I found solution for the problem described above. The gnu make uses the /bin/sh by default and that is why a.{1,2,3} isn't evaluated to a.1 a.2 a.3.

To make 'make' use bash instead of sh add following line to your Makefile:

SHELL=/bin/bash

from now a.{1,2,3} will be considered as a.1 a.2 a.3

+1  A: 

Is there a file named clean in the directory? If so, make will consider that target up to date and won't run the corresponding command. To fix that, add this line to your makefile:

.PHONY: clean

If when you run make clean you get the output

make: `clean' is up to date.

then that's probably your problem.

David Zaslavsky
There is no file named 'clean' in directory. The rule is launched when I type: "make clean", but {} isn't evaled so rm tries to remove "foo.{bar1,bar2,bar3}" not the foo.bar ...
A: 

It's because the shell isn't being invoked here, but rather rm is directly. Since the shell does the {} substitution, what rm 'sees' is the raw foo.{bar1,bar2,bar3} string. As there's no such file, nothing happens.

You should use one of GNUmake's string macros to have it perform the expansion for you.

ronys
The makefile in the question worked for me without any macros (in make 3.80 and bash 3.00), so I have my doubts about this.
David Zaslavsky
Oh, and according to the `make` documentation, commands are interpreted by `/bin/sh`.
David Zaslavsky
I don't want to use macros, since I believe it's possible to eval that patterns without macros. See: http://google.com/codesearch?q=file:Makefile$+rm.*\{.*, - unfortunately that does not work for me.
David, that's make sense now:$ bash$ echo a.{1,2,3}a.1 a.2 a.3$ sh$ echo a.{1,2,3}a.{1,2,3}Any ideas, how to force make to use bash instead of sh?
Ok. I found the solution after David's hint about that make uses /bin/sh by default. If you want to use bash, just add on the top of Makefile line SHELL=/bin/bashNow 'clean' rule works fine for me :)