📄 wmake.gml
字号:
.autopoint
.point
.ix '&makcmdup options' 's'
use the command line option "s"
.point
put an "@" in front of specific commands, or
.point
use the
.id &sysper.SILENT
directive.
.endpoint
.np
In the following example, the rule:
.millust begin
#
# silent command example
#
balance summary : ledger.dat sales.dat purchase.dat
@doreport
.millust end
.pc
will prevent the string "doreport" from being printed on the
screen before the command is executed.
.np
The
.id &sysper.SILENT
directive is used as follows:
.millust begin
#
# .SILENT example
#
&sysper.SILENT
balance summary : ledger.dat sales.dat purchase.dat
doreport
.millust end
.pc
Using the
.id &sysper.SILENT
directive or the "s" command line option will inhibit the printing of
all commands before they are executed.
The "sn" command line option can be used to veto any silencing control.
.np
At this point, most of the capability of &maksname may be realized.
Methods for making makefiles more succinct will be discussed.
.*
.section Defining Recognized File Extensions (.SUFFIXES)
.*
.ix '&makcmdup directives' '.SUFFIXES'
.ix 'SUFFIXES' '&makcmdup directive'
The
.id &sysper.SUFFIXES
directive declares which extensions are allowed to be used in implicit
rules and how these extensions are ordered. It is a synonym for the
.id &sysper.EXTENSIONS
directive. See the section entitled
:HDREF refid='extensions'.
for a full description of both directives.
.*
.section Targets Without Any Dependents (.SYMBOLIC)
.*
.np
.ix '&makcmdup directives' '.SYMBOLIC'
.ix 'SYMBOLIC' '&makcmdup directive'
There must always be at least one target in a rule but it is not
necessary to have any dependents.
If a target does not have any dependents, the command list associated
with the rule will always be executed if the target is updated.
.np
You might ask, "What may a rule with no dependents be used for?".
A rule with no dependents may be used to describe actions that are
useful for the group of files being maintained.
Possible uses include backing up files, cleaning up files, or printing
files.
.np
To illustrate the use of the
.id &sysper.SYMBOLIC
directive, we will add two new rules to the previous example.
First, we will omit the
.id &sysper.SYMBOLIC
directive and observe what will happen when it is not present.
.millust begin
#
# rule 4: backup the data files
#
backup :
echo "insert backup disk"
pause
copy *.dat a:
echo "backup complete"
.millust break
#
# rule 5: cleanup temporary files
#
cleanup :
del *.tmp
del \tmp\*.*
.millust end
.pc
and then execute the command:
.millust begin
&makcmd backup
.millust end
.pc
&maksname will execute the command list associated with the "backup"
target and issue an error message indicating that the file "BACKUP"
does not exist after the command list was executed.
The same thing would happen if we typed:
.millust begin
&makcmd cleanup
.millust end
.pc
In this makefile we are using "backup" and "cleanup" to represent
actions we want performed.
The names are not real files but rather they are symbolic names.
This special type of target may be declared with the
.id &sysper.SYMBOLIC
directive.
This time, we show rules 4 and 5 with the appropriate addition of
.id &sysper.SYMBOLIC
directives.
.millust begin
#
# rule 4: backup the data files
#
backup : .SYMBOLIC
echo "insert backup disk"
pause
copy *.dat a:
echo "backup complete"
.millust break
#
# rule 5: cleanup temporary files
#
cleanup : .SYMBOLIC
del *.tmp
del \tmp\*.*
.millust end
.pc
The use of the
.id &sysper.SYMBOLIC
directive indicates to &maksname that the target should always be
updated internally after the command list associated with the rule has
been executed.
A short form for the common idiom of singular
.id &sysper.SYMBOLIC
targets like:
.millust begin
target : .SYMBOLIC
commands
.millust end
.pc
is:
.millust begin
target
commands
.millust end
.pc
This kind of target definition is useful for many types of management
tasks that can be described in a makefile.
.*
.section Macros
.*
.np
.ix '&makcmdup' 'macros'
.ix 'macros'
&makname has a simple macro facility that may be used to improve
makefiles by making them easier to read and maintain.
.ix '&makcmdup' 'macro identifier'
A macro identifier may be composed from a string of alphabetic
characters and numeric characters.
The underscore character is also allowed in a macro identifier.
If the macro identifier starts with a "%" character, the macro
identifier represents an environment variable.
For instance, the macro identifier "%path" represents the environment
variable "path".
.begpoint $compact $setptnt 16
:DTHD.Macro identifiers
:DDHD.Valid?
.point 2morrow
yes
.point stitch_in_9
yes
.point invalid~~id
no
.point 2b_or_not_2b
yes
.point %path
yes
.point reports
yes
.point !@#*%
no
.endpoint
.np
We will use a programming example to show how macros are used.
The programming example involves four &lang source files and two
&header files.
Here is the initial makefile (before macros):
.millust begin
#
# programming example
# (before macros)
#
plot&exe : main.obj input.obj calc.obj output.obj
&lnkcmd @plot
main.obj : main.&langsuff defs.&hdrsuff globals.&hdrsuff
&compcmd main &compopt &warnopt
calc.obj : calc.&langsuff defs.&hdrsuff globals.&hdrsuff
&compcmd calc &compopt &warnopt
.millust break
input.obj : input.&langsuff defs.&hdrsuff globals.&hdrsuff
&compcmd input &compopt &warnopt
output.obj : output.&langsuff defs.&hdrsuff globals.&hdrsuff
&compcmd output &compopt &warnopt
.millust end
.np
Macros become useful when changes must be made to makefiles.
If the programmer wanted to change the compiler options for the
different compiles, the programmer would have to make a global
change to the makefile.
With this simple example, it is quite easy to make the change but try
to imagine a more complex example with different programs having
similar options.
The global change made by the editor could cause problems by changing
the options for other programs.
A good habit to develop is to define macros for any programs that have
command line options.
In our example, we would change the makefile to be:
.millust begin
#
# programming example
# (after macros)
#
link_options =
compiler = &compcmd
compile_options = &compopt &warnopt
plot&exe : main.obj input.obj calc.obj output.obj
&lnkcmd $(link_options) @plot
main.obj : main.&langsuff defs.&hdrsuff globals.&hdrsuff
$(compiler) main $(compile_options)
.millust break
calc.obj : calc.&langsuff defs.&hdrsuff globals.&hdrsuff
$(compiler) calc $(compile_options)
input.obj : input.&langsuff defs.&hdrsuff globals.&hdrsuff
$(compiler) input $(compile_options)
output.obj : output.&langsuff defs.&hdrsuff globals.&hdrsuff
$(compiler) output $(compile_options)
.millust end
.pc
A macro definition consists of a macro identifier starting on the
beginning of the line followed by an "=" which in turn is followed by
the text to be replaced.
A macro may be redefined, with the latest declaration being used for
subsequent expansions (no warning is given upon redefinition of a
macro).
The replacement text may contain macro references.
.np
A macro reference may occur in two forms.
The previous example illustrates one way to reference macros whereby
the macro identifier is delimited by "$(" and ")".
The parentheses are optional so the macros "compiler" and
"compile_options" could be referenced by:
.millust begin
main.obj : main.&langsuff defs.&hdrsuff globals.&hdrsuff
$compiler main $compile_options
.millust end
.pc
Certain ambiguities may arise with this form of macro reference.
For instance, examine this makefile fragment:
.exam begin
temporary_dir = \tmp\
temporary_file = $temporary_dirtmp000.tmp
.exam end
.pc
The intention of the declarations is to have a macro that will expand
into a file specification for a temporary file.
&maksname will collect the largest identifier possible before macro
expansion occurs.
The macro reference is followed by text that looks like part of the
macro identifier ("tmp000") so the macro identifier that will be
referenced will be "temporary_dirtmp000".
The incorrect macro identifier will not be defined so an error message
will be issued.
.np
If the makefile fragment was:
.millust begin
temporary_dir = \tmp\
temporary_file = $(temporary_dir)tmp000.tmp
.millust end
.pc
there would be no ambiguity.
The preferred way to reference macros is to enclose the macro
identifier by "$(" and ")".
.np
Macro references are expanded immediately on dependency lines (and
thus may not contain references to macros that have not been defined)
but other macro references have their expansion deferred until they
are used in a command.
In the previous example, the macros "link_options", "compiler", and
"compile_options" will not be expanded until the commands that
reference them are executed.
.np
Another use for macros is to replace large amounts of text with a much
smaller macro reference.
In our example, we only have two &header files but suppose we had very
many &header files.
Each explicit rule would be very large and difficult to read and
maintain.
We will use the previous example makefile to illustrate this use of
macros.
.millust begin
#
# programming example
# (with more macros)
#
link_options =
compiler = &compcmd
compile_options = &compopt &warnopt
&header._files = defs.&hdrsuff globals.&hdrsuff
object_files = main.obj input.obj calc.obj &
output.obj
.millust break
plot&exe : $(object_files)
&lnkcmd $(link_options) @plot
main.obj : main.&langsuff $(&header._files)
$(compiler) main $(compile_options)
.millust break
calc.obj : calc.&langsuff $(&header._files)
$(compiler) calc $(compile_options)
input.obj : input.&langsuff $(&header._files)
$(compiler) input $(compile_options)
output.obj : output.&langsuff $(&header._files)
$(compiler) output $(compile_options)
.millust end
.pc
Notice the ampersand ("&") at the end of the macro definition for
"object_files".
The ampersand indicates that the macro definition continues on the
next line.
.ix '&makcmdup' 'line continuation'
.ix 'line continuation'
In general, if you want to continue a line in a makefile, use an
ampersand ("&") at the end of the line.
.np
There are special macros provided by &maksname to access
environment variable names.
.ix '&makcmdup' 'environment variables'
.ix 'environment variables'
.ix '&makcmdup special macros' '$(%path)'
.ix '&makcmdup special macros' '$(%<environment_var>)'
To access the
.ev PATH
environment variable in a makefile, we use the macro identifier
"%path".
For example, if we have the following line in a command list:
.exam begin
echo $(%path)
.exam end
.pc
it will print out the current value of the
.ev PATH
environment variable when it is executed.
.np
There are two other special environment macros that are predefined by
&maksname..
.ix '&makcmdup special macros' '$(%cdrive)'
The macro identifier "%cdrive" will expand into one letter
representing the current drive. Note that it is operating system
dependent whether the cd command changes the current drive.
.ix '&makcmdup special macros' '$(%cwd)'
The macro identifier "%cwd" will expand into the current working
directory.
These macro identifiers are not very useful unless we can specify that
they be expanded immediately.
.ix '&makcmdup special macros' '$+'
.ix '&makcmdup special macros' '$-'
The complementary macros "$+" and "$&minus." respectively turn on and
turn off immediate expansion of macros.
The scope of the "$+" macro is the current line after which the
default macro expansion behaviour is resumed.
A possible use of these macros is illustrated by the following example
makefile.
.ix '&makcmdup special macros' '$(%cdrive)'
.ix '&makcmdup special macros' '$(%cwd)'
.ix '&makcmdup special macros' '$+'
.ix '&makcmdup special macros' '$-'
.ix '&makcmdup directives' '.SYMBOLIC'
.ix 'SYMBOLIC' '&makcmdup directive'
.millust begin
#
# $(%cdrive), $(%cwd), $+, and $- example
#
dir1 = $(%cdrive):$(%cwd)
dir2 = $+ $(dir1) $-
example : .SYMBOLIC
cd ..
echo $(dir1)
echo $(dir2)
.millust end
.pc
Which would produce the following output if the current working
directory is
C:&pathnamup.\SOURCE\EXAMPLE:
.exam begin
(command output only)
C:&pathnamup.\SOURCE
C:&pathnamup.\SOURCE\EXAMPLE
.exam end
.pc
The macro definition for "dir2" forces immediate expansion of the
"%cdrive" and "%cwd" macros thus defining "dir2" to be the current
directory that &maksname was invoked in.
The macro "dir1" is not expanded until execution time when the current
directory has changed from the initial directory.
.np
Combining the $+ and $&minus. special macros with the special macro
identifiers "%cdrive" and "%cwd" is a useful makefile technique.
The $+ and $&minus. spec
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -