首页 > 解决方案 > 我不希望 gnu make 在规则中将自动变量传递给 gnuplot 脚本

问题描述

我在 gnu-make Makefile 中有一个目标,如下所示:

生成文件片段:

rateplots: binattrate.bin
    gnuplot -c $(src)\Plot.gp binattrate.bin

实用程序 gnuplot 将 $1 解释为 Plot.gp 脚本中的特殊字段,当直接从 shell 终端调用时,脚本会正确运行。当从上面显示的 Makefile 片段作为规则运行时,它在 gnuplot- 中失败。

我发现我可以在 Plot.gp 脚本中用双倍的 $ 代替。也就是说,将 Plot.gp 中的 $1 替换为 $$1,make 规则的功能就像它没有从 shell 终端替换一样。gnuplot 似乎看到了从 make 传递的命令参数 $0、$1、$2 等。我不想要这个。我希望 gnuplot 将 $1 解释为它自己的字段变量。

我可以在调用 gnuplot 以在 Plot.gp 中用 $ 替换 $$ 之前在 make 中破解 sed 脚本,但我更喜欢不修改原始代码的解决方案,因为 hack 增加了代码的复杂性并使其他人更难了解makefile。总之,我希望 gnu-make 在不替换 $1 命令参数变量或任何其他隐匿变量的情况下调用规则。

我正在使用 cygwin64 在 Windows 10 平台上工作

  1. 和 GNU Make 4.3 和
  2. gnuplot 5.2(补丁级别 8){请参阅帖子末尾添加的注释}

这是 Plot.gp 中失败的行:

plot inputfile every ::1 binary format=fileformat \
   using (gtime+$1):2  with lines linestyle 1 linecolor rgbcolor "black" linewidth 3 title 'GPS1/GPS2'

如果我将 $1 替换为 $$1,则代码的工作方式与从命令 shell 手动调用时一样。

我通过添加一个使用 sed 将 $$ 替换为 $ 的规则来解决这个问题,从而发出“scratch.gp”:

rateplots: binattrate.bin
  cat $(src)/Plot.gp | sed 's/\$$/\$$\$$/g' >scratch.gp
  gnuplot -c scratch.gp binattrate.bin

我发现该解决方法在其他 5 个相关脚本中很可靠,但它不应该这样做。

我推测这是 cygwin 或 Windows cmd shell 的某些元素下的 gnuplot(相当新)中的一个错误——但我不知道。我正在经历的事情应该是不可能的。找到解决方案非常重要。

谢谢你们。

注意:我发现当我从我的 shell 终端窗口调用 gnuplot 时:

gnuplot --version

返回以下内容:

gnuplot 5.2 patchlevel 8

但是,当创建一个生成文件以在配方中发出相同的命令时:

all:
     gnuplot --version

命令

make all

返回

gnuplot --version
gnuplot 5.4 patchlevel 0

总之,gnu 以某种方式调用gnuplot 5.4 patchlevel 0而在 shell 终端中手动发出相同的命令调用gnuplot 5.2 patchlevel 8。为什么会这样?

我进一步观察到gnuplot 5.4 patchlevel 0包含版本 4 向后兼容功能(可能包括对 $n 环境变量的解释。

标签: makefilegnuplotgnu-make

解决方案


我的问题的所有元素都来自:

  1. gnuplot 5.4.0 中的错误
  2. make 调用 /bin/sh (linux bash) 而不是 windows shell。

我向 gnuplot 开发组 ( https://sourceforge.net/p/gnuplot/bugs/2368/ )提交了一份关于 cygwin 发行版中 gnuplot 5.4.0 的错误报告。开发人员说它将在 5.4.1 中修复。

该错误是由于不推荐使用的 $0、$1、$2 等符号被错误地启用并分配给 gnuplot (5.4.0) 到命令行参数。

有漏洞的 Gnuplot 5.4.0 是“gnuplot-base.exe”,而“过时的”gnuplot 5.2.8 在 cygwin 发行版中显示为“gnuplot.exe”。

我观察命令“gnuplot”:

  1. 从 Windows cmd shell 运行“gnuplot.exe”(5.2.8)。
  2. 而从 /bin/sh 链接到 gnuplot 指向“gnuplot-base.exe”(5.4.0)。

“make”实用程序通过 /bin/sh 提交规则,解释为什么 gnuplot 在“make”中失败,而不是从命令 shell 中失败。

我正在通过在“make”规则中调用“gnuplot.exe”而不是“gnuplot”来解决问题。“gnuplot.exe 是过时的 5.2.8 版本。

谢谢你。我爱你们。


推荐阅读