我在Windows上使用GNU makefile在我的工作中尝试学习。给我带来很多麻烦的食谱线是
$(SED) -n "/Format ID $(def_format_id)/,/End Format ID $(def_format_id)/ p" "$(def_format_altsec_header)" > "$(def_format_file)"
对C:/GNU1_06/bin/sed: -e expression #1, char 7: unterminated address regex
失败。
为了尝试理解我在过去几个小时里一直抨击我的头脑的行为,我把它改成了一个简单的命令,让sed启动和停止,所以我可以看看到底是什么'使用Process Explorer调用:
$(SED) -e s/blah//
ProcExp显示make正在使用预期的命令行直接调用sed。但是,如果单引号参数,则make调用完全相同的东西(在命令行中找不到引号)。
使用双引号时,事情变得非常奇怪。
调用C:/GNU1_06/bin/sh.exe -c "C:/GNU1_06/bin/sed -e \"s/blah//\""
到目前为止一直很好,但随后sh调用C:\GNU1_06\bin\sed.exe -e s/blah//
好像逃脱的报价从未出现过。
这到底发生了什么?为什么我的引号会在sed运行之前消失在幽暗中?
更新:这似乎与$(SED)是完全指定的路径有关。单独使用sed.exe时未观察到此行为(并且ProcExp证明它使用与完全指定路径相同的sed副本)。
此问题在最小的makefile中重现
.PHONY: all
all:
C:/gnu1_06/bin/sed.exe -n "/Format ID 01010101/,/End Format ID 01010101/ p" "./FORMAT/BIGHILO/AC/99/sff_altsec_01_data.h"
答案 0 :(得分:1)
当 make 决定重建目标时,它会扩展配方,然后将结果中的每一行分别传递给shell的新调用。
除了之外,作为优化,当行不包含元字符时(即,shell特别解释的字符,类似{}之类的字符时,无需将其传递给shell。 {1}},<
,>
,"
等)。在这种情况下, make 直接执行该行。 AFAICT此列表未记录。
就个人而言,在Windows上,我只使用cygwin make。为什么?因为它在所有这些角落情况下更加兼容。我曾经到过一个mingw make的地方,其中5个反斜杠是不够的,6个太多了。啊!
另请注意,Windows中的命令行解析是疯狂的。内置于&
的{{1}}何时删除双引号?相信我,cygwin'just works'™(并行建筑仅值得进入)。