1.1.1. Introduction
1.2.1. Operational description of imake
1.3.1. Components of a make file
2.1.1. Comments and line extensions
2.2.1. Macros
2.2.2. Default macros
2.3.1. Escape sequences
2.3.2. !include
2.3.3. Conditionals
2.4.1. Path specifications
2.5.1. Rules
2.5.2. Explicit rules
2.5.3. Implicit rules 
2.6.1. Miscellaneous command constructs
3.1.1. Command line format
4.1.1. itouch


1.1.1. Introduction

This document describes imake, a make file interpreter, and itouch, used 
for setting the time on a file to the current system time.

imake process a list of file dependencies.  If a file depends on another 
file and the time of the second file is later than the time of the first 
file, imake executes a list of commands to bring the first file up to 
date.  This is useful for example to ensure that an executable file is 
rebuilt after the sources which generate it have changed, or to ensure 
that any source which depends on an include file is recompiled or 
reassembled after the include file is changed.

1.2.1. Operational description of imake

imake 1st looks for the file "BUILTINS.MAK".  If it is not found in the
current directory imake searches the path(s) specified in the PHI
environment variable.  If it is still not found imake searches the
directory imake.exe is located in.  if imake finds it it will be loaded as 
a makefile.  BUILTINS.MAK will be ignored if the -r command line switch is 
specified

imake goes on to look for "MAKEFILE" and then "MAKEFILE.MAK".  If it finds 
either of these it loads it.  Only one of these will be loaded.  This 
name may be overridden with the -fNAME switch.  In this case imake will 
skip looking for "MAKEFILE" and "MAKEFILE.MAK" and look instead for "NAME"
and "NAME.MAK".  Again only one of these will be loaded.

The loaded files will be interpreted.  Source dependencies will be 
compared against the current system time and rules are executed to bring 
any old sources up to date.

1.3.1. Components of a make file

Components of a makefile are:

1) Comments
2) Macro definitions
3) Escape sequences
4) Path specifications
5) Implicit rules
6) Explicit rules

2.1.1. Comments and line extensions

Comments start or end with a '#' or can be enclosed in Ftext box 
characters.  The first instance of a comment character will cause text to 
be ignored; the next instance will cause text to be used again.  An End of 
Line marker ends commenting if it is on.

Valid comments include:

        # This is a comment

Extension characters may be used at the end of a line to tell imake to 
concatenate two or more lines together.  Extension characters are '\'.

2.2.1.

Macro definitions must start in the leftmost column.  The syntax is:

MACRONAME = string

whitespace will be stripped from the left and right sides of the string.
Macros may be used at any point in the makefile instead of direct text and 
they will be expanded before use.  To use a macro this is the syntax:

$(MACRONAME)

Macros will be fully expanded, including any macros a macro may have in 
it. Sometimes it is convenient to be able to change text in a macro: the
syntax is:

$(MACRONAME:oldtext=newtext)

where newtext is substituted for oldtext wherever it appears in the macro.
This substitition is done prior to substituting for any macros which may
appear as part of the macro definition for MACRONAME.  Macros may with few 
exceptions be redefined at any time; however as explained later reusue of 
macros may be somewhat confusing.

2.2.2. Default macros

All environment variables are imported as macros.  If a macro has the same 
name as an environment variable the value of the environment variable will 
be lost unless -e is used on the command line.

You may use the -D and -U switches to override macro definitions in the 
makefiles.  -DMACRONAME=VALUE or -DMACRONAME defines a macro with or 
without a value.  -U causes MACRONAME to be undefinable.  These switches 
take full precedence over macros defined in other ways.

The following additional macros are defined by default:

       +---------------------------------------------------------------+
       |Name            Expands to                                     |
       +------------+--------------------------------------------------+
       |MAKE        |   the make program name (usually imake.exe)      |
       |MAKEDIR     |   the path imake was loaded from                 |
       |MAKEFLAGS   |   arguments specified on the imake command line  |
       |__MAKE__    |   Version of imake                               |
       |__MSDOS__   |   "1" - this is an msdos make program            |
       |__PHIDOS__  |   "1" - this is a F tool running under DOS       |
       +------------+--------------------------------------------------+

