123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751 |
- .HTML "Plan 9 Mkfiles
- .TL
- Plan 9 Mkfiles
- .AU
- Bob Flandrena
- bobf@plan9.bell-labs.com
- .SH
- Introduction
- .LP
- Every Plan 9 source directory contains a file, called
- .CW mkfile ,
- specifying the rules for building the executable or
- library that is the product of the directory.
- .I Mk (1)
- interprets the rules in the file, calculates
- the dependencies, and executes an
- .I rc (1)
- script to construct the product.
- If necessary components are supplied by
- neighboring directories or sub-directories, the mkfiles in those
- directories are first executed to build the components
- before the local construction proceeds.
- .LP
- Most application source directories produce one of
- four types of product:
- a single executable, several
- executables, a local library, or
- a system library.
- Four generic
- mkfiles
- define the normal rules
- for building each type of product. The simplest
- mkfiles need only
- list the components
- and include the appropriate
- generic
- mkfile
- to do the work.
- More complex
- mkfiles
- may supply additional rules
- to augment, modify, or override the generic rules.
- .SH
- Using a Mkfile
- .LP
- To build a product, change to the directory containing
- its source and invoke
- .I mk
- with the appropriate target as an argument.
- All mkfiles provide the following standard targets:
- .TS
- lw(1i) lw(4.5i).
- \f(CWall\fP T{
- Build a local version of the product or products for the
- current architecture. If the product is a single program,
- the result is stored in file
- .CW $O.out .
- If the directory produces multiple executables, they are
- stored in the files named
- .CW $O.\fIprogname,\fP
- where
- .I progname
- is the name of each executable.
- A product may be built for a different architecture by
- prefacing the
- .CW mk
- command with
- \f(CWobjtype=\fP\fIarchitecture\fP,
- where
- .I architecture
- is the name of the target architecture.
- Directories producing system
- libraries always operate directly on the installed version of the
- library; in this case the target
- .CW all
- is equivalent to the target
- .CW install .
- T}
- \f(CWinstall\fP T{
- Build and install the product or products for the current
- architecture.
- T}
- \f(CWinstallall\fP T{
- Build and install the product or products for all architectures.
- T}
- \f(CWclean\fP T{
- Rid the directory and its subdirectories of the by-products of
- the build process. Intermediate files that are easily reproduced
- (e.g., object files,
- .CW yacc
- intermediates, target executables) are always
- removed. Complicated intermediates, such as local libraries, are
- usually preserved.
- T}
- \f(CWnuke\fP T{
- Remove all intermediates from the directory and any subdirectories.
- This target guarantees that a subsequent build for the
- architecture is performed
- from scratch.
- T}
- .TE
- .LP
- If no target is specified on the
- .CW mk
- command line, the
- .CW all
- target is built by default. In a directory
- producing multiple executables, there is
- no default target.
- .LP
- In addition to the five standard targets,
- additional targets may be supplied by each
- generic mkfile or by the directory's mkfile.
- .LP
- The environment variable
- .CW NPROC
- is set by the system to the number of
- available processors.
- Setting
- this variable, either in the environment or in
- a mkfile, controls the amount of parallelism in
- the build. For example, the command
- .P1
- NPROC=1 mk
- .P2
- restricts a build to a single thread of execution.
- .SH
- Creating a Mkfile
- .LP
- The easiest way to build a new mkfile is to copy and modify
- an existing mkfile of the same type.
- Failing that, it is usually possible to create a new
- mkfile with minimal effort, since the appropriate
- generic mkfile predefines the rules that do all the work.
- In the simplest and most common cases, the new mkfile
- need only define a couple of variables and include the appropriate
- architecture-specific
- and generic mkfiles.
- .SH The Generic Mkfiles
- .LP
- There are four generic mkfiles containing commonly
- used rules for building a product:
- .CW mkone ,
- .CW mkmany ,
- .CW mklib ,
- and
- .CW mksyslib .
- These rules
- perform such actions as compiling C source files,
- loading object files, archiving libraries, and
- installing executables in the
- .CW bin
- directory of the appropriate architecture.
- The generic mkfiles are stored in directory
- .CW /sys/src/cmd .
- Mkfile
- .CW mkone
- builds a single executable,
- .CW mkmany
- builds several executables from the source in a single
- directory, and
- .CW mklib
- and
- \f(CWmksyslib\fP,
- maintain local and system libraries, respectively.
- The rules in the generic mkfiles are driven by
- the values of variables, some of which must be
- set by the product mkfile and some of which are
- supplied by the generic mkfile. Variables in the
- latter class include:
- .TS
- center;
- ri ci li
- rw(1i) cw(0.5i) lw(2i).
- Variable Default Meaning
- .sp .5
- \f(CWCFLAGS\fP \f(CW-FVw\fP C compiler flags
- \f(CWLDFLAGS\fP Loader flags
- \f(CWYFLAGS\fP \f(CW-d\fP Yacc flags
- \f(CWAFLAGS\fP Assembler flags
- .TE
- .LP
- The following variables are set by the product mkfile
- and used by the generic mkfile.
- Any may be empty depending on the specific product being
- made.
- .TS
- center;
- lw(1i) lw(2.5i).
- \f(CWTARG\fP Name(s) of the executable(s) to be built
- \f(CWLIB\fP Library name(s)
- \f(CWOFILES\fP Object files
- \f(CWHFILES\fP Header files included by all source files
- \f(CWYFILES\fP \f(CWYacc\fP input files
- \f(CWBIN\fP Directory where executables are installed
- .TE
- .SH
- Mkfile Organization
- .LP
- All
- mkfiles
- share the following common structure:
- .P1
- </$objtype/mkfile # \f1architecture-dependent definitions\fP
- .sp
- \fIvariable definitions\fP # TARG\f1, \fPOFILES\f1, \fPHFILES\f1, etc.\fP
- .sp
- </sys/src/cmd/\fIgeneric\fP # mkone\f1, \fPmkmany\f1, \fPmklib\f1, or \fPmksyslib
- .sp
- \fIvariable overrides\fP # CFLAGS\f1, \fPobjtype\f1, etc.\fP
- .sp
- \fIextra rules\fP # \f1overrides, augmented rules, additional targets\fP
- .P2
- Note that the architecture-dependent mkfiles include file
- .CW /sys/src/mkfile.proto
- for system-wide variables that are common to all architectures.
- .LP
- The variables driving the expansion of the generic mkfile
- may be specified in any order as long as they are defined
- before the inclusion of the generic mkfile. The value
- of a variable may be changed by assigning a new value
- following the inclusion of the generic mkfile, but the
- effects are sometimes counter-intuitive.
- Such variable assignments do not apply to the target and
- prerequisite portions of any previously defined rules;
- the new values only apply to the recipes of rules preceding
- the assignment statement and
- to all parts of any rules following it.
- .LP
- The rules supplied by the generic mkfile may
- be overridden or augmented. The new rules must
- be specified after the inclusion of the generic
- mkfile. If the target and prerequisite portion
- of the rule exactly match the target and prerequisite
- portion of a previously defined rule and the new rule contains
- a recipe, the new rule replaces the old one.
- If the target of a new rule exactly matches the
- target of a previous rule and one or more new
- prerequisites are specified and the new rule contains
- no recipe, the new prerequisites are added to the prerequisites
- of the old rule.
- .LP
- Following sections discuss
- each generic mkfile in detail.
- .SH
- Mkone
- .LP
- The
- .CW mkone
- generic mkfile contains rules for building
- a single executable from one or more files
- in a directory.
- The variable
- .CW TARG
- specifies the name of the executable and
- variables
- .CW OFILES
- and
- .CW YFILES
- specify the object files and
- .CW yacc
- source files used to build it.
- .CW HFILES
- contains the names of the local header files
- included in all source files.
- .CW BIN
- is the name of the directory where the executable
- is installed.
- .CW LIB
- contains the names of local libraries used by the
- linker. This variable is rarely needed
- as libraries referenced by a
- .CW #pragma
- directive in an associated header file, including
- all system libraries, are automatically
- searched by the loader.
- .LP
- If
- .CW mk
- is executed without a target, the
- .CW all
- target is built; it
- produces an executable in
- .CW $O.out .
- Variable
- .CW HFILES
- identifies the header files that
- are included in all or most or
- the C source files. Occasionally,
- a program has other header files
- that are only used in some
- source files. A
- header can be added to the prerequisites for
- those object files by adding a rule of
- the following form following the inclusion of generic mkfile
- .CW mkone :
- .P1
- file.$O: header.h
- .P2
- .LP
- The mkfile for a directory producing a single
- executable using the normal set of rules is
- trivial: a list of some files followed by the
- inclusion of
- .I mkone.
- For example,
- .CW /sys/src/cmd/diff/mkfile
- contains:
- .P1
- < /$objtype/mkfile
- TARG=diff
- OFILES=\e
- diffdir.$O\e
- diffio.$O\e
- diffreg.$O\e
- main.$O\e
- HFILES=diff.h
- BIN=/$objtype/bin
- </sys/src/cmd/mkone
- .P2
- The more complex mkfile in
- .CW /sys/src/cmd/awk
- overrides compiler and loader variables to
- select the ANSI/POSIX Computing Environment with appropriately
- defined command line variables. It also overrides
- the default
- .CW yacc
- rule to place the output soure in file
- .CW awkgram.c
- and the
- .CW clean
- and
- .CW nuke
- rules, so it can remove the non-standard intermediate
- files. Finally, the last three rules build a version of
- .CW maketab
- appropriate for the architecture where the
- .CW mk
- is being
- run and then executes it to create source file
- .CW proctab.c :
- .P1
- </$objtype/mkfile
- TARG=awk
- OFILES=re.$O\e
- lex.$O\e
- main.$O\e
- parse.$O\e
- proctab.$O\e
- tran.$O\e
- lib.$O\e
- run.$O\e
- awkgram.$O\e
- HFILES=awk.h\e
- y.tab.h\e
- proto.h\e
- YFILES=awkgram.y
- BIN=/$objtype/bin
- </sys/src/cmd/mkone
- CFLAGS=-c -D_REGEXP_EXTENSION -D_RESEARCH_SOURCE \e
- -D_BSD_EXTENSION -DUTF
- YFLAGS=-S -d -v
- CC=pcc
- LD=pcc
- cpuobjtype=`{sed -n 's/^O=//p' /$cputype/mkfile}
- y.tab.h awkgram.c: $YFILES
- $YACC -o awkgram.c $YFLAGS $prereq
- clean:V:
- rm -f *.[$OS] [$OS].out [$OS].maketab y.tab.? y.debug\e
- y.output $TARG
- nuke:V:
- rm -f *.[$OS] [$OS].out [$OS].maketab y.tab.? y.debug\e
- y.output awkgram.c $TARG
- proctab.c: $cpuobjtype.maketab
- ./$cpuobjtype.maketab >proctab.c
- $cpuobjtype.maketab: y.tab.h maketab.c
- objtype=$cputype
- mk maketab.$cputype
- maketab.$cputype:V: y.tab.h maketab.$O
- $LD -o $O.maketab maketab.$O
- .P2
- .SH
- Mkmany
- .LP
- The
- .CW mkmany
- generic mkfile builds several
- executables from the files in a
- directory. It differs from the operation of
- .CW mkone
- in three respects:
- .CW TARG
- specifies the names of all executables,
- there is no default command-line target,
- and additional rules allow a single executable to
- be built or installed.
- .LP
- The
- .CW TARG
- variable specifies the names of all
- executables produced by the mkfile. The
- rules assume the name of each executable is also
- the name of the file containing its
- .CW main
- function.
- .CW OFILES
- specifies files containing
- common subroutines loaded with all executables.
- Consider the mkfile:
- .P1
- </$objtype/mkfile
- TARG=alpha beta
- OFILES=common.$O
- BIN=/$objtype/bin
- </sys/src/cmd/mkmany
- .P2
- It assumes the main functions for executables
- .CW alpha
- and
- .CW beta
- are in files
- .CW alpha.$O
- and
- .CW beta.$O
- and that both programs use the subroutines
- in file
- .CW common.$O .
- The
- .CW all
- target builds all executables, leaving each in
- a file with a name of the form
- .CW $O.\fIprogname\fP
- where
- .I progname
- is the name of the executable. In this
- example the
- .CW all
- target produces executables
- .CW $O.alpha
- and
- .CW $O.beta .
- .LP
- The
- .CW mkmany
- rules provide additional
- targets for building a single
- executable:
- .TS
- lw(1i) lw(3.8i).
- \f(CW$O.progname\fP T{
- Builds executable
- \f(CW$O.\fP\fIprogname\fP
- in the current directory. When the target
- architecture is not the current architecture
- the
- .CW mk
- command
- must be prefixed with the customary
- .CW objtype=\fIarchitecture\fP
- assignment to select the proper compilers and loaders.
- T}
- \f(CWprogname.install\fP T{
- Installs executable
- .I progname
- for the target architecture.
- T}
- \f(CWprogname.installall\fP T{
- Installs executable
- .I progname
- for all architectures.
- T}
- .TE
- .SH
- Mklib
- .LP
- The
- .CW mklib
- generic mkfile builds a local library.
- Since this form of mkfile constructs no
- executable, the
- .CW TARG
- and
- .CW BIN
- variables are not needed. Instead, the
- .CW LIB
- variable specifies the library
- to be built or updated. Variable
- .CW OFILES
- contains the names of the object files to be archived
- in the library. The use of variables
- .CW YFILES
- and
- .CW HFILES
- does not change. When possible, only the
- out-of-date members of the library are updated.
- .LP
- The variable
- .CW LIBDIR
- contains the name of the directory where the
- library is installed; by default it selects
- the current directory. It can be overridden
- by assigning the new directory name after the
- point where
- .CW mklib
- is included.
- .LP
- The
- .CW clean
- target removes object files and
- .CW yacc
- intermediate files but does not touch the
- library. The
- .CW nuke
- target removes the library as well as the
- files removed by the
- .CW clean
- target. The command
- .RS
- .CW "mk -s clean all"
- .RE
- causes the existing library to be updated, or
- created if it doesn't already exist. The command
- .RS
- .CW "mk -s nuke all"
- .RE
- forces the library to be rebuilt from scratch.
- .LP
- The mkfile from
- .CW /sys/src/cmd/upas/libString
- contains the following specifications to
- build the local library
- .CW libString.a$O
- for the object architecture referenced by
- .CW $O\fR\:\fP
- .P1
- </$objtype/mkfile
- LIB=libString.a$O
- OFILES= s_alloc.$O\e
- s_append.$O\e
- s_array.$O\e
- s_copy.$O\e
- s_getline.$O\e
- s_grow.$O\e
- s_nappend.$O\e
- s_parse.$O\e
- s_read.$O\e
- s_read_line.$O\e
- s_tolower.$O\e
- </sys/src/cmd/mklib
- nuke:V:
- mk clean
- rm -f libString.a[$OS]
- .P2
- The override of the rule for target
- .CW nuke
- removes the libraries for all architectures as
- opposed to the default recipe for this target
- which removes the library for the current architecture.
- .SH
- Mksyslib
- .LP
- The
- .CW mksyslib
- generic mkfile is similar to the
- .CW mklib
- mkfile except that it operates on a system library
- instead of a local library.
- The
- .CW install
- and
- .CW all
- targets are the same; since there is no local copy of
- the library, all updates are performed on the
- installed library.
- The rule for the
- .CW nuke
- target is identical to that of the
- .CW clean
- target; unlike the
- .CW nuke
- target for local libraries,
- the library is never removed.
- .LP
- No attempt is made to determine if individual library
- members are up-to-date; all members of a
- library are always updated.
- Special targets support manipulation of a single
- object file; the target
- .CW objfile
- updates file
- .CW objfile\f(CW.$O\fP
- in the library of the current architecture and the target
- .CW objfile.all
- updates
- .CW objfile\f(CW.$O\fP
- in the libraries of all architectures.
- .SH
- Overrides
- .LP
- The rules provided by a generic mkfile or
- the variables used to control the evaluation
- of those rules may be overridden in most
- circumstances. Overrides
- must be specified in the product mkfile
- after the point where the generic
- mkfile is included; in general, variable
- and rule overrides occupy the end of a
- product mkfile.
- .LP
- The value of a variable is overridden by
- assigning a new value to the variable.
- Most variable overrides modify the
- values of flags or the names of commands executed
- in recipes. For example, the default value of
- .CW CFLAGS
- is often overridden or augmented and
- the ANSI/POSIX Computing Environment is selected by
- setting the
- .CW CC
- and
- .CW LD
- variables to
- .CW pcc.
- .LP
- Modifying rules is trickier than modifying
- variables. Additional constraints can be added
- to a rule by specifying the target and
- the new prerequisite. For example,
- .P1
- %.$O: header.h
- .P2
- adds file
- .CW header.h
- the set of prerequisites for all object files.
- There is no mechanism for adding additional
- commands to an existing recipe; if a
- recipe is unsatisfactory, the rule and its recipe
- must be completely overridden.
- A rule is overridden only when the replacement rule
- matches the target and prerequisite portions
- of the original rule exactly. The recipe
- associated with the new rule
- then replaces the recipe of the original rule.
- For example,
- .CW /sys/src/cmd/lex/mkfile
- overrides the default
- .CW installall
- rule to perform the normal loop on all
- architectures and then copy a prototype file
- to the system library directory.
- .P1
- </$objtype/mkfile
- TARG=lex
- OFILES=lmain.$O\e
- y.tab.$O\e
- sub1.$O\e
- sub2.$O\e
- header.$O\e
- HFILES=ldefs.h\e
- YFILES=parser.y\e
- BIN=/$objtype/bin
- </sys/src/cmd/mkone
- installall:V:
- for(objtype in $CPUS)
- mk install
- cp ncform /sys/lib/lex
- .P2
- Another way to perform the same override is to
- add a dependency to the default
- .CW installall
- rule that executes an additional rule to
- install the prototype file:
- .P1
- installall:V: ncform.install
- ncform.install:V:
- cp ncform /sys/lib/lex
- .P2
- .SH
- Special Tricks
- .LP
- Two special cases
- require extra deviousness.
- .LP
- In the first, a file needed to build an
- executable is generated by a program that,
- in turn, is built from a source file that
- is not part of the product. In this case,
- the
- executable must be built for the
- target architecture, but the intermediate
- executable must be built for the architecture
- .CW mk
- is executing on. The intermediate executable
- is built by recursively invoking
- .CW mk
- with the appropriate target and the
- executing architecture as the target
- architecture. When that
- .CW mk
- completes, the intermediate is
- executed to generate the source file to
- complete the build for the target architecture.
- The earlier example of
- .CW /sys/src/cmd/awk/mkfile
- illustrates this technique.
- .LP
- Another awkward situation
- occurs when a directory contains
- source to build an executable as
- well as source for auxiliary executables
- that are not to be installed. In this case
- the
- .CW mkmany
- generic rules are inappropriate, because
- all executables would be built and installed.
- Instead, use the
- .CW mkone
- generic file to build the primary executable
- and provide extra targets to
- build the auxiliary files. This
- approach is also useful when the auxiliary
- files are not executables;
- .CW /sys/src/cmd/spell/mkfile
- augments the default rules to build and install the
- .CW spell
- executable with
- elaborate rules to generate
- and maintain the auxiliary spelling lists.
|