Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile: reuse value of % of a pattern rule inside the recipe

In a Makefile I have:

images/schematic.pdf: images/schematic.svg

  inkscape -D -z --file=$^ --export-pdf=$@ --export-latex

  sed -i "s:schematic:images/schematic:g" $@_tex

What this rule does is:

  • Use inkscape to convert to a latex-ready .pdf PDF file + its corresponding .pdf_tex text file (see this answer: https://tex.stackexchange.com/a/2107/104581)
  • Modify the mentioned .pdf_tex file so that it will not break latex compiling from a "higher" directory (namely . when the .pdf_tex file is in ./images)

My problem:

I have many rules in this form i. e. where only schematic is changed. I would like to use a pattern-rule that replaces schematic by %. And to use % in the recipe (in the sed command).

However the rule:

images/%.pdf: images/%.svg

  inkscape -D -z --file=$^ --export-pdf=$@ --export-latex

  sed -i "s:%:images/%:g" $@_tex

does not works: % is interpreted literally in the recipe.

I also tried to replace % in the recipe by $% but this variable seems to be empty.

Unsatisfactory solution:

Add a line in the recipe to create a (make) variable that will hold the result of notdir(removeprefix($<)) (using this question or a call to bash because there is no removeprefix in GNU Make).

like image 313
Gabriel Devillers Avatar asked Sep 20 '16 22:09

Gabriel Devillers


1 Answers

You want $*. From https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html :

$*: The stem with which an implicit rule matches (see How Patterns Match). If the target is dir/a.foo.b and the target pattern is a.%.b then the stem is dir/foo. The stem is useful for constructing names of related files.

In a static pattern rule, the stem is part of the file name that matched the ‘%’ in the target pattern.

In an explicit rule, there is no stem; so ‘$*’ cannot be determined in that way. Instead, if the target name ends with a recognized suffix (see Old-Fashioned Suffix Rules), ‘$*’ is set to the target name minus the suffix. For example, if the target name is ‘foo.c’, then ‘$*’ is set to ‘foo’, since ‘.c’ is a suffix. GNU make does this bizarre thing only for compatibility with other implementations of make. You should generally avoid using ‘$*’ except in implicit rules or static pattern rules.

If the target name in an explicit rule does not end with a recognized suffix, ‘$*’ is set to the empty string for that rule.

$% is an automatic variable, but it's for archive (.a library) members, and almost never useful.

like image 101
wnoise Avatar answered Oct 10 '22 13:10

wnoise