Wissensdatenbank
pronego > pronego Helpdesk > Wissensdatenbank

Makefile Directives

Lösung

Makefile Directives


Makefile directives provide additional control over omake. There are two directive types:

  • Percent directives, which use a percent sign (%) as the first non-white-space character on the makefile line.
  • Dot directives, which look like dependency lines but use special target names.

Percent Directives

Percent directives (usually called directives) have names of the form %name, where the directive character is the first non-white-space character on the makefile line. White space is allowed between % and name.

These directives work as read-time directives or run-time directives with indentation determining whether they are interpreted at read time or at run time. If % is in the leftmost column of the line, the directive is interpreted at read time. If white space precedes the %, the directive is interpreted at run time.

Conditional Directives

The directives in Table 6 control the flow of the make process at read time and at run time. Conditional and iteration directives can be nested up to 31 levels deep.

Table 6 Conditional Directives  
Conditional directives
Action
Applicable time
% if condition
Start a conditional block
read/run
% ifdef macro
Start a conditional block
read/run
% ifndef macro
Start a conditional block
read/run
% elif / elseif condition
Continue the conditional block
read/run
% else
Start the default conditional block
read/run
% endif
End the conditional block
read/run

Iteration Directives

The directives in Table 7 provide iteration control. Iteration and conditional directives can be nested up to 31 levels deep.

Table 7 Iteration Directives  
Iteration directives
Action
Applicable time
% foreach name [ in ] list
Loop for each name in list
read/run
% while condition
Loop while condition is true
run
% end
End the loop
read/run
% break
Interrupt and quit innermost loop
run
% continue
Interrupt and restart innermost loop
run

Other Percent Directives

Other directives behave like commands built into omake. At run time, these directives can be preceded with build script prefixes, which must appear before the %. See Table 8.

Table 8 Other Percent Directives   
Other directives
Action
Applicable time
% abort [ status ] [ message ]
Display message, exit with status
read/run
% chdir directory
Change current directory
run
% do [ target ] [ macros ]
Execute build scripts of target
run
% echo [ –n ] message
Display message
read/run
% error [ status ] [ message ]
Display message, return exit status
read/run
% exec command
Execute command line
read
% include [ <" ] file [ >" ]
Include contents of makefile
read
% restart [ flags ]
Start omake again
read/run
% set name [+]= value
Set macro name with value
run
% setenv name [ = ] value
Set environment variable NAME
read/run
% undef name
Undefine macro name
read/run

Conditional Directives

Conditional directives control the makefile lines that omake reads at read time and control the build scripts that are executed at run time. These directives take this form:

%if condition
  [ makefile line ]
  .
  .
  .
[ %elif condition ]
  [ makefile line ]
  .
  .
  .
[ %else ]
  [ makefile line ]
  .

  .
  .
%endif

Each %if must be matched with an %endif. There can be several %elif or %elseif clauses and at most one %else. Lines between %if or %elif and the next %elif, %else, or %endif are a block. If condition is true, the makefile lines are read or the build-script lines are executed. If none of the conditions is true and there is a %else clause, the block between %else and %endif is read or executed.

If the % of these directives is in the leftmost column of the makefile, the directive is evaluated at read time; otherwise, the directive is evaluated at run time. There can be white space between % and the name of the directive. No shell-line prefixes are allowed before the %.

There are two specialized version of %if:

%ifdef name 
%ifndef name 

%ifdef is true if macro name is defined. %ifndef is true if macro name is not defined.

Conditional Directives and Continued Lines

Directives can be used to conditionally select the continued makefile text. For example:

OBJS = main.obj parse.obj \
(the continuing line) 
%ifdef Debugging
 
  version.obj \
(continues here if Debugging  defined) 
  mymalloc.obj
 

%endif
 
a blank line
(continues here if Debugging undefined) 

If the Debugging macro is not defined, the OBJS macro value is main.obj parse.obj. If the macro is defined, the value is main.obj parse.obj version.obj mymalloc.obj.

The way this example is written makes the blank line after the %endif necessary because the continuing line is continued on the first line after the %endif if Debugging is undefined. Using an %else clause instead is done like this:

OBJS = main.obj parse.obj \

(the continuing line) 
%ifdef Debugging

 
  version.obj \
(continues here if Debugging defined) 
  mymalloc.obj
 
%else
 

 
(continues here if Debugging undefined) 
%endif
 

Conditional Expressions

The %if, %elif, and %while directives use the same conditional expressions. These expressions compare strings and numbers and combine the comparisons with logical operations. As well, the status of macros, command-line targets, and files can be determined. All macro references in the conditional expression are expanded before the expression is evaluated.

The conditional expressions here are organized by type. Some examples follow each type. For the examples, the following macros are assumed to be defined:

DEBUG    = 0
MODEL    = S
NONE     =
OBJS     = 1.obj 2.obj

Simple Expressions

You can use any of the following simple expressions:

value
'value'
"value"

If value is zero, the condition is false; all other values indicate true. Single or double quotes must be placed around value if it contains spaces or is null.

Some examples of simple expressions:

%if ASTRING    value is true
%if 12         value is true
%if 0          value is false
%if $(MODEL)   value is true
%if $(DEBUG)   value is false
%if $(NONE)    ERROR! $(NONE) is null
%if "$(NONE)"  value is false

Comparison Operators

The operators in Table 9 make a numerical or alphabetical comparison of two values, returning 1 if the comparison is true and 0 if false.

