11

使用 make.exe 时,有没有办法让目标名称中的空格起作用?如果这个非常古老的错误报告是正确的,这似乎是不可能的: http ://savannah.gnu.org/bugs/?712

作为参考,最大的问题是 makefile 命令的片段,例如:

"foo bar baz": $(OBJ)
    $(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)

...似乎被视为三个单独的命令:一个构建“foo(注意包含的”),一个构建 bar,最后一个构建 baz”(同样,包括“)。这是因为 make.exe 似乎使用空格作为分隔符。

然而,假设一个人可能想要构建“Hello World.exe”是合理的。这似乎是不可能的。双引号不起作用,转义单独的单词也不起作用(我在某处读过,不记得链接了):

"foo\\ bar\\ baz": $(OBJ)
    $(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)

有没有其他方法可以解决这个问题?官方手册仅确认 tokenize-by-spaces 的东西,但没有提供将空间用于任何其他目的的方法: http ://www.gnu.org/software/make/manual/make.html#Rule-句法

编辑:正如建议的那样,我也尝试过单斜杠,但它们与双斜杠具有完全相同的效果。抱怨它找不到第一个单词的规则:

mingw32-make.exe: *** No rule to make target `foo', needed by `all'.  Stop.

虽然可以正确生成可执行文件“foo bar baz.exe”,但每次每个单词都会进行链接。

4

3 回答 3

2

而不是双反斜杠使用单个反斜杠。以下 Makefile 有效(至少对于 gnu make):

goal:   foo\ bar

foo\ bar:
    gcc -o "foo bar" "foo bar.c"
于 2013-02-21T15:07:39.483 回答
2

正如马蒂亚斯所说,这是“\”的问题,但也是双引号的问题。这是我成功的方法:

EXECUTABLE=foo\ bar\ baz
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
                $(CC) $(OBJECTS) -o "$@" $(LDFLAGS)

注意 $@ 周围的双引号在我看来,当 make 到达目标“$(EXECUTABLE)”时,它会扩展“\”,所以命令行变为

gcc file.o -o foo bar baz -LFlags

这不是您想要的,您需要在文件名周围加上双引号。

现在你在 Windows 上,我不记得它如何处理名称中的空格,所以正如 Matthias 所说,首先检查“cmd.exe”如何处理空格(除了用双引号括起来的名称......)

于 2013-11-08T10:35:49.317 回答
2

也许更容易考虑一个更简单的 Makefile,它忽略标准targetRule: dependencies调用中的依赖关系。OP适用于Windows,下面是在Linux的bashshell中完成的;但我猜它可能应该适用于使用bashshell的 Windows。cygwin我有以下内容(注意,命令之前Makefile应该有一个,所以转换为空格):TABecho

testA:
    echo "testA"

unrelated:
    echo "unrelated"

testA\ clean:
    echo "testA clean"

clean:
    echo "clean"

如果我make使用目标cleantestAbashshell 终端中调用,我会得到预期的结果:

$ make testA 
echo "testA"
testA
$ make clean
echo "clean"
clean

现在,如果我make testA clean按原样调用,bashshell 将在空格处拆分参数,因此make将接收两个参数,并将分别运行它们:

$ make testA clean
echo "testA"
testA
echo "clean"
clean

...但是如果我将提供给的目标make用引号括起来 - 或者如果我转义了空格 - shell 将理解它应该是一个内部带有空格的单个参数,并将其传播到make,这将继续执行写为testA\ clean目标规则的内容:

$ make "testA clean"
echo "testA clean"
testA clean
$ make testA\ clean
echo "testA clean"
testA clean

这样做的一个后果是,不幸的是,您不能在命令行中使用“TAB”来自动完成testA\ clean; 如果您make teTAB在命令行键入,则 onlytestA将自动完成(并且testA\ clean不会显示为自动完成选项)。

于 2015-02-05T07:11:07.237 回答