Search code examples
makefilegnuplotgnu-make

I don't want gnu make to pass automatic variables to a gnuplot script in a rule


I have a target in a gnu-make Makefile that looks like this:

Makefile fragment:

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

The utilty gnuplot interpretes $1 as special field in the Plot.gp script and when invoked directly from the shell terminal, the script runs correctly. When run as a rule from the Makefile fragment shown above, it fails in gnuplot-.

I have discovered that I can substitute a doubled $ in the Plot.gp script. That is, substitute $$1 for $1 in Plot.gp and the make rule functions just as it does without substitution from the shell terminal. It appears that gnuplot sees command arguments $0, $1, $2 etc passed from make. I don't want this. I want gnuplot to interpret $1 as it's own field variable.

I can hack a sed script in the make before calling gnuplot to substitute $ for $$ in Plot.gp but I prefer a solution that does not modify the original code as the hack increases the complexity of the code and makes it harder for others to understand the makefile. In summary, I want gnu-make to call the rule without substituting $1 command arguments variables or any other occult variables.

I'm working on a Windows 10 platform with cygwin64

  1. and GNU Make 4.3 and
  2. gnuplot 5.2 (patchlevel 8) {see note added at end of post}

Here is the line in Plot.gp that fails:

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

if I replace $1 with $$1, the code works just as it would when invoked manually from the command shell.

I have worked around this by adding a rule that uses sed to substitute $$ for $, emitting a "scratch.gp" thus:

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

I've found the workaround to be robust in 5 other related scripts but it should not be doing this.

I speculate it is a bug in gnuplot (which is fairly new) under cygwin or some element of the Windows cmd shell -- but I don't know. The thing I'm experiencing should be impossible. It's quite important that I find a solution.

Thank you all.

NB: I discovered that when I call gnuplot from my shell terminal window thus:

gnuplot --version

the following is returned:

gnuplot 5.2 patchlevel 8

however when create a makefile to issue the same command in a recipe:

all:
     gnuplot --version

the command

make all

returns

gnuplot --version
gnuplot 5.4 patchlevel 0

In summary, somehow gnu make calls gnuplot 5.4 patchlevel 0 whereas manually issuing the same command in the shell terminal calls gnuplot 5.2 patchlevel 8. Why would that be the case?

I have further observed that gnuplot 5.4 patchlevel 0 contains version 4 backward compatibility features (which may include interpretation of $n environment variables.


Solution

  • All elements of my problem result from:

    1. bug in gnuplot 5.4.0
    2. make invokes /bin/sh (linux bash) instead of the windows shell.

    I submitted a bug report on gnuplot 5.4.0 in cygwin distribution to the gnuplot development group (https://sourceforge.net/p/gnuplot/bugs/2368/). The developer says it will be fixed in 5.4.1.

    The bug results from deprecated $0, $1, $2 etc symbols being erroneously enabled and assigned to gnuplot (5.4.0) to command line arguments.

    The bugged Gnuplot 5.4.0 is “gnuplot-base.exe” and the “obsolete” gnuplot 5.2.8 appears in the cygwin distribution as “gnuplot.exe”.

    I observe command “gnuplot”:

    1. from a windows cmd shell runs “gnuplot.exe” (5.2.8).
    2. whereas from /bin/sh links to gnuplot point to “gnuplot-base.exe”(5.4.0).

    The “make” utility submits rules through /bin/sh explaining why gnuplot fails in “make” but not from the command shell.

    I’m working around by calling “gnuplot.exe” instead of “gnuplot” in "make" rules. “gnuplot.exe is the obsolete version 5.2.8.

    Thank you. I love you all.