Is there a way to get spaces inside target names working when using make.exe? It seems to be impossible if this really ancient bug report is correct:
http://savannah.gnu.org/bugs/?712
For reference, the big problem is that pieces of makefile commands like:
"foo bar baz": $(OBJ)
$(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)
... seem to get treated as three separate commands: one to build "foo (note the included "), one to build bar, and lastly, one to build baz" (again, including "). This is because make.exe seems to be using space as a delimiter.
However, it's reasonable to assume that one might want to build "Hello World.exe" for example. This doesn't seem to be possible. Double quotes don't work, and neither does escaping the separate words (I've read that somewhere, don't remember the link):
"foo\\ bar\\ baz": $(OBJ)
$(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)
Is there any other way to fix this? The official manual only confirms the tokenize-by-spaces stuff, but doesn't provide a way to use space for any other purpose:
http://www.gnu.org/software/make/manual/make.html#Rule-Syntax
Edit: as suggested, I've tried single slashes too, but these have the exact same effect as double slashes. Make complains it can't find rules for the first word:
mingw32-make.exe: *** No rule to make target `foo', needed by `all'. Stop.
The executable "foo bar baz.exe" is correctly produced though, but linking is done each time per word.
Instead of double backslash use single ones. The following Makefile works (at least for gnu make):
goal: foo\ bar
foo\ bar:
gcc -o "foo bar" "foo bar.c"
as Matthias said, it's a matter of "\ ", but of double quote too. Here is how I succeded into this :
EXECUTABLE=foo\ bar\ baz
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) -o "$@" $(LDFLAGS)
Note the double quotes around the $@
It seems to me that when make reach the target "$(EXECUTABLE)" it expands the "\ ", so the command line becomes
gcc file.o -o foo bar baz -LFlags
which is not what you want, you want double quotes around the name of the file.
Now you are on windows and I don't remember how it deals with spaces in names, so as Matthias said, first check how "cmd.exe" deals with spaces (except by surrounding name with double quotes...)
Maybe easier to consider a simpler Makefile, which ignores the dependencies in the standard targetRule: dependencies
invocation. The OP is for Windows, and the below is done on Linux in the bash
shell; but it should probably be applicable to Windows using the bash
shell via cygwin
, I guess. I have the following in my Makefile
(note, there should be a TAB before the echo
commands, which SO converts to spaces):
testA:
echo "testA"
unrelated:
echo "unrelated"
testA\ clean:
echo "testA clean"
clean:
echo "clean"
If I call make
with targets clean
or testA
in the bash
shell terminal, I get the expected results:
$ make testA
echo "testA"
testA
$ make clean
echo "clean"
clean
Now, if I call make testA clean
just written as is, the bash
shell will split the arguments at spaces, so make
will receive two arguments, and will run them separately:
$ make testA clean
echo "testA"
testA
echo "clean"
clean
... but if I wrap the target supplied to make
in quotes - or if I escape the space - the shell will understand that it is supposed to be a single argument with a space inside, and will propagate it as such to make
, which will proceed to execute what is written as the testA\ clean
target rule:
$ make "testA clean"
echo "testA clean"
testA clean
$ make testA\ clean
echo "testA clean"
testA clean
One consequence of this, is that unfortunately you cannot "TAB" at the command line for autocompletion of testA\ clean
; if you type make te
TAB at the command line, only testA
will be autocompleted automatically (and the testA\ clean
will not be shown as an autocomplete option).