开发者

make: invoke command for multiple targets of multiple files?

I looking to optimize an existing Makefile. It's used to create multiple plots (using Octave) for every logfile in a given directory using an scriptfile for every plot which takes a logfilename as an argument. In the Moment, I use one single rule for every kind of plot available, with a handwritten call to Octave, giving the specific scriptfile/logfile as an argument.

It would be nice, if every plot has "his" octave-script as a dependency (plus the logfile, of course), so only one plot is regenerated if his script is changed.

Since I don't want to type that much, I wonder how I can simplifiy this by using only one general rule to build "a" plot?

To make it clearer:

  • Logfile: "$(LOGNAME).log"
  • Scriptfile: "plot$(PLOTNAME).m" creates "$(LOGNAME)_$(PLOTNAME).png"
开发者_Go百科

The first thing I had in mind:

%1_%2.png: %1.log
    $(OCTAVE) --eval "plot$<2('$<1')"

But this seems not to be allowed. Could someone give me a hint?


It's pretty crazy that make doesn't support this directly, I need it all the time.

The technique I use at the moment (with GNU make) (building on Didier Trosset's example):

define OCT_template

all: %_$(1).png

%_$(1).png: %.log
    $$(OCTAVE) --eval "plot$(1)('$$*')"

endef

PLOT_NAMES = plot1 plot2 plot3

$(foreach p, $(PLOT_NAMES), \
  $(eval $(call OCT_template,$(p))) \
)

This is in the GNU make documentation.


Pattern rules can use only 1 pattern (i.e. you cannot have %1 and %2, just %).

Therefore, depending on the number of PLOTNAME and LOGNAME you have, choose the smallest and write as many pattern rules as needed.

%_plot1.png: %.log
        $(OCTAVE) --eval "plot1('$*')"

If you do not want to write as many rules as you have different plots (or logs), you can use a double Makefile mechanism. In the sub-Makefile, use the above command, but use a parameter for the plot name. In a master Makefile, call it with the various values of the plotname you want.

Makefile.sub:

%_$(PLOTNAME).png: %.log
        $(OCTAVE) --eval "plot$(PLOTNAME)('$*')"

Makefile:

all:
        $(MAKE) PLOTNAME=plot1 -f Makefile.sub
        $(MAKE) PLOTNAME=plot2 -f Makefile.sub
        $(MAKE) PLOTNAME=plot3 -f Makefile.sub

It saves writing the rule many times (and saves updating it as many times when needed), but then requires special handling for other targets than all, such as clean.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