📄 tutorial.ms
字号:
.DEThe creation script attached to the target is used to transform a file withthe first suffix (in this case,.CW .c )into a file with the second suffix (here,.CW .o ).In addition, the target inherits whatever attributes have been appliedto the transformation rule.The simple rule given above says that to transform a C source fileinto an object file, you compile it using.CW ccwith the.CW \-cflag.This rule is taken straight from the system makefile. Manytransformation rules (and suffixes) are defined there, and I refer youto it for more examples (type.CW "pmake -h" '' ``to find out where it is)..LPThere are several things to note about the transformation rule givenabove:.RS.IP 1)The.CW .IMPSRC variable..Ix 0 def variable local .IMPSRC.Ix 0 def .IMPSRCThis variable is set to the ``implied source'' (the file from whichthe target is being created; the one with the first suffix), which, in thiscase, is the .c file..IP 2)The.CW CFLAGSvariable. Almost all of the transformation rules in the systemmakefile are set up using variables that you can alter in yourmakefile to tailor the rule to your needs. In this case, if you wantall your C files to be compiled with the.B \-gflag, to provide information for.CW dbx ,you would set the.CW CFLAGSvariable to contain.CW -g.CW "CFLAGS = -g" '') (``and PMake would take care of the rest..RE.LPTo give you a quick example, the makefile in 2.3.4 .Rm 3 2.3.4could be changed to this:.DSOBJS = a.o b.o c.oprogram : $(OBJS) $(CC) -o $(.TARGET) $(.ALLSRC)$(OBJS) : defs.h.DEThe transformation rule I gave above takes the place of the 6 lines\**.FSThis is also somewhat cleaner, I think, than the dynamic sourcesolution presented in 2.6.FE.Rm 4 2.6.DSa.o : a.c cc -c a.cb.o : b.c cc -c b.cc.o : c.c cc -c c.c.DE.LPNow you may be wondering about the dependency between the.CW .oand.CW .cfiles \*- it's not mentioned anywhere in the new makefile. This isbecause it isn't needed: one of the effects of applying atransformation rule is the target comes to depend on the impliedsource. That's why it's called the implied.I source ..LPFor a more detailed example. Say you have a makefile like this:.DSa.out : a.o b.o $(CC) $(.ALLSRC).DEand a directory set up like this:.DStotal 4-rw-rw-r-- 1 deboor 34 Sep 7 00:43 Makefile-rw-rw-r-- 1 deboor 119 Oct 3 19:39 a.c-rw-rw-r-- 1 deboor 201 Sep 7 00:43 a.o-rw-rw-r-- 1 deboor 69 Sep 7 00:43 b.c.DEWhile just typing.CW pmake '' ``will do the right thing, it's much more informative to type.CW "pmake -d s" ''. ``This will show you what PMake is up to as it processes the files. Inthis case, PMake prints the following:.DSSuff_FindDeps (a.out) using existing source a.o applying .o -> .out to "a.o"Suff_FindDeps (a.o) trying a.c...got it applying .c -> .o to "a.c"Suff_FindDeps (b.o) trying b.c...got it applying .c -> .o to "b.c"Suff_FindDeps (a.c) trying a.y...not there trying a.l...not there trying a.c,v...not there trying a.y,v...not there trying a.l,v...not thereSuff_FindDeps (b.c) trying b.y...not there trying b.l...not there trying b.c,v...not there trying b.y,v...not there trying b.l,v...not there--- a.o ---cc -c a.c--- b.o ---cc -c b.c--- a.out ---cc a.o b.o.DE.LP.CW Suff_FindDepsis the name of a function in PMake that is called to check for impliedsources for a target using transformation rules.The transformations it tries are, naturallyenough, limited to the ones that have been defined (a transformationmay be defined multiple times, by the way, but only the most recentone will be used). You will notice, however, that there is a definiteorder to the suffixes that are tried. This order is set by therelative positions of the suffixes on the.CW .SUFFIXESline \*- the earlier a suffix appears, the earlier it is checked asthe source of a transformation. Once a suffix has been defined, theonly way to change its position in the pecking order is to remove allthe suffixes (by having a.CW .SUFFIXESdependency line with no sources) and redefine them in the order youwant. (Previously-defined transformation rules will be automaticallyredefined as the suffixes they involve are re-entered.).LPAnother way to affect the search order is to make the dependencyexplicit. In the above example,.CW a.outdepends on.CW a.oand.CW b.o .Since a transformation exists from.CW .oto.CW .out ,PMake uses that, as indicated by the.CW "using existing source a.o" '' ``message..LPThe search for a transformation starts from the suffix of the targetand continues through all the defined transformations, in the orderdictated by the suffix ranking, until an existing file with the samebase (the target name minus the suffix and any leading directories) isfound. At that point, one or more transformation rules will have beenfound to change the one existing file into the target..LPFor example, ignoring what's in the system makefile for now, say youhave a makefile like this:.DS\&.SUFFIXES : .out .o .c .y .l\&.l.c : lex $(.IMPSRC) mv lex.yy.c $(.TARGET)\&.y.c : yacc $(.IMPSRC) mv y.tab.c $(.TARGET)\&.c.o : cc -c $(.IMPSRC)\&.o.out : cc -o $(.TARGET) $(.IMPSRC).DEand the single file.CW jive.l .If you were to type.CW "pmake -rd ms jive.out" ,'' ``you would get the following output for.CW jive.out :.DSSuff_FindDeps (jive.out) trying jive.o...not there trying jive.c...not there trying jive.y...not there trying jive.l...got it applying .l -> .c to "jive.l" applying .c -> .o to "jive.c" applying .o -> .out to "jive.o".DEand this is why: PMake starts with the target.CW jive.out ,figures out its suffix.CW .out ) (and looks for things it can transform to a.CW .outfile. In this case, it only finds.CW .o ,so it looks for the file.CW jive.o .It fails to find it, so it looks for transformations into a.CW .ofile. Again it has only one choice:.CW .c .So it looks for.CW jive.cand, as you know, fails to find it. At this point it has two choices:it can create the.CW .cfile from either a.CW .yfile or a.CW .lfile. Since.CW .ycame first on the.CW .SUFFIXESline, it checks for.CW jive.yfirst, but can't find it, so it looks for.CW jive.land, lo and behold, there it is.At this point, it has defined a transformation path as follows:.CW .l\(->.CW .c\(->.CW .o\(->.CW .outand applies the transformation rules accordingly. For completeness,and to give you a better idea of what PMake actually did with thisthree-step transformation, this is what PMake printed for the rest ofthe process:.DSSuff_FindDeps (jive.o) using existing source jive.c applying .c -> .o to "jive.c"Suff_FindDeps (jive.c) using existing source jive.l applying .l -> .c to "jive.l"Suff_FindDeps (jive.l)Examining jive.l...modified 17:16:01 Oct 4, 1987...up-to-dateExamining jive.c...non-existent...out-of-date--- jive.c ---lex jive.l\&.\|.\|. meaningless lex output deleted .\|.\|.mv lex.yy.c jive.cExamining jive.o...non-existent...out-of-date--- jive.o ---cc -c jive.cExamining jive.out...non-existent...out-of-date--- jive.out ---cc -o jive.out jive.o.DE.LPOne final question remains: what does PMake do with targets that haveno known suffix? PMake simply pretends it actually has a known suffixand searches for transformations accordingly.The suffix it chooses is the source for the.CW .NULL.Ix 0 ref .NULLtarget mentioned later. In the system makefile, .CW .outis chosen as the ``null suffix''.Ix 0 def suffix null.Ix 0 def "null suffix"because most people use PMake to create programs. You are, however,free and welcome to change it to a suffix of your own choosing.The null suffix is ignored, however, when PMake is in compatibilitymode (see chapter 4)..xH 2 Including Other Makefiles.Ix 0 def makefile inclusion.Rd 2.LPJust as for programs, it is often useful to extract certain parts of amakefile into another file and just include it in other makefilessomehow. Many compilers allow you say something like.DS#include "defs.h".DEto include the contents of.CW defs.hin the source file. PMake allows you to do the same thing formakefiles, with the added ability to use variables in the filenames.An include directive in a makefile looks either like this:.DS#include <file>.DEor this.DS#include "file".DEThe difference between the two is where PMake searches for the file:the first way, PMake will look forthe file only in the system makefile directory (to find out what thatdirectory is, give PMake the.B \-hflag)..Ix 0 ref flags -hFor files in double-quotes, the search is more complex:.RS.IP 1)The directory of the makefile that's including the file..IP 2)The current directory (the one in which you invoked PMake)..IP 3)The directories given by you using.B \-Iflags, in the order in which you gave them..IP 4)Directories given by.CW .PATHdependency lines (see chapter 4)..IP 5)The system makefile directory..RE.LPin that order..LPYou are free to use PMake variables in the filename\*-PMake willexpand them before searching for the file. You must specify thesearching method with either angle brackets or double-quotes.I outsideof a variable expansion. I.e. the following.DSSYSTEM = <command.mk>#include $(SYSTEM).DEwon't work..xH 2 Saving Commands.LP.Ix 0 def ...There may come a time when you will want to save certain commands tobe executed when everything else is done. For instance: you'remaking several different libraries at one time and you want to create themembers in parallel. Problem is,.CW ranlibis another one of those programs that can't be run more than once inthe same directory at the same time (each one creates a file called.CW __.SYMDEFinto which it stuffs information for the linker to use. Two of themrunning at once will overwrite each other's file and the result willbe garbage for both parties). You might want a way to save the ranlibcommands til the end so they can be run one after the other, thuskeeping them from trashing each other's file. PMake allows you to dothis by inserting an ellipsis (``.\|.\|.'') as a command betweencommands to be run at once and those to be run later..LPSo for the.CW ranlibcase above, you might do this:.Rd 5.DSlib1.a : $(LIB1OBJS) rm -f $(.TARGET) ar cr $(.TARGET) $(.ALLSRC) ... ranlib $(.TARGET)lib2.a : $(LIB2OBJS) rm -f $(.TARGET) ar cr $(.TARGET) $(.ALLSRC) ... ranlib $(.TARGET).DE.Ix 0 ref variable local .TARGET.Ix 0 ref variable local .ALLSRCThis would save both.DSranlib $(.TARGET).DEcommands until the end, when they would run one after the other(using the correct value for the.CW .TARGETvariable, of course)..LPCommands saved in this manner are only executed if PMake manages tore-create everything without an error..xH 2 Target Attributes.LPPMake allows you to give attributes to targets by means of specialsources. Like
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -