MAKE Rules (Explicit and Implicit) and Commands

From RAD Studio
Jump to: navigation, search

Go Up to MAKE.EXE


You write explicit and implicit rules to instruct MAKE how to build the targets in your makefile. In general, these rules are defined as follows:

  • Explicit rules are instructions for specific files.
  • Implicit rules are general instructions for files without explicit rules.

All the rules you write follow this general format:

Dependency line
   Command line

While the Dependency line has a different syntax for explicit and implicit rules, the Command line syntax stays the same for both rule types.

MAKE supports multiple dependency lines for a single target, and a single target can have multiple command lines. However, only one dependency line should contain a related command line. For example:

Target1: dependent1 dep2 dep3 dep4 dep5
Target1: dep6 dep7 dep8
    bcc32 -c $**

Explicit Rule Syntax

Explicit rules specify the instructions that MAKE must follow when it builds specific targets. Explicit rules name one or more targets followed by one or two colons. One colon means one rule is written for the targets; two colons mean that two or more rules are written for the targets.

Explicit rules follow this syntax:

<target> [<target>...]:[:][{<path>}] [<dependent[s]>...]
    [<commands>]
Element Description
<target>

Specifies the name and extension of the file to be built (a target must begin a line in the makefile -- you cannot precede the target name with spaces or tabs). To specify more than one target, separate the target names with spaces or tabs. Also, you cannot use a target name more than once in the target position of an explicit rule.

<path>

Is a list of directories that tells MAKE where to find the dependent files. Separate multiple directories with semicolons and enclose the entire path specification in braces.

<dependent>

Is the file (or files) whose date and time MAKE checks to see whether it is newer than target. Each dependent file must be preceded by a space. If a dependent appears elsewhere in the makefile as a target, MAKE updates or creates that target before using the dependent in the original target (this in known as a linked dependency.)

<commands>

Are any operating system command or commands. You must indent the command line by at least one space or tab, otherwise it is interpreted as a target. Separate multiple commands with spaces.


If a dependency or command line continues on the following line, use a backslash \ at the end of the first line to indicate that the line continues. For example:

MYSOURCE.EXE: FILE1.OBJ\       #Dependency line
FILE3.OBJ                      #Dependency line continued
    bcc32 file1.obj file3.obj  #Command line

Single Targets with Multiple Rules

A single target can have more than one explicit rule. To specify more than a single explicit rule, use a double colon :: after the target name.

The following example shows targets with multiple rules and commands:

.cpp.obj:
   bcc32 -c -ncobj $<

.asm.obj:
   tasm /mx $<, asmobj\

mylib.lib :: f1.obj f2.obj #double colon specifies multiple rules
   echo Adding C files
   tlib mylib -+cobjf1 -+cobjf2

mylib.lib :: f3.obj f4.obj
   echo Adding ASM files
   tlib mylib -+asmobjf3 -+asmobjf4

Implicit Rule Syntax

An implicit rule specifies a general rule for how MAKE should build files that end with specific file extensions. Implicit rules start with either a path or a period. Their main components are file extensions separated by periods. The first extension belongs to the dependent, the second -- to the target.

If implicit dependents are out-of-date with respect to the target, or if the dependents don't exist, MAKE executes the commands associated with the rule. MAKE updates explicit dependents before it updates implicit dependents.

Implicit rules follow this basic syntax:

[{>source_dir>}].<source_ext>[{target_dir}].<target_ext>:
    [<commands>]
Element Description
<source_dir>

Specifies the directory (or directories) containing the dependent files. Separate multiple directories with a semicolon.

.<source_ext>

Specifies the dependent file name extension.

<target_dir>

Specifies the directory where MAKE places the target files. The implicit rule will only be used for targets in this directory. Without specifying a target directory, targets from any directory will match the implicit rule.

.<target_ext>

Specifies the target file name extension. Macros are allowed here.

: (colon)

Marks the end of the dependency line.

<commands>

Are any operating system commands. You must indent the command line by at least one space or tab; otherwise it is interpreted as a target.


If two implicit rules match a target extension but no dependent exists, MAKE uses the implicit rule whose dependent's extension appears first in the list of a .SUFFIXES directive.

Explicit Rules with Implicit Commands

A target in an explicit rule can get its command line from an implicit rule. The following example shows an implicit rule followed by an explicit rule without a command line:

.c.obj:
bcc32 -c $<  #This command uses a macro $< described later
myprog.obj:  #This explicit rule uses the command: bcc32 -c 
myprog.c

The implicit rule command tells MAKE to compile MYPROG.C (the macro $< replaces the name myprog.obj with myprog.c.)

MAKE Command Syntax

Commands immediately follow an explicit or implicit rule and must begin on a new line with a space or tab. Commands can be any operating system command, but they can also include MAKE macros, directives, and special operators that your operating system does not recognize (however, note that | cannot be used in commands).

Here are some sample commands:

cd..
bcc32 -c mysource.c
COPY *.OBJ C:\PROJECTA
bcc32 -c $(SOURCE) #Macros in "Using MAKE macros"

Commands follow this general syntax:

[<prefix>...] <commands>

Command Prefixes

Commands in both implicit and explicit rules can have prefixes that modify how MAKE treats the commands. The following table lists the prefixes you can use in makefiles:

Prefix Description
@

Does not display the command while it is being executed.

-<num>

Stops processing commands in the makefile when the exit code returned from the command exceeds the integer num. Normally, MAKE aborts if the exit code is nonzero. No space is allowed between - and <num>.

-

Continues processing commands in the makefile, regardless of the exit codes they return.

&

Expands either the macro $**, which represents all dependent files, or the macro $?, which represents all dependent files stamped later than the target. Execute the command once for each dependent file in the expanded macro.

!

Behaves like the & prefix.


Using @

The following command uses the @ prefix, which prevents MAKE from displaying the command onscreen:

diff.exe : diff.obj
   @bcc32 diff.obj

Using -<num> and -

The prefixes -<num> and - (hyphen) control the makefile processing when errors occur. You can choose to continue with the MAKE process if any error occurs, or you can specify a number of errors to tolerate.

In the following example, MAKE continues processing if BCC32 returns errors:

target.exe : target.obj
target.obj : target.cpp
      -bcc32 -c target.cpp

Using &

The & prefix issues a command once for each dependent file. It is especially useful for commands that do not take a list of files as parameters. For example:

copyall : file1.cpp file2.cpp
    &copy $** c:\temp

invokes COPY twice, as follows:

copy file1.cpp c:\temp
copy file2.cpp c:\temp

Without the & modifier, MAKE would call COPY only once.

Note: The & prefix only works with the $** and $! macros.

MAKE Command Operators

While you can use any operating system command in a MAKE command section, you can also use the following special operators:

Operator Description
<

Uses input from a specified file rather than from standard input.

>

Sends the output from command to file.

>>

Appends the output from command to file.

<<

Creates a temporary inline file and use its contents as standard input to command. Also, create a temporary response file when -N is used. Note: This can only be used with Microsoft's NMAKE.

&&

Creates a temporary response file and insert its name in the makefile.

<delimiter>

Uses delimiters with temporary response files. You can use any character other than # as a delimiter. Use << and && as starting and ending delimiters for a temporary file. Any characters on the same line and immediately following the starting delimiter are ignored. The closing delimiter must be written on a line by itself.

See Also