开发者

How to replace text in a makefile in a way that works with make AND dmake?

I've got this makefile:

ALL = ../lib/Mo.pm \
      ../lib/Mo/builder.pm \
      ../lib/Mo/default.pm \
      ../lib/Mo/has.pm \

all: $(ALL)

$(ALL): Mo.pm compress.pl Makefile
    perl compress.pl $(@:../lib/%=%) > $@

What it's meant to do is something like this:

$ make -n
perl compress.pl Mo.pm > ../lib/Mo.pm
perl compress.pl Mo/builder.pm > ../lib/Mo/builder.pm
perl compress.pl Mo/default.pm > ../lib/Mo/default.pm
perl compress.pl Mo/has.pm > ../l开发者_运维问答ib/Mo/has.pm

However with dmake on Windows this happens:

d:\mo-pm\src>dmake -n
perl compress.pl ..\lib\Mo.pm > ..\lib\Mo.pm
perl compress.pl ..\lib\Mo\builder.pm > ..\lib\Mo\builder.pm
perl compress.pl ..\lib\Mo\default.pm > ..\lib\Mo\default.pm
perl compress.pl ..\lib\Mo\has.pm > ..\lib\Mo\has.pm

I've been trying out various combinations of s/// and subst to make it work in dmake, and found out that it wants the path to have \s, which means a double substitution against both variants of the path (../lib/ and ..\lib) could work, but i can't figure out how to make it work for both make variants.

Any ideas or other ways to do this?


It's not only that the dir separator chars are different for both versions, moreover the dmake syntax seems to be deliberately designed to be incompatible with GNU make. The only part of the syntax that is actually compatible is pattern substitution, so this is the way to go:

 all: $(ALL)

 $(ALL) : Makefile compress.pl
 ../lib/%.pm : %.pm 
         perl compress.pl $< > $@

dmake actually substitutes the / for directory separator chars for you here. I've tested this Makefile with an echo instead, and it writes to the right directory.

Explanation: The pattern rules define rules for a particular file to be re-made when it matches a regular expression (the ../lib/%.pm part) and a prerequisite of a similar name is found (%.pm). The % in the prerequisite is replaced by the matching part of the % in the target. The extra rule with Makefile and compress.pl is needed because dmake doesn't like extra prerequisites in a pattern rule. As usual, $< and $@ are make's special variables for source and target file.

So, the core difference is that your original rule said "the files named in this list can be made with the following rule), while the pattern rule says "any file looking like ../lib/%.pm can be made from a matching file in the current directory" and then gives a list of pm files to make.

Pattern rules are actually quite powerful, useful to know. Unfortunately, some makes don't know them, only the older suffix rules.

Further details of what's going on can be obtained by running

make -rdn
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