Table 9 Comparison Operators
Comparison operators
Value
value1 = = value2
True if value1 is equal to value2.
value1 != value2
True if value1 is not equal to value2.
value1 < value2
True if value1 is less than value2.
value1 <= value2
True if value1 is less than or equal to value2.
value1 > value2
True if value1 is greater than value2.
value1 >= value2
True if value1 is greater than or equal to value2.

If both values start with a digit, the comparison is done numerically; otherwise, it is done alphabetically. If either value contains spaces or is null, it must be enclosed in quotes. The case-sensitivity of the string comparison is the same as for target names and can be set with the .CASE_TARGET and .NOCASE_TARGET directives.

Some examples of comparison operators:

%if $(MODEL) == S   true
%if ABC > DEF       false
%if $(DEBUG) != 0   false
%if $(XYZ) == 1     error! $(XYZ) is null
%if $(XYZ)x == 1x   false
%if $(OBJS)x != x   error! $(OBJS) has spaces
%if "$(OBJS)" != "" true

Functional Operators (Also Called Built-In Functions)

All function operators take one or more arguments and return a value that is false (0), true (1) or some other number. See Table 10.

Table 10 Functional Operators
Functional operators
Value
%defined(name)
True if macro name is defined.
%dir(name)
True if name is a directory.
%exists(name)
True if name is a file or directory.
%file(name)
True if name is a file.
%length(name)
The number of characters in $(name).
%make(name)
True if name is a command-line target.
%member(name, list)
True if name appears exactly as an element of list.
%null(name)
True if macro name is undefined or if its expansion is null.
%time(name)
The on-disk time stamp of file name.
%writable(name)
True if file name is writable

File-Test Operators

The file-test operators return the state of files and directories. Most of these operators have been made obsolete by the equivalent functional operators. See Table 11.

Table 11 File-Test Operators
File-test operators
Value
–d name
Same as %dir(name).
–e name
Same as %exists(name).
–f name
Same as %file(name).
–r name
Same as %file(name).
–w name
Same as %writable(name).
–z name
True if name is a zero-length file.

One example of the file-test operators:

%if –e builtins.mak 
(true if builtins.mak exists) 

Command-Execution Operator

The command-execution operator executes a command using the shell program. See Table 12.

Table 12 Command-Execution Operator
Execution operator
Value
[ command ]
where the brackets are literal.
The exit status of the command. By convention, commands return 0 if they succeed.

Here is an example that runs a hypothetical mkproto program that freshens the prototype files for its source files:

%if [ mkproto *.c ]
% abort MKPROTO could not freshen the prototypes.
%endif

You can ignore the exit status of the executed command by using an %if ... %endif pair that doesn't encapsulate anything. The following idiom is seen in VC++ makefiles:

!if [ if exist MSVC.BND del MSVC.BND ]
!endif

Logical Operators

The logical operators are used to combine other expressions. Each expression is evaluated from left to right, but parentheses can be used to order the evaluation. See Table 13.

Table 13 Logical Operators
Logical operators
Value
exp1 && exp2
True if both exp1 and exp2 are true.
exp1 | | exp2
True if either exp1 or exp2 are true.
! exp
True if exp is false. False if exp is true.
( exp )
The same state as exp.

Unlike the C programming language, the logical expressions do not short-circuit. That is, exp1 and exp2 are always evaluated. For example:

%if %defined(NONE) && %null(NONE)
(true) 
%if %defined(XYZ) && %null(XYZ)
(false) 
%if ! ( ! –f file || –z file )
(false if file is absent or is zero length) 

Iteration Directives

The %while and %foreach directives provide iteration capability. At run time, they allow build scripts to be executed multiple times. %foreach can also be used at read time to replicate makefile lines.

The %foreach Directive

The form of the %foreach directive:

%foreach name [ in ] list_of_names 

  [ makefile lines ]
  .
  .
  .
%end 

The list_of_names is a set of names separated by white space. The value of macro name is set to the first name in the list_of_names, and the makefile lines after this %foreach and before %end are read (at read time) or executed (at run time).

If the % of these directives is in the leftmost column of the makefile, the directive is evaluated at read time; otherwise, the directive is evaluated at run time. No shell-line prefixes are allowed before %foreach or %end.

When %end is reached, name is set to the next name in list_of_names, and the loop is restarted. When there are no more names, the loop is done and name returns to its previous value. For PM/CB compatibility, the optional keyword in is supported and %endfor can be used in place of %end.

If %foreach is used at read time, the makefile lines between %foreach and %end are parsed multiple times with name taking on successive values from the list_of_names. As the lines are parsed, all macro references to name are expanded.

The following example illustrates the use of %foreach at read time:

%foreach var in main sub io
macro_$(var) = $(value_$(var)) $(other_macro)
$(var).obj : $(var).c
  cl –c $(.SOURCE)
%endfor

All $(var) references are replaced with the current value of var. omake treats the previous %foreach loop as if it has read the following makefile lines:

macro_main = $(value_main) $(other_macro)
main.obj : main.c

  cl –c $(.SOURCE)
macro_sub = $(value_sub) $(other_macro)
sub.obj : sub.c
  cl –c $(.SOURCE)
macro_io = $(value_io) $(other_macro)
io.obj : io.c
  cl –c $(.SOURCE)

Here is an example run-time use of %foreach to build a linker response file using the inline response file syntax (see Inline Response Files):

project.exe : $(OBJS)
 
  link @<<
(link @response_file) 
%foreach x in $(.SOURCES)
 
$x 

(adds each .obj +) 
%end
    
Artikel-ID: 19
Kategorie: pronego
Datum (hinzugefügt): 06.02.2009 09:32:36
Aufrufe: 5011

 
<< Zurück

Powered by Help Desk Software HESK™