qnt*_*ntm 69 shell gnu makefile
我有一个包含多个文件的目录,其中一些文件的名称中有空格:
Test workspace/
Another directory/
file1.ext
file2.ext
demo 2012-03-23.odp
Run Code Online (Sandbox Code Playgroud)
我$(wildcard)在这个目录上使用GNU的命令,然后使用遍历结果$(foreach),打印出所有内容.这是代码:
FOO := $(wildcard *)
$(info FOO = $(FOO))
$(foreach PLACE,$(FOO),$(info PLACE = $(PLACE)))
Run Code Online (Sandbox Code Playgroud)
以下是我希望看到的内容:
Test workspace
Another directory
file1.ext
file2.ext
demo 2012-03-23.odp
Run Code Online (Sandbox Code Playgroud)
这是我真正得到的:
Test
workspace
Another
directory
file1.ext
file2.ext
demo
2012-03-23.odp
Run Code Online (Sandbox Code Playgroud)
后者对我来说显然毫无用处.该文档为$(wildcard)它返回一个"名字的空格分隔的名单",但完全平整出国家不承认这引起了巨大的问题.也不对文件进行$(foreach).
有可能解决这个问题吗?如果是这样,怎么样?重命名每个文件和目录以删除空格不是一个选项.
Jan*_*dec 49
错误#712表明make不处理带空格的名称.从来没有.
我找到了一篇博文,说它是通过使用\(\\似乎是拼写错误或格式化人工制品)来逃避空间而部分实现的,但是:
$(wildcard).$?,$^和$+以及任何用户定义的变量.这反过来意味着虽然$(wildcard)匹配正确的文件,但无论如何你都无法解释结果.因此,使用明确或非常简单的模式规则,您可以使其工作,但除此之外,您运气不好.您将不得不寻找支持空间的其他构建系统.我不确定jam/bjam是否有,scons,waf,ant,nant和msbuild都应该有效.
Pau*_*per 19
GNU Make在空格分隔的文件名中表现很差.
空格在整个单词列表中用作分隔符.
这篇博文很好地总结了这种情况,但是警告:它错误地使用了\\而不是\
target: some\ file some\ other\ file
some\ file some\ other\ file:
echo done
Run Code Online (Sandbox Code Playgroud)
您也可以使用变量,因此这也可以
VAR := some\ file some\ other\ file
target: $(VAR)
$(VAR):
echo done
Run Code Online (Sandbox Code Playgroud)
只有该wildcard功能才能识别逃逸,所以你不能做任何花哨的事情.
但是不要忘记你的shell也使用空格作为分隔符.
如果我想更改echo done为touch $@,我必须添加斜杠以逃避它为我的shell.
VAR := some\ file
target: $(VAR)
$(VAR):
touch $(subst \,\\,$@)
Run Code Online (Sandbox Code Playgroud)
或者,更有可能的是,使用引号
VAR := some\ file some\ other\ file
target: $(VAR)
$(VAR):
touch '$@'
Run Code Online (Sandbox Code Playgroud)
最后,如果你想避免很多痛苦,无论是在GNU make还是在你的shell中,都不要在文件名中加上空格.如果你这样做,希望Make的有限功能就足够了.
Mr_*_*ags 13
此方法还允许使用列出的文件名,例如作为$?文件列表的用户变量.
在Make中处理空格的最佳方法是用空格替换其他字符.
s+ = $(subst \ ,+,$1)
+s = $(subst +,\ ,$1)
$(call s+,foo bar): $(call s+,bar baz) $(call s+,bar\ baz2)
# Will also shows list of dependencies with spaces.
@echo Making $(call +s,$@) from $(call +s,$?)
$(call s+,bar\ baz):
@echo Making $(call +s,$@)
$(call s+,bar\ baz2):
@echo Making $(call +s,$@)
Run Code Online (Sandbox Code Playgroud)
输出
Making bar baz
Making bar baz2
Making foo bar from bar baz bar baz2
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用所有GNU Make函数安全地操作文件名列表.在规则中使用这些名称之前,请务必删除+.
SRCS := a\ b.c c\ d.c e\ f.c
SRCS := $(call s+,$(SRCS))
# Can manipulate list with substituted spaces
OBJS := $(SRCS:.c=.o)
# Rule that has object files as dependencies.
exampleRule:$(call +s,$(OBJS))
# You can now use the list of OBJS (spaces are converted back).
@echo Object files: $(call +s,$(OBJS))
a\ b.o:
# a b.o rule commands go here...
@echo in rule: a b.o
c\ d.o:
e\ f.o:
Run Code Online (Sandbox Code Playgroud)
输出
in rule: a b.o
Object files: a b.o c d.o e f.o
Run Code Online (Sandbox Code Playgroud)
此信息全部来自其他人发布的博客.
大多数人似乎建议在路径中使用空格或使用Windows 8.3路径,但如果必须使用空格,则转义空格和替换有效.
如果你愿意更多地依赖你的 shell,这给出了一个可以包含空格的名称的列表:
$(shell find | sed 's: :\\ :g')
Run Code Online (Sandbox Code Playgroud)