我有一个根据列表内容生成 C 文件的 makefile 规则。
LIST = foo \
bar
generated.c:
@echo "Creating $@"
(echo "#include <stuff.h>"; \
echo "void init_local() {"; \
for i in $(LIST) ; do \
echo " init_$$i();"; \
done;
echo "}") > $@
在 Linux 平台上,这给了我预期的结果:
#include <stuff.h>
void init_local() {
init_foo();
init_bar();
}
但是,在我的 Windows 7 64 位平台上,GNU Make 3.82 (x86_64-w64-mingw32),
我得到以下信息(全部在一行中):
"#include <stuff.h>"; \"void init_local() {" \
for i in foo bar; do echo " init_$i();"; done; echo "}"
我还尝试打破个别行的规则:
echo "#include <stuff.h>" > %@
echo "void init_local() {" >> $@
...
使用该解决方案,我每行有 1 个字符串,但引号仍然存在!
我将如何更改规则以使生成的文件在 Linux 和 Windows 平台上都正确?
最佳答案
这是因为 DOS 有自己的命令分隔符 - &(类似于 bash 中的 ;)。但我建议使用 make echo 而不是在 DOS 和 bash 中工作的 shell echo:
但这还不是全部,据我所知,您不需要在输出中使用引号 (""),这就是为什么您不应该将它们传递给 echo,而是转义特殊符号<强>^强>。
ifeq ($(OS_TYPE),linux)
Q="
ESC=
else
Q=
ESC=^
endif
generated.c:
@echo "Creating $@"
echo $(Q)#include $(ESC)<stuff.h$(ESC)>$(Q) > $@
echo $(Q)void init_local() {$(Q) >> $@
...
此外,您的 bash for..;do..;done; 循环应替换为 make $(foreach, $(LIST), echo ...) 对两个 shell 都是正确的。
是的,我知道,这看起来很难看,但那是因为奇怪的 DOS 规则。如果您需要生成大量内容,我建议您使用 awk、python 或 perl。
关于makefile - make echo 在生成的文件中包含引号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13631551/