J'ai une cible dans un Makefile gnu-make qui ressemble à ceci :

Fragment de makefile :

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

L'utilitaire gnuplot interprète $1 comme un champ spécial dans le script Plot.gp et lorsqu'il est invoqué directement depuis le terminal shell, le script s'exécute correctement. Lorsqu'il est exécuté en règle générale à partir du fragment Makefile indiqué ci-dessus, il échoue dans gnuplot-.

J'ai découvert que je peux substituer un $ doublé dans le script Plot.gp. C'est-à-dire, remplacez $1 par $$1 dans Plot.gp et la règle make fonctionne comme elle le fait sans substitution du terminal shell. Il semble que gnuplot voit les arguments de commande $0, $1, $2 etc passés de make. Je ne veux pas de ça. Je veux que gnuplot interprète $1 comme sa propre variable de champ.

Je peux pirater un script sed dans le make avant d'appeler gnuplot pour substituer $ à $$ dans Plot.gp mais je préfère une solution qui ne modifie pas le code d'origine car le hack augmente la complexité du code et le rend plus difficile pour les autres comprendre le makefile. En résumé, je veux que gnu-make appelle la règle sans substituer des variables d'arguments de commande $1 ou toute autre variable occulte.

Je travaille sur une plate-forme Windows 10 avec cygwin64

  1. et GNU Make 4.3 et
  2. gnuplot 5.2 (patchlevel 8) {voir note ajoutée à la fin du message}

Voici la ligne dans Plot.gp qui échoue :

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

Si je remplace $1 par $$1, le code fonctionne exactement comme s'il était invoqué manuellement à partir du shell de commande.

J'ai contourné cela en ajoutant une règle qui utilise sed pour substituer $$ à $, en émettant un "scratch.gp" ainsi :

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

J'ai trouvé que la solution de contournement était robuste dans 5 autres scripts connexes, mais cela ne devrait pas être le cas.

Je suppose qu'il s'agit d'un bogue dans gnuplot (qui est assez nouveau) sous cygwin ou un élément du shell cmd Windows - mais je ne sais pas. La chose que je vis devrait être impossible. Il est assez important que je trouve une solution.

Merci à tous.

NB : j'ai découvert que lorsque j'appelais gnuplot depuis ma fenêtre de terminal shell ainsi :

gnuplot --version

Ce qui suit est renvoyé :

gnuplot 5.2 patchlevel 8

Cependant, lors de la création d'un makefile pour émettre la même commande dans une recette :

all:
     gnuplot --version

La commande

make all

Retour

gnuplot --version
gnuplot 5.4 patchlevel 0

En résumé, d'une manière ou d'une autre, gnu appelle gnuplot 5.4 patchlevel 0 alors que l'émission manuelle de la même commande dans le terminal shell appelle gnuplot 5.2 patchlevel 8. Pourquoi serait-ce le cas ?

J'ai en outre observé que gnuplot 5.4 patchlevel 0 contient des fonctionnalités de compatibilité descendante de la version 4 (qui peuvent inclure l'interprétation de $n variables d'environnement.

2
Burton 17 nov. 2020 à 20:58

1 réponse

Meilleure réponse

Tous les éléments de mon problème résultent de :

  1. bogue dans gnuplot 5.4.0
  2. make invoque /bin/sh (linux bash) au lieu du shell Windows.

J'ai soumis un rapport de bogue sur gnuplot 5.4.0 dans la distribution cygwin au groupe de développement gnuplot (https : //sourceforge.net/p/gnuplot/bugs/2368/). Le développeur dit que cela sera corrigé dans 5.4.1.

Le bogue résulte du fait que les symboles obsolètes $0, $1, $2, etc. sont activés par erreur et attribués à gnuplot (5.4.0) aux arguments de la ligne de commande.

Le bug de Gnuplot 5.4.0 est "gnuplot-base.exe" et le "obsolète" gnuplot 5.2.8 apparaît dans la distribution cygwin sous le nom de "gnuplot.exe".

J'observe la commande "gnuplot":

  1. à partir d'un shell Windows cmd, exécutez "gnuplot.exe" (5.2.8).
  2. alors que depuis /bin/sh, les liens vers gnuplot pointent vers « gnuplot-base.exe » (5.4.0).

L'utilitaire "make" soumet des règles via /bin/sh expliquant pourquoi gnuplot échoue dans "make" mais pas à partir du shell de commande.

Je travaille en appelant "gnuplot.exe" au lieu de "gnuplot" dans les règles "make". « gnuplot.exe est la version obsolète 5.2.8.

Merci. Je vous aime tous.

3
Burton 22 nov. 2020 à 16:40