RAD Studio
ContentsIndex
PreviousUpNext
MAKE Rules (Explicit and Implicit) and Commands

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 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 target(s); two colons mean that two or more rules are written for the target(s).  

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 enclosed the entire path specification in braces.  
<dependent>  
Is the file (or files) whose date and time MAKE checks to see if 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 they are 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 

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 filename 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 filename extension. Macros are allowed here.  
: (colon)  
Marks the end of the dependency line.  
<commands>  
Are any operating system command or commands. You must indent the command line by at least one space or tab; otherwise they are 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 .SUFFIXES list.

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).

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 won’t recognize (however, note that | can't 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's being executed.  
-<num>  
Stops processing commands in the makefile when the exit code returned from 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 don't 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 $** and $! macros.

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

Operator 
Description 
<  
Use input from a specified file rather than from standard input.  
>  
Send the output from command to file.  
>>  
Append the output from command to file.  
<<  
Create a temporary inline file and use its contents as standard input to command. Also, create temporary response file when -N is used. Note: this is only for use with Microsoft's NMAKE.  
&&  
Create a temporary response file and insert its name in the makefile.  
<delimiter>  
Use delimiters with temporary response files. You can use any character other than # as a delimiter. Use << and && as a starting and ending delimiter 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.  
Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!