In addition the following macros may be used in commands in implicit and
explicit rules:

       +------------------------------------------------------------------+
       |macro   Expands in Implicit             Expands in Explicit       |
       +------+------------------------------+----------------------------+
       |$*    | path\dependent file          |  path\target file          |
       |$<    | path\dependent file+ext      |  path\target file +ext     |
       |$:    | path for dependents          |  path for target           |
       |$.    | dependent file +ext          |  target file +ext          |
       |$&    | dependent file               |  target file               |
       |$@    | path\target file +ext        |  path\target file +ext     |
       |$**   | path\dependent file+ext      |  files from dependents line|
       |$?    | path\dependent file+ext      |  undefined                 |
       +------+------------------------------+----------------------------+

2.3.1. Escape sequences

Escape sequences are used to control interpretation of the makefile.  
Escape sequences exist to include an include file or for conditional 
interpretation.

Escape sequences begin with a '!' character.  If an esacpe sequence is used,
it may be indented by any amount of whitespace.  Escape sequences are case 
sensitive and must be lower case.

2.3.2. !include

!include "filename"

Filename will be searched for along the include search path (-I paramater).
If found they will be loaded.  Commands and macro definitions may span
file boundaries; keep this in mind.

2.3.3. Conditionals

Conditionals only check for the presence or absence of a macro.  There is 
no support in imake for mathematical calculations or comparisons.

!ifdef  $(MACRO)
or
!ifdef {MACRO}

Start an if block.  if MACRO is undefined lines will not be parsed until
the next escape sequence.

!ifndef $(MACRO)
or
!ifndef {MACRO}

Start an if block.  If MACRO is defined lines will not be parsed until the
next escape sequence.

!else 

if line skipping is on, start parsing lines again, otherwise stop parsing

!endif

close this if block and start parsing if the nesting if allows.

Note that MACRO searching in an escape sequence is done at the time the
line is encountered in the input file.  Thus if the macro was defined
anywhere before the escape sequence it will be located.  In contrast to 
this, macros in commands are not expanded until the entire make file has 
been read... so the very last definition of a given macro is the one that 
holds in this case.

2.4.1. Path specifications

Source filenames may appear in alternate directories.  When searching for a 
source (dependency) imake first looks in the current directory.  Then it 
examines the extension of the file and determines if any alternate
directories have been specified; if so it will look for the file in the 
alternate directory.  If it cannot find a source file which has been
specified as a dependent and cannot find a rule for building it, imake 
will generate an error message.

Path specifications must start in the first column of a line and take the
following form:

.path.EXT = searchpath[;searchpath[;searchpath ...]]

for example:

.path.asm = ..\source

tells imake to look for source files in the source directory.  Path 
declarations must be done in lower case.


2.5.1. Rules

Rules tell imake which files are dependents of other files.  They also 
tell how to build, or bring up to date, any files that are older than 
their dependents.

There are two types of rules: explicit rules and implicit rules.

The basic format of a rule is as follows:

target:   dependency list
  (any whitespace) command1
  (any whitespace) command2
        ...

The need for whitespace to indicate a command is why macros and path 
specifications and targets are required to start in the first column.

Imake will accept target names to build on the command line; these must be 
explicit target names and can optionally have wildcard characters in 
them. If no target names are specified on the command line imake processes 
the first explicit rule it finds, spawning off other rules as needed to 
keep dependent files up to date.  

commands may be any MSDOS command, including .EXE and .COm files.  IMAKE
does not support .BAT files

2.5.2. Explicit rules

For an explicit rule, all files in the dependency list are checked to 
make sure they are newer than any files required to build them.  A 
recursive check is done on every file in the dependency list to make sure 
that it is up to date with respect to its own dependents.  The recursion 
continues until all dependency lists result in files that either exist or 
can be build with a rule.  If a file does not exist and IMAKE can not find 
a rule to build it, imake generates an error message.

Imake then starts with the lowest level of dependencies and starts 
building any files which are out of date.  If a file is out of date all 
files which depend on it are also out of date and are rebuilt.

For explicit rules, it is not necessary to have a list of commands.  Imake
will accept a target name with dependencies as a simple way to force itto 
evaluate all the dependencies; thus to build an entire project onemight 
use the target 'all' and give as dependencies any files which themake file 
is meant to build.

As an example, the rule:

