A macro definition associates a name and a value. The macro expansion of a macro name returns the value. Macros are used at read time to organize names of files, compiler options, and so on. At run time, macros provide information about the current target being built.
When a macro is referenced, the expanded value can be modified through the use of macro modifiers. To modify a macro, expand it with:
$(name,modifier[,modifier ...])
Everything between $( and ) is expanded, the value of name is expanded, and then each modifier is applied in succession to the expanded value. The separator between name and modifier can be a comma or colon, but subsequent modifiers must follow a comma. A literal comma is available by using \,. Some modifiers use regular expressions. The treatment of the backslash, can make it awkward to use a modifier when a backslash also terminates its argument. You can work around this by using two backslashes before a comma separator(\\,) or
if possible, move the awkward modifier to the end. If this not possible, use two modifications. For example,
OBJS = $(SRCS,<obj\,R,>.obj)
does not work, but this pair of macro definitions does:
OBJS = $(SRCS,<obj\)
OBJS := $(OBJS,R,>.obj)
Considering the macro value as a list of macro elements separated by white space, the first modifier is applied to all elements, then the next modifier is applied, and the next, and so on. The following list of modifiers is organized into functional groups. Examples of each modifier use the following macro definition:
SRCS = \src\main.c \sys\sub.cpp io.cpp
>string | Appends string to each element of the macro. |
|
$(SRCS,B,>.obj) is main.obj sub.obj io.obj |
<string | Prepends string to each element of the macro. |
LC | Lowercase. Change the letters of the element to lowercase. |
|
$(SRCS,Z,LC) is d: c: c:
|
UC | Uppercase. Change the letters of the element to uppercase. |
|
$(SRCS,B,>.obj,UC) is MAIN.OBJ SUB.OBJ IO.OBJ
|
X | This modifier expands elements into their pathnames. As an example: |
|
.PATH.obj = objs |
|
OBJS = 1.obj 2.obj |
|
project.exe : $(OBJS) |
|
link $(.TARGET), $(OBJS,X);
|
The .PATH.obj macro defines a search directory where .obj files are located. The X modifier causes omake to search for each element in its search directories. Assuming 1.obj and 2.obj are in the objs directory: | |
|
$(OBJS) is 1.obj 2.obj |
|
$(OBJS,X) is objs\1.obj objs\2.obj |
@d regex d subst d | |
Include file, with regular-expression matching. [A regular expression . matches any single character; a regular expression \. is a literal period (or dot). Several regular expression characters that omake uses are poor choices when the regular expression is used to match file names. omake allows you to redefine these characters with the .REGEX_CHAR and .REGEX_WILD directives.] | |
The macro's value is the name of a file to be read. Each line in the file is examined with the regular expression regex. If regex matches the line, the matched part of the line is replaced with the substitution string subst. If regex does not match, the line is skipped. | |
The d is a single-character delimiter that cannot appear in regex or subst and cannot be a comma (usually a slash (/) or single quote ( ' ) is used). |
The M, N, and S modifiers use pattern-matching strings known as regular expressions. The regular expression (or regex) matches characters in strings, both literally and with wildcards, and the match is case-sensitive.
Two directives control the special characters that appear in regular expressions:
.REGEX_CHAR sets the character used to indicate special character sequences. The default character is a backslash (\).
.REGEX_WILD sets the wildcard character that matches any single character. The default character is a period ( . ).
The backslash and period are standard characters in UNIX-styled regular expressions, but are awkward to use in Windows NT because the backslash is the directory separator and the period is the file extension separator. The .REGEX_CHAR and .REGEX_WILD directives can be used to change these characters to some other characters.
The default characters are most problematic for the M and N modifiers when you are trying to match a file name. For this case, use the M"spec" and N"spec" modifiers because the spec is a file specification rather than a regular expression.
Assume the following macro definitions:
SRCS = main.c sub.cpp io.cpp
CFLAGS = -AX -Ifoo -Ibar /Ibaz -DX=-IT xI.c yi.c
To select files whose names include .c:
$(SRCS,M\.c)
is main.c sub.cpp
To select files that end in .c, the search can be anchored to the end with the regex character $. To get $ to the regular expression, you need to use $$ in the makefile:
You can also select .c files with the M"spec" modifier:
Analogous to the $ anchor, the ^ regex character anchors the search to the front of the macro element:
$(CFLAGS,M-I)
is -Ifoo -Ibar -DX=-IT
is
$(CFLAGS,M^-I)-Ifoo -Ibar
The [set] regex characters indicate a set of characters, where the set can be single characters ([aA@] matches a, A or @), a range of characters ([a-z] matches a through z), or a mixture. For example:
$(CFLAGS,M^[-/]I)
is -Ifoo -Ibar /Ibaz
One powerful feature of regular expressions is that when used in substitutions, they can access the matched parts of the string. The down side of the more powerful regular expressions is that the expressions can be hard to read. For example, when DIR = NT_L, the expression $(DIR,S/\(.*\)_.*/\1/)
is NT
.
The \(, \) pair surround a part of the regular expression that is referenced later. Inside the pair is .*, which matches any character (.) repeated zero or more times (*). Taken together they instruct omake to match any character, zero or more times, and attach a tag to it. The rest of the regular expression is _ , which matches _, and .*, which matches any character repeated zero or more times.
The expression \1 is the stuff matched in the first pair of \( \), so the substitution evaluates to NT. Simple regular expressions are easy to read, but if you write more complicated expressions, be sure to provide thorough comments.
If omake is configured for alternative regular expression characters, the following directives appear in your make.ini:
.REGEX_CHAR : ~
.REGEX_WILD : ?
These examples are then easier to read:
$(SRCS,M.c) is main.c sub.cpp
$(SRCS,M.c$$) is main.c
$(CFLAGS,M-I) is -Ifoo -Ibar -DX=-IT
$(CFLAGS,M^-I) is -Ifoo -Ibar
$(CFLAGS,M^[-/]I) is -Ifoo -Ibar /Ibaz
$(DIR,S/~(?*~)_?*/~1/) is NT
omake defines several macros before it reads the initialization file and makefiles. These macros come in two general types:
Predefined macros cannot be changed or undefined. Important subsets of the predefined macros are run-time macros, which change with the target being built, and state macros, which hold the state of the command-line options and read-time directives.
Built-in macros have the same precedence as normal makefile macros, and so can be redefined in your makefiles or on the command line.
The run-time macros are changed dynamically by omake according to the current target being built. A key feature of the run-time macros is that their values are pathnames. A target's pathname is the location the target was found on disk. The run-time macros evaluate to pathnames, which is important for use on build scripts where the executed command needs the location of the targets.
All run-time macros have names of the form .name, and several have one- or two-letter aliases that you are likely to see in makefiles of other make utilities.
The predefined macros in Table 3 give you information about the current make process. One of the most important predefined macros is the status macro at the bottom of the table.
General Macro | Value |
---|---|
$ | When you need a literal dollar sign, you must use $$. |
BUILTINS | The name of the initialization (built-ins) file. |
CWD | The current working directory (same as MAKEDIR). |
FIRSTTARGET | The first command-line target or, if one isn't given, the default makefile target. |
INPUTFILE | The name of the current makefile. omake can read multiple makefiles, either with multiple -f command-line options or with %include directives. The INPUTFILE macro's value is the current makefile being read. |
MAKEARGS | The command line with which omake was started, including command-line options, macros, and targets. |
MAKEDIR | The current working directory (same as CWD). |
MAKEMACROS | The command-line macros with which omake was started. Any macros that have spaces are enclosed in double quotes so they can be used on a command line again. |
MAKESTATUS | The exit status of omake. This can be used in the .AFTER special target to determine whether omake is exiting with an error. |
MAKETARGETS | The list of command-line targets passed to omake. |
MAKEVERSION | The version number for omake. Its format is X.Y, where X and Y are the major and minor release numbers. |
OPUS | Defined to the value 1. This can be used to test if you are running omake or some other Make. |
status | The exit status of the last build script. It is used with conditional directives to execute other build scripts. For historical reasons, the name is lowercase. |
The state macros provide information about the state of command-line options and read-time directives. Most command-line options have an equivalent directive, and the value of the state macro is the same regardless of whether the option or directive was used.
In the list of macros in Table 4, the macro values that are the state of a directive or command-line option mean the value is 1 if the directive or command-line option was used; otherwise the value is 0.
NOTE: In terms of implementation, .ALWAYS, .IGNORE, and .SILENT are not directives; they are target attributes. They look like directives when they appear in a makefile on the target side of a dependency line when there are no dependencies. For example,
.IGNORE :
sets the .IGNORE attribute for every target created after the appearance of this line. The .ALWAYS, .IGNORE, and .SILENT macros have the correct value, as if these attributes were directives.
NOTE: Exactly one of $(.MS_NMAKE), $(.omake) or $(.POLY_MAKE) is 1.
State Macro | Value |
---|---|
.ALWAYS | The state of the .ALWAYS directive and -a command-line option. [In terms of implementation, .ALWAYS, .IGNORE, and .SILENT are not directives but target attributes. They look like directives when they appear in a makefile on the target side of a dependency line when there are no dependencies. For example, |
.CASE_MACRO | The state of the .CASE_MACRO directive. |
.CASE_TARGET | The state of the .CASE_TARGET directive. |
.DEBUG | The debug options as set by the .DEBUG directive and -# command-line option. |
.DEBUG_PRINT | The state of the .DEBUG_PRINT directive and -p command-line option. |
.DEBUG_RUN | The state of the .DEBUG_RUN directive and -d command-line option. |
.ENVMACROS | The state of the .ENVMACROS directive. |
.ENV_OVERRIDE | The state of the .ENV_OVERRIDE directive and -e command-line option. |
.IGNORE | The state of the .IGNORE directive and -i command-line option. |
.IGNORE_MFLAGS | The state of the -z command-line option. |
.KEEPDIR | The state of the .KEEPDIR directive and -D command-line option. |
.KEEPWORKING | The state of the .KEEPWORKING directive and -k command-line option. |
.MAKE_MAKEFILE | The state of the .MAKE_MAKEFILE directive and -M command-line option. |
.MS_NMAKE | The state of the .MS_NMAKE directive (exactly one of $(.MS_NMAKE), $(.omake) or $(.POLY_MAKE) is 1) and -EN command-line option. |
.OPUS_52X | The list of Opus Make v5.2x compatibility features, as set by the -E2 command-line option. |
.omake | The state of the .omake directive and -EO command-line option. |
.POLY_MAKE | The state of the .POLY_MAKE directive and -EP command-line option. |
.QUERY | The state of the -q command-line option. |
.REGEX_BACK | The regular expression literal backslash (\). This is provided for writing regular expressions that are independent of the value of .REGEX_CHAR. If .REGEX_CHAR is \,its value is \\; otherwise, its value is \. |
.REGEX_CHAR | The regular expression escape character set by the .REGEX_CHAR directive. |
.REGEX_DOT | The regular expression literal dot (or period). If .REGEX_WILD is . its value is ${REGEX_CHAR}.; otherwise its value is . |
.REGEX_WILD | The regular-expression wildcard character set by the .REGEX_WILD directive. |
.REJECT_RULES | The state of the .REJECT_RULES directive and -r command-line option. |
.REREAD | The state of the .REREAD directive. |
.RULE_CHAR | The regular expression character as set by the .RULE_CHAR directive. |
.SHELL | The command to execute the shell program as set by the .SHELL directive. |
.SILENT | The state of the .SILENT directive or -s command-line option. |
.SUFFIXES | The list of suffixes as set by the .SUFFIXES directive. |
.UNIXPATHS | The state of the .UNIXPATHS directive. |
Here is an example of how these macros can be used. Suppose you want to debug the contents of your makefile with the -#1 command-line option. However, this also produces output that comes from your make.ini file, which probably doesn't need debugging. Modify your make.ini file with the following:
_OLD_DEBUG := $(.DEBUG) |
(get current state) |
.NODEBUG : 1 |
(turn off "-#1" if set) |
[Original make.ini goes here] |
|
.DEBUG : $(_OLD_DEBUG) |
(restore state) |
omake defines the built-in macros with a default value, but they have the same precedence as normal makefile macros, so you can be redefine them.
Built-in Macro | Definition |
---|---|
CC | Used in the %.obj : %.c rule, the name of the C compiler. The default value is cl, the name of the Microsoft C Compiler. |
FC | Used in the %.obj : %.for rule, the name of the FORTRAN compiler. The default value is f77l, the name of the Lahey FORTRAN Compiler. |
LIBEXE | Used in the %.lib : %.obj rule, the name of the object librarian. The default value is lib, the name of the Microsoft Librarian. |
LINK | Used in the %.exe : %.obj rule, the name of the object linker. The default value is link, the name of the Microsoft Linker. |
MAKE | The value is the full pathname of the omake executable. The MAKE macro is special in that its appearance on a build script overrides the -n (no execute) command-line option for that line. This can be used in a recursive make, to have omake do the recursion. |
MAKE_TMP | The name of the directory omake uses for temporary files (response files under Windows NT). Initially MAKE_TMP is undefined and omake uses the current directory for temporary files. If you define MAKE_TMP its value must be an absolute directory (such as D:\ or D:\tmp, preferably on a RAM disk. As an example, the environment variable TMP names the temporary directory some compiler vendors use. You can put the following in make.ini:
|
MFLAGS | After all makefiles have been read, omake defines MFLAGS with all the command-line options. MFLAGS is useful for invoking omake recursively, as shown in the definition of the MAKE macro. NOTE: MFLAGS is a built-in macro only if you are using native omake mode (that is, if you are not using an emulation mode). In the emulation modes, it is not predefined by omake; however, you can redefine it. A second usage of MFLAGS is to pass initial options to omake. If MFLAGS is defined in the environment or in make.ini its value specifies additional command-line options. For example, the following macro definition placed in make.ini turns on the keep-directory mode (the -D command-line option):
Because there are directives for all command-line options, this second usage of MFLAGS is discouraged, and you should use the directives. |
OS | The operating system. Its value is NT. |
RC | Used in the %.res : %.rc rule, the name of the resource compiler. The default value is rc, the name of the Microsoft Resource Compiler. |
SHELLCOMMANDS | Alphabetical list of commands known to need execution by the shell program. If you define this macro, omake uses it to detect when to use the shell program. This macro is not defined initially; omake uses an internal list of commands. See Auto-Detection Mode. |
SHELLSUFFIX | Suffix used by omake for the batch files it generates. The default value is .bat. |
Through emulation, omake supports all PM/CB and NMAKE macros.
Feedback on the documentation in this site? We welcome any comments!
Copyright © 2001 by Rational Software Corporation. All rights reserved. |