Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get pattern rules to match file names with spaces in Makefile?

In the GNU make docs, '%' is documented to match "any nonempty substring". However, it seems it actually only matches non-empty substrings that do not contain whitespace. For example, say you do this:

mkdir /tmp/foo
cd /tmp/foo
echo 'int main() { return 0; }' > "test.c"
echo 'int main() { return 0; }' > "test space.c"

Now, you should be able to build these using GNU Make's built-in pattern rules:

anthony@Zia:/tmp/foo$ make "test"
cc     test.c   -o test
anthony@Zia:/tmp/foo$ make "test space"
make: *** No rule to make target `test space'.  Stop.

The same problem happens when you write a makefile.

anthony@Zia:/tmp/foo$ rm test
anthony@Zia:/tmp/foo$ echo 'all: test test\ space' > Makefile 
anthony@Zia:/tmp/foo$ make
cc     test.c   -o test
make: *** No rule to make target `test space', needed by `all'.  Stop.

Even if you explicitly add in a %: %.c rule, the result is the same. But if you add in an explicit rule to the Makefile, like this, it works:

test\ space: test\ space.c
    $(CC) -o "$@" "$<"     # first char is tab, of course.

Is there a trick to get spaces to work with implicit rules?

edit

I've sent a bug report: http://lists.gnu.org/archive/html/bug-make/2011-06/msg00002.html

like image 910
derobert Avatar asked Jun 03 '11 23:06

derobert


People also ask

What does Addprefix do in makefile?

What is add prefix in makefile? $(addprefix prefix , names …) The argument names is regarded as a series of names, separated by whitespace; prefix is used as a unit. The value of prefix is prepended to the front of each individual name and the resulting larger names are concatenated with single spaces between them.

What is Notdir in makefile?

$(notdir names …) Extracts all but the directory-part of each file name in names . If the file name contains no slash, it is left unchanged. Otherwise, everything through the last slash is removed from it. A file name that ends with a slash becomes an empty string.

What is filename pattern?

You can specify a file name pattern, using wildcard characters, to identify a file to be read by the FileInput, CDInput, and FTEInput nodes. You can also specify a file name pattern, using a single wildcard character, to name the file to be created by the FileOutput and FTEOutput nodes.

What is rule in makefile?

A rule appears in the makefile and says when and how to remake certain files, called the rule's targets (most often only one per rule). It lists the other files that are the prerequisites of the target, and the recipe to use to create or update the target.


2 Answers

I don't believe so. The notion of a list of whitespace-separated tokens being passed around as a string is pretty deeply ingrained in make. Those lists are parsed and reparsed. There's a reason why spaces in directory and file names is considered bad practice in the UNIX world.

like image 58
Ernest Friedman-Hill Avatar answered Dec 09 '22 23:12

Ernest Friedman-Hill


This is a kludge, but as of today, people still get given paths with spaces in sometimes.

Anyway, making a link instead of directly accessing the directory in the % rule works OK.

# GNU makefile
DIR_WITH_SPACE=/c/Users/me/My\ Code

# *** DOESN'T WORK ***
%.h : $(DIR_WITH_SPACE)/%.h
    cp -v "$<" "$@"

fix:
  ln -s $(DIR_WITH_SPACES) dir_fixed

# Does work :)
%.h : dir_fixed/%.h
    cp -v "$<" "$@"
like image 22
ahnkle Avatar answered Dec 09 '22 23:12

ahnkle