PMAKE 21 Jul 84 page 1 Copyright 1984 Michael M Rubenstein Permission is granted for noncommercial distribution of this program and documentation. Credits. PMAKE is a much simplified version of the Unix make program. PMAKE is derived from a version of make for the IBM PC written by John M Sellens. Changes in version 2.0. The major change is that pmake now supports named variable substitution. The old $1, $2, ... syntax is no longer supported. Unfortunately, this means version 1 makefiles will require modification before use with version 2. Description. It is generally accepted that moderate to large sized programs are best written as a collection of relatively small modules. It is often most convenient to keep these modules in separate files. This, however, quickly leads to difficulties in keeping track of which files must be compiled or assembled. The problem grows even worse when one is working on a system of programs which share some modules. How often does one change something and not know offhand just what files have to be compiled and linked? Happens to me all the time. PMAKE partially solves these problems. Details will be presented later, but an intuitive description of PMAKE seems appropriate here. Throughout the following, the term "file name" includes the possible specification of drive and user number in the form [][][:] (the ":" is required and only permitted if at least one of or is specified. Examples b3:file file on drive b, user 3 3:file file on current drive, user 3 b:file file on drive b, current user file file on current drive and user One prepares a file (the MAKEFILE) showing for each file in the PMAKE 21 Jul 84 page 2 system which other files it depends on (i.e. which other file will, when changed, require a change to this file) and the method of changing (or recreating). Consider, for example, PMAKE itself. It was written as four files, PMAKE.C, GETMEM.C, and GETMOD.C. Two of these, PMAKE.C and GETMOD.C include a header file, PMAKE.H. Let's look at the dependencies. Our objective is to create PMAKE.COM. PMAKE.COM depends on the relocatables PMAKE.REL GETMEM.REL GETMOD.REL generated by the C compiler (That's on my system. Your C compiler might generate a different file type). In turn PMAKE.REL depends on PMAKE.C and PMAKE.H GETMEM.REL depends on GETMEM.C GETMOD.REL depends on GETMOD.C and PMAKE.H One also tells PMAKE, in the MAKEFILE, how these files are to be (in this case) created when there is a change to a file on which it depends. To Make Command(s) ---------- --------------------------------------------- PMAKE.REL cc pmake GETMEM.REL cc getmem GETMOD.REL cc getmod PMAKE.COM l80 pmake/n,pmake,getmem,getmod,strmake/e Suppose a change is made to PMAKE.H. PMAKE will then compile PMAKE.C and GETMOD.C (GETMEM is not affected by this change) and link PMAKE.COM. As will be seen in the next section, there are several other features, but they are simply modifications to the above to ease use or to take into account some characteristics of CP/M. Note that the concept of dependence is not quite what most people think "natural". In the above, PMAKE.C, which includes PMAKE.H, does not depend on PMAKE.H (i.e. if you change PMAKE.H, no changes are needed to PMAKE.C). PMAKE.REL does depend on PMAKE.H since a change to PMAKE.H requires changing PMAKE.REL. The MAKEFILE. PMAKE 21 Jul 84 page 3 The MAKEFILE contains the information PMAKE needs to bring a system up to date. It may contain 5 types of lines 1. Blank lines. 2. Comment lines, beginning with ";". 3. Variable definition lines, beginning with "%". 4. Howto lines, beginning with tab. 5. Dependency lines, beginning with any other character. All lines must be 128 or fewer characters. Blank and comment lines are simply ignored by PMAKE. As will be seen, howto lines may contain references to variables supplied when PMAKE is invoked. Variable definition lines may included in the MAKEFILE to specify default values for the variables. A varibale definition line consists of a "%" in the first position, followed by an assignment to a variable, e.g. %debug=-vdebug or a "%" simply followed by a name, e.g. %debug The latter is interpreted as being equivalent to %debug=debug Variable names consist of up to 8 characters, each of which is a letter, digit, or one of ".", "-", "_". Variables may be used in any type of line and may be nested, but it is the users responsibility to insure that recursion does not take place. To use a variable, simply put it's name between percent signs, e.g. %debug%. The final "%" is not needed if the character after the variable is not one of those which may appear in a variable (or "%"). To put a "%" in a line, just use "%%". As we will see, variables may also be defined in the command line. They may not be redefined. Once a variable is defined, any attempt at redefinition is silently ignored. Thus, definitions in the makefile may be considered defaults to be used if no definition of the variable is given on the command line. Howto lines are simply CP/M commands. They are used to generate a submit file which will bring the desired files up to date. Finally, dependency lines contain a file name followed by a white space (space or tab) separated list of files on which it depends. Dependency lines are always converted to upper case by PMAKE. Each dependency line is followed by zero or more (we'll see why you might want zero shortly) howto lines. If PMAKE determines that the file must be brought up to date, the howto lines are written to the output submit file, making any needed parameter substitutions. PMAKE 21 Jul 84 page 4 There should be no more than one dependency line for any file. If there is more than one, all but the first will be ignored. The order of the dependency lines is not otherwise significant. Let's look at a sample MAKEFILE. ; sample MAKEFILE for PMAKE pmake.rel pmake.c pmake.h cc pmake %debug% getmod.rel getmod.c pmake.h cc getmod %debug% getmem.rel getmem.c cc getmem pmake.com pmake.rel getmod.rel getmem.rel l80 pmake/n/y,pmake,getmod,getmem/e When invoking PMAKE, one tells it the file(s) it is to bring up to date. The command pmake pmake.com will bring the file pmake.com (and any files it depends on) up to date. Using this MAKEFILE, let's say that PMAKE determines that getmod.c has been modified. It will generate the commands cc getmod -QDEBUG l80 pmake/n/y,pmake,getmod,getmem,strmake/e (assuming no parameter has been specified when PMAKE is invoked.) How does PMAKE now a file has been changed? On Unix, make checks the date last modified of all files. This isn't possible in CP/M 2.2. Therefore, a file attribute is used. As distributed, the F1 attribute is set whenever PMAKE brings a file up to date and, presumably, is reset when the file is updated. All of the editors I use will do this. If the F1 attribute is unsuitable, PMAKE may be changed (see Installation section) to use any of the file attributes. PMAKE examines each file and places it into one of 4 categories: 1. File does not exist. 2. File has the attribute set (unchanged file). 3. File does not have the attribute set (changed file). 4. File has been brought up to date in this run. A file is brought up to date under any of the following PMAKE 21 Jul 84 page 5 circumstances: 1. The file does not exist and there is a dependency line for the file. 2. There is a dependency line for the file with no dependencies. 3. Any file on which it depends has been changed or brought up to date in the current run. All files are marked as unchanged. It is an error for a file to depend on another which does not exist and for which there is no dependency line. It must be understood that only files which PMAKE sees are candidates for all this. The MAKEFILE might (mine, in fact does) contain other dependencies. For example, my MAKEFILE for PMAKE contains pset.rel pset.c cc pset pset.com pset.rel l80 pset/n/y,pset/e If PMAKE is told to make pmake.com, it will never look at these files and the condition of, say, pset.c is immaterial. Now, suppose one wants to bring several programs up to date. One could simply tell PMAKE to bring them all up to date in the command line with something like pmake pmake.com pset.com This could quickly get out of hand if there are several programs in the system. The solution is to use a phony file and include a line like Note that this example begins with a ".". This is not really necessary, but will tell PMAKE that the file is phony and will prevent checking it's status -- it will immediately be treated as a file which does not exist. Now with the command pmake .programs PMAKE will bring .programs up to date. This is, of course, not very meaningful, but in order to do it PMAKE will first have to bring pmake.com and pset.com up to date, which is desired. To further simplify use of PMAKE, if no file is requested in the command, PMAKE will bring the phony file ".do" up to date. One would normally specify PMAKE 21 Jul 84 page 6 in the above case or if only pmake.com were in the MAKEFILE allowing the simplest (and most common) form of the pmake command pmake Phony files have some other uses. In some cases there will be more dependencies for a file than can be put on one line. It's not necessary here, but the dependency for pmake.com could have been written pmake.com .pmake1 .pmake2 l80 pmake/n/y,pmake,getmod,getmem,strmake/e Finally, there are two special phony files, .init and .fin, used for initialization and completion. If any howto lines are output, the generated submit file will contain the howto lines for .init at the beginning and those for .fin at the end. These can be used to set up any environment needed before compiling and to restore the environment or to delete temporary files after compiling. Running PMAKE. The most common form of the PMAKE command is simply pmake This will read the file makefile.dat and bring the phony file .do up to date, placing the required commands in the file makef000.sub. A list of files which must be marked as up to date is placed in makefile.set. The command pset makefile.set will now mark these files as up to date. In some cases, it may be necessary to specify some options to PMAKE. Options are specified with a preceding "-". Most options require a parameter, which may be separated from the option by spaces. Possible options are -f specifies a MAKEFILE. If omitted, makefile.dat is used. PMAKE 21 Jul 84 page 7 -i allows continuation on certain errors. -n maximum size of a submit file. This is described more fully below. -v specifies a variable definition, May occur more than once. The definition is in the same form as in the file, but without the leading "%" (e.g. -vdebug=-qdebug). If the definition contains spaces, it must be enclosed in quotes or appostrophes. In addition to options, the PMAKE command may contain names of files to be brought up to date. If none is specified, the (phony) file .do will be brought up to date. The -n option requires more explanation. Normally CP/M imposes a limit of 128 lines on a submit file. This may not be enough. PMAKE will, if a submit file gets too large, generate a SUBMIT command for a new file and start placing commands in this new file. The files generated are makef000.sub, makef001.sub, ... Since the howto lines may contain submits (if one uses a SUBMIT processor such as SUB2 or SUPERSUB which allows nesting), PMAKE must know how many lines it can put into a the submit file. As distributed, the default is 96, allowing reasonable nesting. This may be changed with the -n option. If you are using a memory resident SUBMIT processor, such as EX or ZEX which do not allow nesting, specify "-n 0" to allow any number of lines. If an error is encountered or if everything is up to date and does not require marking, the file $$$.sub will be deleted. This makes it very easy to embed PMAKE in a submit file which then submits the generated file and executes PSET. Installation and Field Modification. A few locations in pmake.com may have to be changed with DDT: 0109H The file attribute bit which is to be used to indicate changed files. 0=F1, 1=F2, ..., 7=F8, 8=T1, 9=T2, 10=T3. Distributed as 0. The byte at 0103H in PSET.COM must be changed to the same value. 010BH-010CH The maximum number of lines to be put into a SUBMIT file (actually, one more line may be put into the SUBMIT file. If your SUBMIT processor does not allow nesting, this should be changed to 0FFFFH. Distributed as 96 (60H). 010DH-0115H The name of your SUBMIT processor, terminated PMAKE 21 Jul 84 page 8 by a zero byte. Distributed as "SUB". Modification and Enhancement. Source code is provided for use with the Software Toolworks C80 compiler. However, the program was compiled with a private, proprietary run time system so a fair amount of work will be required to compile on your system. Major considerations are 1. The file handling routines process the drive/user specification. If your's does not, you will have to either do without it or make modifications. 2. The function "error" displays a message, preceded by the program name. 3. The function "error" and the function "exit" (if called with a nonzero argument) delete a:$$$.sub. This is used in the error handling. 4. The file handling routines create a new file with a temporary name and rename it when closed. This is very different from most systems. 5. The setflg function sets various file modes. In this program, the only one of interest is "d", which deletes the file when it is closed. This list is not exhaustive. Beware.