Makefile directives provide additional control over omake. There are two directive types:
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.
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.
The directives in Table 7 provide iteration control. Iteration and conditional directives can be nested up to 31 levels deep.
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.
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.
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:
%else
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
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
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.
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
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.
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.
One example of the file-test operators:
%if –e builtins.mak
(true if builtins.mak exists)
The command-execution operator executes a command using the shell program. See Table 12.
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
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.
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)
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 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)
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: 6412
<< Zurück
Powered by Help Desk Software HESK™