file1.obj: file1.asm
        nasm -fobj file1.asm

will compare the date of file1.obj with the date of file1.asm.  If file1.asm
is newer then the command:
        nasm -fobj file1.asm
will be issued to MSDOS, resulting in bringing the file up to date.
 
2.5.3. Implicit rules 

Implicit rule targets take the form:

.EXT1.EXT2:
        < command list >

where EXT1 and EXT2 may be any valid MSDOS file extension.  If imake finds
a file with no explicit rules specified, it will look at all implicit
rules and find one whose EXT2 matches the extension on the file.  If it
finds one, it will replace the EXT2 with EXT1 in the filename and search
for the resulting filename.  If it finds that file, it presumes the
explicit rule matches the file and then compares the dates on the original
file and the one it found.  If the original file is older, it is then
rebuilt with the commands specified with the rule.

Implicit rules are searched in the order that imake encounters them.

As an example, the rule:

.asm.obj:
        nasm -fobj $<

will match any files ending in extension .obj, for example file1.obj.  If 
imake then finds a file called file1.asm (looking along the path variable
if necessary) then the implicit rule matches and imake compares the file
dates.  If file1.asm is newer than file1.obj then the command is issued,
which assembles the file and brings it up to date.

2.6.1. Miscellaneous command constructs

Some built-in macros like $< can generate a whole list of files for use
in an implicit rules.  For example:

.asm.obj:
        $(ASM) $<

will generate an ASM command line which has any SRC files which need to be
rebuilt.  If it is desirable to use a tool which does not accept multiple 
input files it can be written this way:

.asm.obj:
        @$(ASM) $<

and imake will spawn one ASM command for each file in the list.


Sometimes the command line to use with valx or xlib is too long
to fit in the MSDOS command buffer; both of these utilities (ans some others)
allow nearly unlimited input to be taken from a file.  imake will create
temporary files from an in-line file specification, pass them as arguments
to the command, and then delete them (unless -K is specified).

The syntax for starting a temporary file is: &&|, where | may be any
delimiting character.  This character will also be used to end the temporary
file.  Upon finding this sequence in a command list, imake will first ignore
the remainder of the current line as if it had been commented out.  Lines
after that will be macro-substituted and then printed directly to a temporary
file imake creates, until the delimiting character is found.  Each line
in the temporary file will be ended with a hard end of paragraph (0x0a).
Lines may be concatenated with the line extenders.

Now the first line will be recalled and the name of the makefile will be
substituted for the &&|.  Characters on the last line after the delimiting
character will be appended to this line and the entire thing will be
issued as a command.  imake uses the name "MAKEFILE.???" for temporary
files, where the wildcards may be any number.  This allows an arbitrary
number of temporary files during a build.

For example:

        valx -use32 -nci @&&|
codos.obj $(SOURCE_deps),filnam,filnam,cldos.lib
|

If SOURCE_deps expands to the files DEBUG.obj and HANDLER.obj a file will 
be created by imake with the following contents:

c0dos.obj debug.obj handler.obj,filnam,filnam,cldos.lib

This file will be called makefile.??? where digits will be substitute for 
the ???.  imake will then issue the command:

        valx -use32 -nci @makefile.???


3.1.1. Command line format

imake [/a/B/D/e/f/h/I/K/m/n/q/r/s/u target names]
-B      force everything to be rebuilt regardless of times
-DMACRO or -DMACRO=value
        define a macro
-e      Don't allow redefinition of environment variable macros
-fname  use file "name" instead of "MAKEFILE"
-h      show the usage line
-I      specify include file directories
-K      Keep temporary files.  By default imake deletes temporary files.
-m      Display the date and time stamp of each file imake processes.
        Files which need to be rebuilt will have a '*' next to them.
-n      Commands are printed to the screen but not executed.  Useful in
        debugging a makefile
-p      Print macro definitions and rules after parsing but before
        execution of the makefile
-q      change the return value to be 0 if the target is up to date or 1
        if any changes were made
-r      Ignore BUILTINS.MAK
-s      don't print commands to the screen before spawning them
-U      Make a macro undefinable

4.1.1. itouch

itouch stamps the current system time to the files specified.  Wild
cards may be used.  The only option is:

itouch [/v] filenames

-v      display files as they are being touched