PBMake 2.16 for Clipper, Xbase++, C and ASM

PBMake Features:

Memory Usage
What is a section?
Directives used in PBMake
PBMake Conditionals ( #DEFINE #IFDEF #IFNDEF #ELSE #ENDIF #UNDEF )
Directive Case and Space Sensitivity
Directive Limitations
Commenting your Make Script
OBJDIR= Placing Objects in another directory
SRCDIR= Placing Source in another directory
File Validity Checking
INCLUDE= What about INCLUDE files?
LIB= What about LIB files?
SUCCESS=, FAILURE= and NONEED=
PRECOMPILECMD= and PRELINKCMD=
How do I use the 'Jump to Editor on Compile Failure' feature?
How to use the CLEANUP= directive.
What is the /ALL flag for?
What is the /LINK flag for?
What is the /P flag for?
My linker doesn't like the @ symbol!
How big can my make scripts get?


Memory Usage

Since PBMake uses your .MAK script to create a batch file that does the actual work, there is NO memory overhead during the compiling and linking process. Also, other MAKE processes stay resident and shell to DOS each time a source module is compiled, or a linker is run. This memory swapping adds a lot of time to the process, so if you currently use another MAKE engine and you use it in the simple form, you will see some speed savings by switching to PBMake.

What is a section?

Sections are provided in PBMake scripts so you can place many different sets of directives into a single script. PBMake can use up to 99 sections. This example has three sections: EXEFILE= LINKFILE= LINKER= COMPILER1= FLAG1= PROG1= SRCDIR1= OBJDIR1= COMPILER2= FLAG2= PROG2= SRCDIR2= OBJDIR2= COMPILER3= FLAG3= PROG3= SRCDIR3= OBJDIR3=

Directives used in PBMake

These directives are not case sensitive. EXEFILE= The target you are creating TARGET= (a synonym for EXEFILE=) + LIB= Libraries that the target depends on PRELINKCMD= Runs after compiler and before linker LINKFILE= The linker script for the EXEFILE LINKER= The linker you want to use LINKER_SEP= Optional link file prefix + INCLUDE= The include files you depend on + INCLUDE1= ... INCLUDE99= (can be different for each section) PRECOMPILECMD= Runs before the first compile COMPILER= Defaults to CLIPPER COMPILER1= .... COMPILER99= (can be different for each section) ONERROR= This sets up PBMake so that when ONERROR1= .... ONERROR99= an error is encountered in the compile process, it will jump to the editor of your choice. ERRFILE= Placing a file name here will override the default of ${pbm}.err ERRBAT= Placing a file name here will ERRBAT1= ... ERRBAT99= override the default of ${pbm}.bat + CLEANUP= Cleans up (deletes) temp files. NONEED= Runs if there was nothing to do SUCCESS= Runs if everything worked FAILURE= Runs if something failed SRCDIR= Where the source code resides SRCDIR1= .... SRCDIR99= (can be different for each section) OBJDIR= Where the object code will go OBJDIR1= .... OBJDIR99= (can be different for each section) SRCEXT= Defaults to .PRG for Clipper SRCEXT1= .... SRCEXT99= (can be different for each section) OBJEXT= Defaults to .OBJ for Clipper OBJEXT1= .... OBJEXT99= (can be different for each section) FLAG1= .... FLAG99= The compiler flags for each section + PROG1= .... PROG99= The source files to compile #DEFINE Conditional Script Commands #IFDEF #IFNDEF #ELSE #ENDIF #UNDEF + Denotes directives that can be used additively. This means that if you need more of each type of these directives than will conveniently fit on one line, you may add more and more of these until all files are listed. If you use any of the other directives more than once, PBMake will use the last one read in.

PBMake Conditionals ( #DEFINE #IFDEF #IFNDEF #ELSE #ENDIF #UNDEF )

PBMake allows for the following conditional directives from the command line, which can create conditional make scripts. #DEFINE #IFDEF #IFNDEF #ELSE #ENDIF #UNDEF These definitions can be nested up to 7 deep Definition parameters are defined by prefixing a /D For example, if you want to define DEMO to a PBMake script, you would pass /DDEMO as a parameter. Definitions are passed as parameters on the command line after the name of the make script, like: MAKE PBMAKE /DDEMO /DDEBUG or MAKE PBMAKE /DDEBUG Note! As of Version 2.00, these defines are passed on into the linker script. Actually, your .LNK script is processed into a temporary script which is then used to perform the link. With definitions like these, you can do the following: ****************************************************************************** * PBMake 2.16 for Clipper, Xbase++, C and ASM * * Copyright (C) 1998 Phil Barnett, All Rights Reserved Worldwide * * See PBMAKE.NG for help. * ****************************************************************************** LINKER=BLINKER PROG1=PBMAKE BUFFREAD #IFDEF DEMO EXEFILE=DEMO\PBMAKE.EXE LINKFILE=DEMO.LNK OBJDIR=DEMO\OBJ\ #IFNDEF DEBUG FLAG1= /M /N /W /Q /ES2 /DDEMO #ELSE FLAG1= /M /N /W /Q /ES2 /DDEMO /B #ENDIF SUCCESS=PKLITE DEMO\PBMAKE -E -A #ELSE EXEFILE=REG\PBMAKE.EXE LINKFILE=REG.LNK OBJDIR=REG\OBJ\ #IFDEF DEBUG FLAG1= /M /N /W /Q /ES2 /B #ELSE FLAG1= /M /N /W /Q /ES2 #ENDIF SUCCESS=PKLITE REG\PBMAKE -E -A #ENDIF NONEED=ECHO PKLite not Necessary

Directive Case and Space Sensitivity

Directives are not case sensitive. Spaces after the = sign are removed and do not effect the make engine. So: objdir= obj\ works the same as: OBJDIR=OBJ\ Please note! OBJDIR = OBJ\ ^^ ^^ ^^ will not work, as the space between OBJDIR and = will cause the PBMake to view the line as a comment. The = sign must follow the directive with no spaces between.

Directive Limitations

There are five directives that can be used on more than one line in any script. CLEANUP= INCLUDE= INCLUDE1= ... INCLUDE99= LIB= PROG1= ... PROG99= These lines are completely additive, and any of them can be used to add more and more directives to that category. Like: LIB= F:\FLEXFILE\LIB\FLEX52.LIB LIB= F:\COMIX\LIB\CMX52.LIB INCLUDE=C:\SOMEDIR\GLOBAL.CH INCLUDE=C:\ANOTHER\GLOBAL2.CH OBJDIR=OBJ\ FLAG1= /W /M /N /Q /ES2 PROG1=HELP DBF_OPEN PRINTER WHERPRNT P_PAYMNT J_BILL PROG1=ERROR52 INVCOST GOODNTX ADDQUEUE VENEDIT VENADD PROG1=EDTQUEUE FBROWSE DEPTADD PDOTADD ORDRFILL CLEAREM INCLUDE2=C:\MSC\INCLUDE\C_GLOBAL.H INCLUDE2=PUBLICS.H INCLUDE2=FLD_MAST.H CLEANUP=TEMP.TXT CLEANUP=*.$* CLEANUP=$*.* Up to 99 sections of directives can be used.

Commenting your Make Script

You may comment the MAKE script by simply typing in whatever you want on any line that does not start with a directive. Note! End of line comments are not allowed. In short, there are directive lines and ignored lines. Any line not starting with a directive will be ignored.

OBJDIR= Placing Objects in another directory

The OBJDIR= directive is optional. Use it if you want to place your objects in a different directory from where you run the make script. Note! When you use the OBJDIR= directive, your objects will not be built in the current directory. This means that your linker script will also need to refer to the actual location of the objects. You may also override the OBJDIR=, which is active across all sections with individual directives for each section. So, you can do this: OBJDIR=OBJ\ OBJDIR2=\OTHER\OBJ

SRCDIR= Placing Source in another directory

The SRCDIR= directive is optional. (formerly SOURCEDIR=) Use it if you do not keep your source code in the directory where you run the make script from. You may also override the SRCDIR=, which is active across all sections with individual directives for each section. So, you can do this: SRCDIR=SRC\ SRCDIR2=\OTHER\SRC

File Validity Checking

OBJDIR=, SRCDIR=, LIB= and INCLUDE= directives are checked for validity. In the case of the OBJDIR= and SRCDIR= directives, if an invalid path is used, the make script will halt with an appropriate error message. In the case of the INCLUDE= and LIB= directives, the existance of each file is validated. The make script will halt with an appropriate error message when it comes to an invalid one.

INCLUDE= What about INCLUDE files?

The INCLUDE= directive is optional and has the following properties 1. The time and date stamps of all files placed in the INCLUDE= directives will be compared to the time and date stamps of all of the objects. 2. Any object older than any file in the INCLUDE= directive will be recompiled. PBMake does not check to see if the source file contains an actual reference to the include file. The assumption is that ALL source depend on the INCLUDE= directives. Any file referenced in a INCLUDE= directive that does not exist as an actual file will stop the make process with an appropriate error. You can override the master INCLUDE= directive by using numbered versions for each section. For example, you can: INCLUDE= SOMETHIN.CH SRCEXT=.PRG INCLUDE3= mystuff.h SRCEXT3=.C

LIB= What about LIB files?

The LIB= directive is optional and has the following properties. 1. The time and date stamps of all files placed in the LIB= directives will be compared to the time and date stamp of the target file. 2. If the target is older than any file in the LIB= directive it (the target) will be relinked. Any file referenced in a LIB= directive that does not exist as an actual file will stop the make process with an appropriate error.

SUCCESS=, FAILURE= and NONEED=

With the SUCCESS= and FAILURE= directives, you can execute a DOS program based on whether the make process succeeded. Note! If it exists, and there is nothing to do, the NONEED= directive will execute. If you don't include the NONEED= directive, but you have included the SUCCESS= directive, the SUCCESS= directive will execute when there is nothing to do. Please see the companion commands, PRECOMPILECMD= and PRELINKCMD= If you need to run another batch file, remember to use the CALL batch file command, like: SUCCESS=CALL VERS_CTL.BAT FAILURE=CALL BADCOMP.BAT NONEED=ECHO Nothing Happened. Didn't use SUCCESS= or FAILURE=

PRECOMPILECMD= and PRELINKCMD=

The PRECOMPILECMD= and PRELINKCMD= directives are for performing actions just before the compile process starts, or just before the linking process starts. Please note the following behaviour! The PRECOMPILECMD= directive will NOT run if there is nothing to compile! The PRELINKCMD= directive will NOT run if there is nothing to link! You can use either of these commands to run any DOS program or batch file. If you need to run another batch file, remember to use the CALL batch file command, like: PRECOMPILECMD=CALL PRECOMP.BAT PRELINKCMD=DEL SOMEFILE.XXX

How do I use the 'Jump to Editor on Compile Failure' feature?

ONERROR= is the Compile Failure directive. It allows you to use PBMake in a way that when a compiler error is encountered, your editor will be invoked and you will be fast forwarded to the point in your source code where the error occured. A note about Clipper, here... Clipper does NOT normally create a DOS errorlevel on exit after failure. You must place the /ES2 flag in the flag directive to use this error trap feature. Here is an example for Clipper and Qedit: FLAG= /M /N /W /ES2 ( or whatever flags you use + /ES2 ) ONERROR= CLIPPER Q -N Here is an example for Clipper and MultiEdit: FLAG= /M /N /W /ES2 ( or whatever flags you use + /ES2 ) ONERROR= CLIPPER ME /L Here's how it works: PBMake tells DOS to redirect the text output from your compiler into a file. When PBMake encounters a DOS error in the make process, it jumps to the compiler error trap in MAKE.BAT file. The compiler error trap executes PBERRLIN.EXE and passes in a bunch of information from your .MAK file: <parm1> = The redirected output from the compiler. ( defaults to ${pbm}.err, override with ERRFILE= ) <parm2> = Batch file name to be created. ( defaults to ${pbm}.bat, override with ERRBAT= ) <parm3> = The Compiler that created the error. <parm4> = The DOS command that invokes your editor. <parm5> = The directive that causes your editor to jump to a line. When PBERRLIN.EXE executes it parses the <parm1> file looking for two pieces of information. It determines the source module that failed, and it determines the line number where the first error originated. ( Please note that you are only supplying the 3,4 and 5 <parms> in the ONERROR= line. ) After PBERRLIN.EXE has the information it needs, it creates the file named in <parm2>. MAKE.BAT then executes the <parm2> file that was just created. The <parm2> file contains the editor directive to edit the failed compile source code and the directive to jump to the correct line number. It also loads the error file as the second file, so if there is more than one error, you can swap windows back and forth to fix all the errors in one shot. Fortunately, this takes longer to read about than to execute. It's really quite fast and a very time saving feature. The files in <parm1> and <parm2> are automatically added to the CLEANUP= directive.

How to use the CLEANUP= directive.

The CLEANUP= directive will clean up after the temp files that are created during the compile and link process. Most notably, the two junk files from the ERRFILE= and ERRBAT= directives (which always have defaults) are cleaned up after (this happens automatically). Of course, you can use this to keep any filespec deleted out of your working directory. For Example: CLEANUP= *.TMP If you wish to suppress the automatic deletion of the ERRFILE= and ERRBAT= files, use the following example: CLEANUP= NONE

What is the /ALL flag for?

The /ALL flag on the DOS command line will force all objects to be rebuilt, regardless of their time and date stamps. It has the same effect as deleting all of your objects, without going through the actual process of deleting them. Instead, PBMake thinks that all of the time and date comparisons failed, ie: PBMake thinks that all of the source code is newer than all of the objects. MAKE MYPROG /ALL PBMake decides when the linker needs to run based on a few criteria. 1. The output file is missing. 2. The link script is newer than the output. 3. An object was rebuilt. (like in the /ALL directive) 4. An object was newer then the output. Use the /ALL command just before you are ready to distribute your application, to make sure that everything has been freshly compiled. Another time to use the /ALL command is when you are using the debugger. When you add the /B switch to the Clipper Compiler, you will want to rebuild all of the objects, so the debugging information is included in the objects. Then, when you are done debugging, you will remove the /B flag, and run /ALL again, to remove the extra debugging code and keep your executable faster and smaller.

What is the /LINK flag for?

The /LINK flag on the DOS command line will force the linker to run regardless of the need to recompile any objects that the target depends on. MAKE MYPROG /LINK Normally, if you have set up your dependencies correctly, this will never need to be done, but the option is there if you need it.

What is the /P flag for?

PBMake uses a script preprocessor to do the actual make and link process. This allows you to use a linker that does not support #defines, since PBMake does the work ahead of time. If you are wondering what the actual script contains that is being passed to the make process or the link process, simply pass /P on the command line, and PBMake will not clean up the preprocessor scripts. Then, you can look at them. The .MAK file preprocesses into the .PPM file of the same name. The .LNK file preprocesses into the .PPL file of the same name.

My linker doesn't like the @ symbol!

If you are using PBMake for a linker that does not require the @ symbol before the script name, you can eliminate it by using the LINKER_SEP= directive. You can use this directive to substitute a new symbol... LINKER_SEP=% ...or to eliminate the symbol: LINKER_SEP=NONE or LINKER_SEP= If you don't use the LINKER_SEP= directive, it defaults to: LINKER_SEP=@

How big can my make scripts get?

If you cannot fit all of these dependencies on one line, you can add more and more lines of these directives. + LIB= The library files you depend on + INCLUDE= The include files you depend on + INCLUDE1= ... INCLUDE99= (can be different for each section) + PROG1= .... PROG99= The source files to compile + Denotes directives that can be used additively. This means that if you need more of each type of these directives than will conveniently fit on one line, you may add more and more of these until all files are listed. They are additive. The basic limit is that of Clipper. No more than 4096 elements in any directive group (they are arrays). If you use any of the other directives more than once, PBMake will use the last one read in. It is highly unlikely you will ever reach the limits of PBMake.