为什么我的行情消失了? (GNU make / sh)

时间:2015-01-27 04:00:00

标签: shell makefile cygwin gnu-make

我在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"

1 个答案:

答案 0 :(得分:1)

make 决定重建目标时,它会扩展配方,然后将结果中的每一行分别传递给shell的新调用。

除了之外,作为优化,当行不包含元字符时(即,shell特别解释的字符,类似{}之类的字符时,无需将其传递给shell。 {1}},<>"等)。在这种情况下, make 直接执行该行。 AFAICT此列表未记录。

就个人而言,在Windows上,我只使用cygwin make。为什么?因为它在所有这些角落情况下更加兼容。我曾经到过一个mingw make的地方,其中5个反斜杠是不够的,6个太多了。啊!

另请注意,Windows中的命令行解析是疯狂的。内置于&的{​​{1}}何时删除双引号?相信我,cygwin'just works'™(并行建筑仅值得进入)。