This is Release 2.0 of jam, a make-like program.
Jam recursively builds target files from their source files, using
two files to define the dependency graph and the updating actions for
all targets. The file Jambase (usually located in /usr/local/lib)
defines rules, and the file Jamfile (located in the current directory)
lists the targets and sources in terms of those rules. Jam does not
need to rely on suffix-driven implicit rules or directory contents.
A Jambase is provided with jam; the user supplies the Jamfile.
Jambase contains a set of jam rule definitions that provide roughly
make(1)-like functionality. Jam reads Jambase, which in turn
includes the Jamfile from the current directory.
FEATURES
-> Jam is a make(1) replacement that makes building simple things
simple and building complicated things manageable.
-> Jam's language is expressive, making Jamfiles (c.f. Makefiles)
compact. Here's a sample:
Main smail : main.c map.c resolve.c deliver.c
misc.c parser.y alias.c pw.c headers.c
scanner.l getpath.c str.c ;
This builds "smail" from a dozen source files. Jam handles
header file dependencies automatically and on-the-fly.
-> Jam is very portable: it runs on UNIX, VMS, and NT. Most
Jamfiles themselves are portable, like the sample above.
-> Jam is unintrusive: it is small, it has negligible CPU
overhead, and it doesn't create any of its own funny files
(c.f. Odin, nmake, SunOS make).
-> Jam can build large projects spread across many directories
in one pass, without recursing, tracking the relationships
among all files. See the accompanying paper. On UNIX, jam
can do this with multiple, concurrent processes.
-> Jam isn't under the blinkin GNU copyright, so you can
incorporate it into commercial products.
Supplied documentation:
jam.1 Jam man page - a terse description.
jam.ps
Jambase.5 Reference for the rule boilerplate file.
Jambase.ps
Jamfile.5 Easy reading on creating a Jamfile and using jam.
Jamfile.ps
Paper.ps The 1994 UNIX Application Development Symposium paper
on jam (reflects Release 1 - see RELNOTES for diffs).
RELNOTES Release 2.0 release notes.
Porting Notes on porting jam to wildcat platforms.
README Includes installation instructions.
jam.c Contains jam's main() as well as an introduction to the
code, for serious hackers.
sei...@tea.org
--------------------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# Contents: README Paper.ps filent.c
# Wrapped by kent@ftp on Sat Mar 25 12:04:10 1995
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 1 (of 7)."'
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(3012 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
Xjam - make(1) redux
X
X /+\
X +\ Copyright 1993, 1995 Christopher Seiwald.
X \+/
X
X This is Release 2.0 of jam, a make-like program.
X The next release will be Release 2.1.
X
X License is hereby granted to use this software and distribute it
X freely, as long as this copyright notice is retained and modifications
X are clearly marked.
X
X ALL WARRANTIES ARE HEREBY DISCLAIMED.
X
X
XFEATURES
X
X -> Jam is a make(1) replacement that makes building simple things
X simple and building complicated things manageable.
X
X -> Jam's language is expressive, making Jamfiles (c.f. Makefiles)
X compact. Here's a sample:
X
X Main smail : main.c map.c resolve.c deliver.c
X misc.c parser.y alias.c pw.c headers.c
X scanner.l getpath.c str.c ;
X
X This builds "smail" from a dozen source files. Jam handles
X header file dependencies automatically and on-the-fly.
X
X -> Jam is very portable: it runs on UNIX, VMS, and NT. Most
X Jamfiles themselves are portable, like the sample above.
X
X -> Jam is unintrusive: it is small, it has negligible CPU
X overhead, and it doesn't create any of its own funny files
X (c.f. Odin, nmake, SunOS make).
X
X -> Jam can build large projects spread across many directories
X in one pass, without recursing, tracking the relationships
X among all files. See the accompanying paper. On UNIX, jam
X can do this with multiple, concurrent processes.
X
X -> Jam isn't under the blinkin GNU copyright, so you can
X incorporate it into commercial products.
X
X
XINFORMATION GUIDE
X
X jam.1 Jam man page - a terse description.
X jam.ps
X
X Jambase.5 Reference for the rule boilerplate file.
X Jambase.ps
X
X Jamfile.5 Easy reading on creating a Jamfile and using jam.
X Jamfile.ps
X
X Paper.ps The 1994 UNIX Application Development Symposium paper
X on jam (reflects Release 1 - see RELNOTES for diffs).
X
X RELNOTES Release 2.0 release notes.
X
X Porting Notes on porting jam to wildcat platforms.
X
X README This file. Includes installation instructions.
X
X jam.c Contains jam's main() as well as an introduction to the
X code, for serious hackers.
X
X
XINSTALLING
X
X Build jam with make(1) on:
X
X BSDI BSD/386 1.0
X COHERENT COHERENT/386
X DEC 3000/500 OSF/1
X DG AViiON DGUX 5.4
X HP 9000/700 HPUX 9.0
X IBM RS/6000 AIX *
X SGI R4000 IRIX 5.0
X Sequent 2000 PTX V2.1.0
X Sun 3 SunOS4.0
X Sun 4 Solaris 2 *+
X Sun 4 SunOS4.1
X VAX Ultrix 4.2
X
X IBM PC NT *
X
X * requires editing Makefile
X + only works with SUNSwpro CC (dirent confusion)
X
X Build jam with @build.com on:
X
X VAX VMS 5.4
X DEC 3000/500 OPENVMS *
X
X * requires editing build.com
X
X The Makefile (UNIX, NT) and build.com (VMS) are for bootstrapping.
X
X Once jam is built, read the Jamfile man page and give it a try.
X
X
XComments to the author!
X
XNovember, 1993 - release 1.0
XMarch, 1995 - release 2.0
X
X--- Christopher
Xsei...@tea.org
END_OF_FILE
if test 3012 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Paper.ps' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Paper.ps'\"
else
echo shar: Extracting \"'Paper.ps'\" \(70543 characters\)
sed "s/^X//" >'Paper.ps' <<'END_OF_FILE'
X%!PS-Adobe-3.0
X%%Creator: groff version 1.08
X%%DocumentNeededResources: font Times-Bold
X%%+ font Times-Roman
X%%+ font Times-Italic
X%%+ font Courier
X%%DocumentSuppliedResources: procset grops 1.08 0
X%%Pages: 10
X%%PageOrder: Ascend
X%%Orientation: Portrait
X%%EndComments
X%%BeginProlog
X%%BeginResource: procset grops 1.08 0
X/setpacking where{
Xpop
Xcurrentpacking
Xtrue setpacking
X}if
X/grops 120 dict dup begin
X/SC 32 def
X/A/show load def
X/B{0 SC 3 -1 roll widthshow}bind def
X/C{0 exch ashow}bind def
X/D{0 exch 0 SC 5 2 roll awidthshow}bind def
X/E{0 rmoveto show}bind def
X/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
X/G{0 rmoveto 0 exch ashow}bind def
X/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
X/I{0 exch rmoveto show}bind def
X/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
X/K{0 exch rmoveto 0 exch ashow}bind def
X/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
X/M{rmoveto show}bind def
X/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
X/O{rmoveto 0 exch ashow}bind def
X/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
X/Q{moveto show}bind def
X/R{moveto 0 SC 3 -1 roll widthshow}bind def
X/S{moveto 0 exch ashow}bind def
X/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
X/SF{
Xfindfont exch
X[exch dup 0 exch 0 exch neg 0 0]makefont
Xdup setfont
X[exch/setfont cvx]cvx bind def
X}bind def
X/MF{
Xfindfont
X[5 2 roll
X0 3 1 roll
Xneg 0 0]makefont
Xdup setfont
X[exch/setfont cvx]cvx bind def
X}bind def
X/level0 0 def
X/RES 0 def
X/PL 0 def
X/LS 0 def
X/PLG{
Xgsave newpath clippath pathbbox grestore
Xexch pop add exch pop
X}bind def
X/BP{
X/level0 save def
X1 setlinecap
X1 setlinejoin
X72 RES div dup scale
XLS{
X90 rotate
X}{
X0 PL translate
X}ifelse
X1 -1 scale
X}bind def
X/EP{
Xlevel0 restore
Xshowpage
X}bind def
X/DA{
Xnewpath arcn stroke
X}bind def
X/SN{
Xtransform
X.25 sub exch .25 sub exch
Xround .25 add exch round .25 add exch
Xitransform
X}bind def
X/DL{
XSN
Xmoveto
XSN
Xlineto stroke
X}bind def
X/DC{
Xnewpath 0 360 arc closepath
X}bind def
X/TM matrix def
X/DE{
XTM currentmatrix pop
Xtranslate scale newpath 0 0 .5 0 360 arc closepath
XTM setmatrix
X}bind def
X/RC/rcurveto load def
X/RL/rlineto load def
X/ST/stroke load def
X/MT/moveto load def
X/CL/closepath load def
X/FL{
Xcurrentgray exch setgray fill setgray
X}bind def
X/BL/fill load def
X/LW/setlinewidth load def
X/RE{
Xfindfont
Xdup maxlength 1 index/FontName known not{1 add}if dict begin
X{
X1 index/FID ne{def}{pop pop}ifelse
X}forall
X/Encoding exch def
Xdup/FontName exch def
Xcurrentdict end definefont pop
X}bind def
X/DEFS 0 def
X/EBEGIN{
Xmoveto
XDEFS begin
X}bind def
X/EEND/end load def
X/CNT 0 def
X/level1 0 def
X/PBEGIN{
X/level1 save def
Xtranslate
Xdiv 3 1 roll div exch scale
Xneg exch neg exch translate
X0 setgray
X0 setlinecap
X1 setlinewidth
X0 setlinejoin
X10 setmiterlimit
X[]0 setdash
X/setstrokeadjust where{
Xpop
Xfalse setstrokeadjust
X}if
X/setoverprint where{
Xpop
Xfalse setoverprint
X}if
Xnewpath
X/CNT countdictstack def
Xuserdict begin
X/showpage{}def
X}bind def
X/PEND{
Xclear
Xcountdictstack CNT sub{end}repeat
Xlevel1 restore
X}bind def
Xend def
X/setpacking where{
Xpop
Xsetpacking
X}if
X%%EndResource
X%%IncludeResource: font Times-Bold
X%%IncludeResource: font Times-Roman
X%%IncludeResource: font Times-Italic
X%%IncludeResource: font Courier
Xgrops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
X792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
X/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
X/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
X/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
X/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
X/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
X/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C
X/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash
X/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q
X/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
X/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
X/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
X/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
X/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
X/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
X/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
X/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
X/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
X/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
X/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
X/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
X/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
X/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
X/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
X/udieresis/yacute/thorn/ydieresis]def/Courier@0 ENC0/Courier RE/Times-Italic@0
XENC0/Times-Italic RE/Times-Roman@0 ENC0/Times-Roman RE/Times-Bold@0 ENC0
X/Times-Bold RE
X%%EndProlog
X%%Page: 1 1
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 14/Times-Bold@0 SF -.21(Ja)236.378 100.8 S 3.5(m\212M).21 G(ak)296.046
X100.8 Q(e\(1\) Redux)-.14 E/F1 12/Times-Roman@0 SF(Christopher Seiw)256.896
X148.8 Q(ald)-.12 E/F2 12/Times-Italic@0 SF(INGRES Corpor)253.92 163.2 Q(ation)
X-.18 E F1(Seiw)253.038 177.6 Q(a...@Ingres.Com)-.12 E(March 11, 1994)267.84 192
XQ/F3 11/Times-Roman@0 SF(Abstract)287.366 234 Q/F4 10/Times-Roman@0 SF .171
X(Despite the progress of UNIX, the basic mechanism by which de)110 250.2 R -.15
X(ve)-.25 G .17(lopers b).15 F .17(uild their programs \212)-.2 F/F5 10
X/Times-Italic@0 SF(mak)110 262.2 Q(e)-.1 E F4 .399
X(\(1\) \212 has remained at its core unimpro)B -.15(ve)-.15 G 2.899(ds).15 G
X.399(ince its inception.)312.192 262.2 R .4(Most notably)5.4 F 2.9(,t)-.65 G
X(he)450.21 262.2 Q F5(mak)2.9 E(e)-.1 E F4(lan-)2.9 E .147(guage has seen fe)
X110 274.2 R 2.647(wi)-.25 G(mpro)193.088 274.2 Q -.15(ve)-.15 G 2.647
X(ments. Jam).15 F .146(is a)2.647 F F5(mak)2.646 E(e)-.1 E F4 .146
X(replacement that uses an e)2.646 F .146(xtensible, e)-.15 F(xpressi)-.15 E
X-.15(ve)-.25 G .59(language for describing w)110 286.2 R .591
X(ays in which \214les relate.)-.1 F .591(This ne)5.591 F 3.091(wl)-.25 G .591
X(anguage simpli\214es the description)363.847 286.2 R .381
X(of systems, both small and lar)110 298.2 R .381(ge, and renders e)-.18 F .381
X(xtending Jam')-.15 F 2.881(sf)-.55 G .38(unctionality not only possible b)
X366.78 298.2 R(ut)-.2 E(easy)110 310.2 Q(.)-.65 E .958(Jam e)110 330.6 R .958
X(xists no)-.15 F 3.458(wa)-.25 G .958(nd runs on man)180.524 330.6 R 3.458(yU)
X-.15 G .958(NIX platforms, VMS, and NT)260.866 330.6 R 5.958(.I)-.74 G 3.458
X(ti)396.286 330.6 S 3.459(sf)405.304 330.6 S .959(reely a)415.983 330.6 R -.25
X(va)-.2 G .959(ilable in the).25 F .326(comp.sources.unix archi)110 342.6 R
X-.15(ve)-.25 G 2.826(s. As).15 F .325(proof of concept, it has been used to b)
X2.826 F .325(uild a v)-.2 F .325(ery lar)-.15 F .325(ge commer)-.18 F(-)-.2 E
X(cial product, generating in a single in)110 354.6 Q -.2(vo)-.4 G
X(cation 1,000 deli).2 E -.15(ve)-.25 G
X(rable \214les from 12,000 source \214les.).15 E/F6 11/Times-Bold@0 SF 2.75
X(1. Intr)90 382.8 R(oduction)-.198 E F4 1.016(The UNIX)90 399 R F5(mak)3.516 E
X(e)-.1 E F4 1.016(\(1\) program [Feldman, 1986], which automates the b)B 1.017
X(uilding of tar)-.2 F 1.017(gets from their source)-.18 F 1.033
X(\214les, is widely used.)90 411 R -.8(To)6.033 G 1.033
X(gether with its compatible successors \().8 F F5(dmak)A(e)-.1 E F4([V)3.533 E
X1.033(adura, 1990], GNU)-1.11 F F5(mak)3.532 E(e)-.1 E F4([Stall-)3.532 E 1.02
X(man, 1991], NET2)90 423 R F5(mak)3.52 E(e)-.1 E F4 1.021([BSD, 1991], SunOS)
X3.52 F F5(mak)3.521 E(e)-.1 E F4 1.021([Sun, 1989]\) and mutations \()3.521 F
XF5(cak)A(e)-.1 E F4 1.021([Somogyi, 1987],)3.521 F F5(cook)90 435 Q F4([Miller)
X2.835 E 2.835(,1)-.4 G(993],)149.98 435 Q F5(nmak)2.835 E(e)-.1 E F4([F)2.835 E
X-.25(ow)-.15 G(ler).25 E 2.835(,1)-.4 G .335(985], Plan 9)243.675 435 R F5(mk)
X2.834 E F4([Flandrena],)2.834 E F5(mms)2.834 E F4 .334(on VMS, etc.\),)2.834 F
XF5(mak)2.834 E(e)-.1 E F4(enjo)2.834 E .334(ys w)-.1 F(orld)-.1 E
X(domination in its capacity)90 447 Q(.)-.65 E(As)90 463.2 Q F5(mak)3.446 E(e)
X-.1 E F4 2.046 -.55('s a)D(uthor).55 E 3.446(,S)-.4 G .946
X(tuart Feldman, noted,)172.328 463.2 R F5(mak)3.446 E(e)-.1 E F4 .946
X(itself is not suited for describing huge programs.)3.446 F .947(This is)5.947
XF(ar)90 475.2 Q .013(guably because the)-.18 F F5(mak)2.513 E(e)-.1 E F4 .013
X(language has one useful statement: the e)2.513 F .012
X(xpression of a direct dependenc)-.15 F 2.512(ya)-.15 G(mong)499.22 475.2 Q
X2.667(\214les. This)90 487.2 R(mak)2.667 E .167(es for a clumsy)-.1 F 2.667(,b)
X-.65 G .168(ottom-up description of ho)222.742 487.2 R 2.668(wt)-.25 G 2.668
X(ob)342.604 487.2 S .168(uild a system \212 describing lar)355.072 487.2 R .168
X(ge systems)-.18 F .26(this w)90 499.2 R .26(ay is unmanageable.)-.1 F F5(mak)
X5.26 E(e)-.1 E F4 1.36 -.55('s s)D .26(uccessors try to o).55 F -.15(ve)-.15 G
X.26(rcome this dif).15 F .26(\214culty with sundry tricks:)-.25 F(dependen-)
X5.26 E .234(cies with wild-carded names matched ag)90 511.2 R .235
X(ainst directory contents; parsing command output as Mak)-.05 F .235
X(e\214le syn-)-.1 F(tax; macro e)90 523.2 Q
X(xpansions with and without the help of the C preprocessor)-.15 E 2.5(,e)-.4 G
X(tc.)381.35 523.2 Q .668(Jam is an attempt to replace)90 539.4 R F5(mak)3.168 E
X(e)-.1 E F4 1.768 -.55('s r)D .667
X(ule system, with its bottom-up language and w).55 F(ayw)-.1 E .667
X(ard implicit rules,)-.1 F .986(with an e)90 551.4 R(xpressi)-.15 E 1.286 -.15
X(ve l)-.25 H .986(anguage that mak).15 F .986(es it possible to describe e)-.1
XF .986(xplicitly and cogently the compilation of)-.15 F 2.819(programs. The)90
X563.4 R .319(current practice of b)2.819 F .319
X(uilding source simply because it matched wildcards is unreliable in the)-.2 F
X-.1(fa)90 575.4 S 1.211(ce of debris left around by a careless programmer).1 F
X6.211(.A)-.55 G(rob)324.72 575.4 Q 1.211(ust product should be b)-.2 F 1.212
X(uilt e)-.2 F(xplicitly)-.15 E 3.712(,a)-.65 G 1.212(nd to)500.508 575.4 R(mak)
X90 587.4 Q 2.5(et)-.1 G(his palatable, Jam mak)116.84 587.4 Q
X(es it easy to be e)-.1 E(xplicit.)-.15 E 2.5(At)90 603.6 S
X(ypical sample of Jam')102.5 603.6 Q 2.5(sl)-.55 G
X(anguage as seen by end-users will serv)199.16 603.6 Q 2.5(et)-.15 G 2.5(oa)
X363.69 603.6 S(nchor its description:)375.63 603.6 Q/F7 10/Courier@0 SF
X(MAIN prog : prog.c ;)130 619.8 Q(LIBS prog : libaux.a ;)130 631.8 Q
X(LIBRARY libaux.a : compile.c gram.y scan.c ;)130 643.8 Q F4 .489(This e)90
X664.2 R .489(xample in)-.15 F -.2(vo)-.4 G -.1(ke).2 G 2.989(st).1 G .489
X(hree rules that instruct Jam to b)183.667 664.2 R .488(uild an archi)-.2 F
X.788 -.15(ve f)-.25 H .488(rom three source \214les, to compile a).15 F .106
X(fourth source \214le, and to link it ag)90 676.2 R .107(ainst the archi)-.05 F
X-.15(ve)-.25 G 5.107(.A).15 G .107
X(ll three rules, as well as all other rules gi)306.973 676.2 R -.15(ve)-.25 G
X2.607(na).15 G 2.607(se)490.663 676.2 S(xam-)501.45 676.2 Q(ples in this paper)
X90 688.2 Q 2.5(,a)-.4 G(re stock ones that come with Jam \(see)167.09 688.2 Q
XF5 -.35(Ja)2.5 G(mbase).35 E F4(\(5\) [Seiw)A(ald, 1993]\).)-.1 E EP
X%%Page: 2 2
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 11/Times-Bold@0 SF 2.75(2. The)90 96 R -.165(Ja)2.75 G 2.75(mL).165 G
X(anguage)154.922 96 Q/F1 10/Times-Roman@0 SF .429(As with)90 112.2 R/F2 10
X/Times-Italic@0 SF(mak)2.929 E(e)-.1 E F1 2.929(,t)C .429
X(he most important statement in the Jam language is the e)153.957 112.2 R .428
X(xpression of a relationship among)-.15 F 3.416(\214les. W)90 124.2 R(ith)-.4 E
XF2(mak)3.416 E(e)-.1 E F1 3.416(,t)C .916
X(he relationship is a direct dependenc)167.798 124.2 R .916
X(y; with Jam, the relationship is user)-.15 F 3.416(-de\214ned. The)-.2 F -.15
X(ex)90 136.2 S(pression of such a relationship is:).15 E/F3 10/Courier@0 SF
X(<RULE> <targets> [ : <sources> ] ;)130 152.4 Q F1 .658
X(This statement is referred to as a rule in)90 172.8 R -.2(vo)-.4 G .658
X(cation, with the name of the rule leading the statement.).2 F(Except)5.657 E
X.328(for a handful of b)90 184.8 R .329
X(uilt-in rules, the de\214nition of a rule is user)-.2 F 2.829(-de\214ned. The)
X-.2 F .329(<sources> are optional.)2.829 F .329(Each of)5.329 F
X(the three lines in the e)90 196.8 Q(xample abo)-.15 E .3 -.15(ve a)-.15 H
X(re rule in).15 E -.2(vo)-.4 G(cations.).2 E 1.732(Because rules in)90 213 R
X-.2(vo)-.4 G 1.932 -.1(ke e).2 H 1.732(ach other).1 F 4.232(,t)-.4 G 1.731
X(he e)234.19 213 R 1.731(xpression of a user)-.15 F 1.731
X(-de\214ned relationship can result in other user)-.2 F(-)-.2 E .724
X(de\214ned relationships being made among the same or dif)90 225 R .725
X(ferent \214les.)-.25 F .725(In the case of the e)5.725 F .725(xample gi)-.15 F
X-.15(ve)-.25 G .725(n, the).15 F(MAIN rule will in)90 237 Q -.2(vo)-.4 G .2 -.1
X(ke t).2 H(he rules:).1 E F3(CC prog.o : prog.c ;)130 253.2 Q
X(LINK prog : prog.o ;)130 265.2 Q F1 .465(These rules \(presumably\) handle th\
Xe cases of compiling an object module from a C source \214le and linking)90
X285.6 R(that object module into an e)90 297.6 Q -.15(xe)-.15 G(cutable.).15 E
XF0 2.75(2.1. Rule)90 313.8 R(De\214nition)2.75 E F1 2.973(Ar)90 330 S .473
X(ule is de\214ned in tw)103.523 330 R 2.973(op)-.1 G .474
X(arts: the Jam statements to e)194.398 330 R -.15(xe)-.15 G .474
X(cute when the rule is in).15 F -.2(vo)-.4 G -.1(ke).2 G 2.974(d\().1 G .474
X(essentially a proce-)443.852 330 R .881(dure call\); and the actions \()90 342
XR F2(sh)A F1 .881(\(1\) commands\) to e)B -.15(xe)-.15 G .881
X(cute in order to update the tar).15 F .881(gets of the rule.)-.18 F 3.381(Ar)
X5.881 G(ule)509.78 342 Q(may ha)90 354 Q .3 -.15(ve a p)-.2 H
X(rocedure de\214nition, actions, or both.).15 E 2.5(Ar)90 370.2 S(ule')103.05
X370.2 Q 2.5(sp)-.55 G(rocedure de\214nition is gi)129.44 370.2 Q -.15(ve)-.25 G
X2.5(nw).15 G(ith:)248.47 370.2 Q F3(rule <RULE> { <statements> })130 386.4 Q F1
X.191(This statement causes <statements> to be interpreted by Jam whene)90 406.8
XR -.15(ve)-.25 G 2.692(r<).15 G -.4(RU)383.382 406.8 S .192(LE> is in).4 F -.2
X(vo)-.4 G -.1(ke).2 G 2.692(d. The).1 F(<tar)2.692 E(gets>)-.18 E 1.13
X(and <sources> gi)90 418.8 R -.15(ve)-.25 G 3.63(na).15 G 3.63(tr)182.86 418.8
XS 1.13(ule in)192.6 418.8 R -.2(vo)-.4 G 1.13(cation are a).2 F -.25(va)-.2 G
X1.13(ilable as the special v).25 F 1.13
X(ariables $\(<\) and $\(>\) in the <state-)-.25 F .571
X(ments> de\214ning the rule.)90 430.8 R .572(<statements> may be an)5.572 F
X3.072(yo)-.15 G 3.072(ft)309.104 430.8 S .572
X(he Jam statements listed in this document.)318.286 430.8 R(Carry-)5.572 E
X(ing on the CC e)90 442.8 Q(xample, a de\214nition for the CC rule might be:)
X-.15 E F3(rule CC)130 459 Q({)130 471 Q(DEPENDS $\(<\) : $\(>\) ;)166 483 Q(})
X130 495 Q F1 1.003
X(This particular rule de\214nition simply arranges for the tar)90 515.4 R 1.002
X(gets to depend on the sources, using the b)-.18 F(uilt-in)-.2 E
X(rule DEPENDS \(described belo)90 527.4 Q(w\).)-.25 E 2.5(Ar)90 543.6 S(ule')
X103.05 543.6 Q 2.5(su)-.55 G(pdating actions are gi)129.44 543.6 Q -.15(ve)-.25
XG 2.5(nw).15 G(ith:)239.02 543.6 Q F3(actions <RULE> { <string> })130 559.8 Q
XF1 .29(This causes the)90 580.2 R F2(sh)2.79 E F1 .291
X(script <string> to be associated with the <tar)2.79 F .291(gets> in an)-.18 F
X2.791(yi)-.15 G -1.9 -.4(nv o)401.267 580.2 T .291(cation of <R).4 F 2.791
X(ULE>. Later)-.4 F(,)-.4 E .367(if Jam determines that the <tar)90 592.2 R .367
X(gets> are out-of-date, it will pass <string> to)-.18 F F2(sh)2.867 E F1 .367
X(for e)2.867 F -.15(xe)-.15 G 2.867(cution. Jam).15 F -.15(ex)2.867 G(pands).15
XE .065($\(<\) and $\(>\) in <string>, b)90 604.2 R .065
X(ut $\(<\) and $\(>\) in this case refer to the <tar)-.2 F .065
X(gets> and <sources> after the)-.18 F 2.565(yh)-.15 G -2.25 -.2(av e)508.47
X604.2 T .258(been bound to real \214le path names \(see Binding, belo)90 616.2
XR 2.758(w\). Finishing)-.25 F .258(out the CC e)2.758 F .257
X(xample, a de\214nition of CC)-.15 F(actions w)90 628.2 Q(ould be:)-.1 E F3
X(actions CC)130 644.4 Q({)130 656.4 Q(cc -c $\(CCFLAGS\) -I$\(HDRS\) $\(>\))178
X668.4 Q(})130 680.4 Q EP
X%%Page: 3 3
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 11/Times-Bold@0 SF 2.75(2.2. Rule)90 96 R(Effects)2.75 E/F1 10
X/Times-Roman@0 SF .631(Rule in)90 112.2 R -.2(vo)-.4 G .631(cations ha).2 F
X.931 -.15(ve n)-.2 H 3.131(oo).15 G .632(utputs or return v)200.454 112.2 R
X.632(alues and, instead, do their job through three distinct types of)-.25 F
X(side-ef)90 124.2 Q 3.793(fects. The)-.25 F 1.293(\214rst is when a rule')3.793
XF 3.793(sp)-.55 G 1.293(rocedure in)258.491 124.2 R -.2(vo)-.4 G -.1(ke).2 G
X3.793(sb).1 G 1.292(uilt-in rules to modify the tar)336.267 124.2 R 1.292
X(get dependenc)-.18 F(y)-.15 E 2.628(graph. These)90 136.2 R -.2(bu)2.628 G
X.128(ilt-ins will be discussed shortly).2 F 5.129(.T)-.65 G .129
X(he second is when a rule')294.759 136.2 R 2.629(sp)-.55 G .129
X(rocedure sets v)407.733 136.2 R 2.629(ariables. The)-.25 F .156
X(third is the association of the updating actions with the tar)90 148.2 R .155
X(gets, which occurs whene)-.18 F -.15(ve)-.25 G 2.655(rar).15 G .155
X(ule with updating)451.69 148.2 R(actions is in)90 160.2 Q -.2(vo)-.4 G -.1(ke)
X.2 G(d.).1 E F0 2.75(2.3. Built-in)90 176.4 R(Rules)2.75 E F1 .935
X(There are six b)90 192.6 R .935(uilt-in rules, \214v)-.2 F 3.435(eo)-.15 G
X3.435(fw)228.85 192.6 S .935(hich modify the tar)242.835 192.6 R .935
X(get dependenc)-.18 F 3.435(yg)-.15 G 3.436(raph. None)393.54 192.6 R .936
X(of these rules ha)3.436 F -.15(ve)-.2 G(updating actions.)90 204.6 Q(The b)5 E
X(uilt-in rules are:)-.2 E/F2 10/Courier@0 SF
X(DEPENDS, INCLUDES, ECHO, TEMPORARY, NOTIME, NOCARE)130 220.8 Q F1 .923
X(DEPENDS and INCLUDES tak)90 241.2 R 3.423(e<)-.1 G(tar)234.772 241.2 Q .923
X(gets> and <sources>.)-.18 F .923(ECHO tak)5.923 F .922(es only <tar)-.1 F
X3.422(gets>. TEMPORAR)-.18 F -1.29(Y,)-.65 G(NO)90 253.2 Q 1.169
X(TIME, and NOCARE tak)-.4 F 3.669(eo)-.1 G 1.169(nly <tar)222.766 253.2 R 1.169
X(gets> and mark them with attrib)-.18 F 1.17(utes to indicate special handling)
X-.2 F(when descending the dependenc)90 265.2 Q 2.5(yg)-.15 G(raph.)231.48 265.2
XQ(DEPENDS)90 281.4 Q .713(The basic b)115 293.4 R .712(uilder of the dependenc)
X-.2 F 3.212(yg)-.15 G .712(raph: it mak)271.664 293.4 R .712
X(es <sources> dependencies of <tar)-.1 F .712(gets>, just lik)-.18 F(e)-.1 E
X.594(the simple)115 305.4 R/F3 10/Times-Italic@0 SF(mak)3.094 E(e)-.1 E F1 .594
X(\231:\232 dependenc)3.094 F 4.394 -.65(y. I)-.15 H 3.095(f<).65 G .595
X(sources> are ne)269.375 305.4 R .595(wer than <tar)-.25 F .595
X(gets> \(using \214le update times for)-.18 F 2.239(comparison\), or if <sourc\
Xes> are being updated, then the updating actions of <tar)115 317.4 R 2.239
X(gets> will be)-.18 F -.15(exe)115 329.4 S(cuted.).15 E(INCLUDES)90 345.6 Q
X3.479(Av)115 357.6 S .979(ariation on DEPENDS: it mak)130.449 357.6 R .979
X(es <sources> dependencies of an)-.1 F 3.479(yt)-.15 G(ar)401.64 357.6 Q .98
X(gets of which <tar)-.18 F .98(gets> are)-.18 F 2.5(dependencies. This)115
X369.6 R -.15(ex)2.5 G(ample mak).15 E
X(es both foo.c and foo.h dependencies of foo.o:)-.1 E F2
X(DEPENDS foo.o : foo.c ;)155 385.8 Q(INCLUDES foo.c : foo.h ;)155 397.8 Q F1
X(ECHO)90 418.2 Q 1.684(Just echoes its tar)115 430.2 R 1.684
X(gets to the standard output, as a means for communicating with the user)-.18 F
X6.683(.J)-.55 G(am)509.78 430.2 Q(kno)115 442.2 Q(ws no f)-.25 E(atal error)-.1
XE 2.5(,s)-.4 G 2.5(ot)203.95 442.2 S
X(he message emitted by ECHO can only be advisory)214.23 442.2 Q(.)-.65 E
X(TEMPORAR)90 458.4 Q(Y)-.65 E(Allo)115 470.4 Q .097(ws for intermediate tar)
X-.25 F .098(gets to be missing and not updated if the \214nal tar)-.18 F .098
X(get is up-to-date.)-.18 F .098(If a tar)5.098 F(-)-.2 E 1.131(get mark)115
X482.4 R 1.131(ed TEMPORAR)-.1 F 3.631(Yi)-.65 G 3.631(sn)231.803 482.4 S 1.131
X(ot present, then it simply inherits its parent')244.324 482.4 R 3.63(st)-.55 G
X1.13(ime-stamp. TEMPO-)436.43 482.4 R(RAR)115 494.4 Q 3.077(Yc)-.65 G .577
X(an be used for an)149.647 494.4 R 3.077(yt)-.15 G .577(emporary tar)230.972
X494.4 R .577(get, such as the short-li)-.18 F -.15(ve)-.25 G 3.077(do).15 G
X.578(bject module that is to be part)399.654 494.4 R(of a library archi)115
X506.4 Q -.15(ve)-.25 G(.).15 E(NO)90 522.6 Q(TIME)-.4 E 1.052
X(Indicates that the tar)115 534.6 R 1.051
X(get is not really a \214le and therefore doesn')-.18 F 3.551(th)-.18 G -2.25
X-.2(av e)387.756 534.6 T 3.551(at)3.751 G 3.551(ime-stamp. An)415.608 534.6 R
X3.551(yu)-.15 G(pdating)492 534.6 Q .386(actions are only e)115 546.6 R -.15
X(xe)-.15 G .387(cuted if the tar).15 F(get')-.18 E 2.887(sd)-.55 G .387
X(ependencies were updated, rather than on the basis of time-)281.357 546.6 R
X.016(stamp comparisons.)115 558.6 R(NO)5.016 E .016
X(TIME is used for pseudo tar)-.4 F .015
X(gets such as \231all\232 or \231install\232, which ha)-.18 F .315 -.15(ve d)
X-.2 H(epen-).15 E(dencies b)115 570.6 Q(ut don')-.2 E 2.5(ta)-.18 G
X(ctually get b)190.44 570.6 Q(uilt themselv)-.2 E(es.)-.15 E(NOCARE)90 586.8 Q
X.58(Indicates that the tar)115 598.8 R .58(get may both be non-e)-.18 F .581
X(xistent and not ha)-.15 F .881 -.15(ve a)-.2 H .881 -.15(ny u).15 H .581
X(pdating actions.).15 F .581(This loophole)5.581 F(is used to mak)115 610.8 Q
X2.5(eu)-.1 G 2.5(pf)184.34 610.8 S(or the sloppiness of the header)195.17 610.8
XQ(-\214le scanning.)-.2 E F0 2.75(2.4. J)90 627 R(am V)-.165 E(ariables)-1.012
XE F1 -.15(Pa)90 643.2 S 1.015(rt of Jam').15 F 3.515(sp)-.55 G 1.015
X(rogrammability lies in its treatment of v)152.615 643.2 R 3.515(ariables. As)
X-.25 F(with)3.515 E F3(mak)3.515 E(e)-.1 E F1(and)3.514 E F3(sh)3.514 E F1
X3.514(,J)C 1.014(am v)454.692 643.2 R 1.014(ariables are)-.25 F .143
X(lists of strings, with zero or more elements.)90 655.2 R .143
X(But unique to Jam, the result of v)5.143 F .143(ariable e)-.25 F .144
X(xpansion is the prod-)-.15 F(uct of the v)90 667.2 Q(ariable v)-.25 E
X(alues and literal constants in the tok)-.25 E(en being e)-.1 E 2.5
X(xpanded. An)-.15 F -.15(ex)2.5 G(ample helps here:).15 E F2($\(X\) -> a b c)
X130 683.4 Q(t$\(X\) -> ta tb tc)130 695.4 Q
X($\(X\)$\(X\) -> aa ab ac ba bb bc ca cb cc)130 707.4 Q EP
X%%Page: 4 4
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF .41(This approach mak)90 96 R .41(es quick w)-.1 F .41
X(ork of man)-.1 F 2.909(yn)-.15 G .409(ormal v)268.319 96 R .409
X(ariable manipulations: prepending a path name to a list)-.25 F(of \214le name\
Xs, prepending \231-l\232 to a list of library names, appending a \231,v\232 to\
X RCS \214le names, etc.)90 108 Q 1.459(Jam has a modicum of v)90 124.2 R 1.46
X(ariable editing options to replace components of a path name and to subselect)
X-.25 F(members of a list.)90 136.2 Q
X(These options are discussed in usable detail in Jam')5 E 2.5(sm)-.55 G
X(anual page [Seiw)386.92 136.2 Q(ald, 1993].)-.1 E(Unlik)90 152.4 Q(e)-.1 E/F1
X10/Times-Italic@0 SF(mak)3.336 E(e)-.1 E F0 3.336(,J)C .836
X(am does not defer e)151.182 152.4 R .835(xpansion of v)-.15 F 3.335
X(ariables. When)-.25 F 3.335(av)3.335 G .835(ariable is referenced, e)367.72
X152.4 R -.15(ve)-.25 G 3.335(nt).15 G 3.335(oa)480.89 152.4 S .835(ssign a)
X493.665 152.4 R(ne)90 164.4 Q 2.5(wv)-.25 G(ariable, the v)113.66 164.4 Q
X(alue is e)-.25 E(xpanded at that time.)-.15 E 1.563(Jam v)90 180.6 R 1.563
X(ariables ha)-.25 F 1.863 -.15(ve t)-.2 H 1.763 -.1(wo s).15 H 1.563
X(copes: global and tar).1 F 4.064(get-speci\214c. Global)-.18 F -.25(va)4.064 G
X1.564(riables beha).25 F 1.864 -.15(ve m)-.2 H 1.564(uch as one might).15 F
X-.15(ex)90 192.6 S .25(pect, holding their v).15 F .25(alue until reassigned.)
X-.25 F -.8(Ta)5.25 G -.18(rg).8 G .25(et-speci\214c v).18 F .25(ariables tak)
X-.25 F 2.75(ep)-.1 G .25(recedence o)395.46 192.6 R -.15(ve)-.15 G 2.75(rg).15
XG .25(lobal v)463.4 192.6 R(ariables)-.25 E .063(when the speci\214ed tar)90
X204.6 R .064(get is being bound \(see belo)-.18 F .064(w\) or updated.)-.25 F
X.064(The distinction between global and tar)5.064 F(get-)-.18 E .273
X(speci\214c v)90 216.6 R .273(ariables is made when the v)-.25 F .272
X(ariables are assigned.)-.25 F .272(The syntax for setting the tw)7.772 F 2.772
X(ot)-.1 G .272(ypes is, respec-)460.086 216.6 R(ti)90 228.6 Q -.15(ve)-.25 G
X(ly:).15 E/F2 10/Courier@0 SF(<var> = <value> ;)130 244.8 Q
X(<var> on <targets> = <value> ;)130 256.8 Q F0 -.8(Ta)90 277.2 S -.18(rg).8 G
X1.009(et-speci\214c v).18 F 1.009(ariables ha)-.25 F 1.309 -.15(ve s)-.2 H
X-2.15 -.25(ev e).15 H 1.009(ral uses.).25 F 3.509(As)6.009 G 1.009
X(imple one is to permit dif)285.684 277.2 R 1.01
X(ferent compiler \215ag settings for)-.25 F(dif)90 289.2 Q .06
X(ferent source \214les.)-.25 F .06(In this w)5.06 F(ay)-.1 E 2.56(,t)-.65 G .06
X(he actions of the CC rule may be used to compile an)231.28 289.2 R 2.56(yCs)
X-.15 G .06(ource \214le, with)461.61 289.2 R -.25(va)90 301.2 S .484
X(rious \215ags \(HDRS, CCFLA).25 F .484(GS\) being adjusted per)-.4 F(-tar)-.2
XE 2.985(get. Other)-.18 F .485(uses of tar)2.985 F .485(get-speci\214c v)-.18 F
X.485(ariables will be)-.25 F(discussed shortly)90 313.2 Q(.)-.65 E/F3 11
X/Times-Bold@0 SF 2.75(2.5. Flo)90 329.4 R(w-of-Contr)-.11 E(ol)-.198 E F0 .86
X(In addition to statements for de\214ning and in)90 345.6 R -.2(vo)-.4 G .859
X(king rules and setting v).2 F .859(ariables, the Jam language contains)-.25 F
X(statements for \215o)90 357.6 Q(w-of-control and \214le inclusion.)-.25 E
X(The statements are:)5 E F2
X(if <condition> { <statements> } [ else { <statements> } ])130 373.8 Q
X(for <var> in <value> { <statements> })130 397.8 Q
X(switch <value> { case <value> : <statements> ; ... })130 421.8 Q
X(include <file> ;)130 445.8 Q F0 .473(The \231if\232 statement does the ob)90
X466.2 R .474
X(vious; the <condition> is the usual mix of comparison and logical operators)
X-.15 F(applied to v)90 478.2 Q(ariables.)-.25 E .09
X(The \231for\232 statement iterates o)90 494.4 R -.15(ve)-.15 G 2.59(rt).15 G
X.089(he elements of <v)226.5 494.4 R .089(alue>, assigning the \(global\) v)
X-.25 F .089(ariable <v)-.25 F .089(ar> to each ele-)-.25 F(ment and e)90 506.4
XQ -.15(xe)-.15 G(cuting the statement block.).15 E
X(The \231switch\232 statement e)90 522.6 Q -.15(xe)-.15 G
X(cutes the statement block whose case <v).15 E(alue> matches the switch')-.25 E
X2.5(s<)-.55 G -.25(va)477.13 522.6 S(lue>.).25 E(The \231include\232 statement\
X sources another \214le containing Jam statements.)90 538.8 Q 1.377
X(Jam neither needs nor desires a macro preprocessor)90 555 R 6.377(.M)-.55 G
X1.377(aking rule de\214nitions and \214le inclusions normal)322.626 555 R 2.015
X(statements ob)90 567 R 2.014(viates a macro preprocessor for conditional comp\
Xilation, as these statements may appear)-.15 F .581(within Jam conditionals.)90
X579 R(Further)5.581 E 3.081(,p)-.4 G .581(reprocessing w)234.424 579 R .582
X(ould require the Jam language to play \231dodge-em\232 with)-.1 F
X(the preprocessor semantics.)90 591 Q EP
X%%Page: 5 5
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 11/Times-Bold@0 SF 2.75(3. Binding)90 96 R(Files)2.75 E/F1 10/Times-Roman@0
XSF .91(Jam can \214nd source and tar)90 112.2 R .91
X(get \214les in distant directories, much lik)-.18 F 3.41(et)-.1 G .91
X(he functionality of VP)375.33 112.2 R -1.11(AT)-.92 G 3.41(Hi)1.11 G 3.41(nG)
X491.93 112.2 S(NU)507.56 112.2 Q/F2 10/Times-Italic@0 SF(mak)90 124.2 Q(e)-.1 E
XF1(and)2.5 E F2(dmak)2.5 E(e)-.1 E F1(.)A .066(By def)90 140.4 R .066
X(ault, a tar)-.1 F .066(get is located at the actual path of the tar)-.18 F
X.066(get, relati)-.18 F .366 -.15(ve t)-.25 H 2.566(ot).15 G .066
X(he directory of Jam')379.24 140.4 R 2.566(si)-.55 G -1.9 -.4(nv o)468.934
X140.4 T 2.566(cation. If).4 F .051(the special v)90 152.4 R .051
X(ariable $\(LOCA)-.25 F .051
X(TE\) is set to a directory name, Jam locates the tar)-1.11 F .05
X(get in that directory \(correctly)-.18 F .273(concatenating the v)90 164.4 R
X.273(alue of $\(LOCA)-.25 F .274(TE\) and the tar)-1.11 F(get')-.18 E 2.774(sp)
X-.55 G .274(ath name\).)320.598 164.4 R .274(If $\(LOCA)5.274 F .274
X(TE\) is unset b)-1.11 F .274(ut the special)-.2 F -.25(va)90 176.4 S .203(ria\
Xble $\(SEARCH\) is set to a directory list, Jam searches along the directory l\
Xist for the tar).25 F .203(get \214le \(ag)-.18 F(ain,)-.05 E
X(correctly concatenating the path names\).)90 188.4 Q 1.18(Jam mak)90 204.6 R
X1.18(es a)-.1 F -.25(va)-.2 G 1.18(ilable the bound tar).25 F 1.181
X(get names by using them when e)-.18 F 1.181
X(xpanding $\(<\) and $\(>\) for updating)-.15 F 3.033(actions. Thus,)90 216.6 R
X3.033(at)3.033 G(ar)162.149 216.6 Q .533
X(get can be referred to by a short, unrooted name when in)-.18 F -.2(vo)-.4 G
X.533(king a rule to de\214ne a rela-).2 F .063(tionship, b)90 228.6 R .063
X(ut an)-.2 F 2.563(ys)-.15 G .064(hell commands manipulating the tar)163.179
X228.6 R .064(get see a path name usable from the current directory)-.18 F(.)
X-.65 E 2.23($\(SEARCH\) pro)90 244.8 R 2.23(vides VP)-.15 F -1.11(AT)-.92 G
X(H-lik)1.11 E 4.729(ef)-.1 G(unctionality)242.449 244.8 Q 4.729(,a)-.65 G(llo)
X301.248 244.8 Q 2.229(wing Jam to be in)-.25 F -.2(vo)-.4 G -.1(ke).2 G 4.729
X(di).1 G 4.729(nd)422.833 244.8 S 2.229(irectories other than)437.562 244.8 R
X.076(where the source li)90 256.8 R -.15(ve)-.25 G .076(s, while $\(LOCA).15 F
X.076(TE\) liberates Jam from the directory tree altogether)-1.11 F 5.077(.W)
X-.55 G .077(ith it, Jam can)465.659 256.8 R(run an)90 268.8 Q(ywhere.)-.15 E
X1.237(By setting $\(SEARCH\) and $\(LOCA)90 285 R 1.237(TE\) properly)-1.11 F
X3.737(,J)-.65 G 1.236(am can handle a v)305.922 285 R 1.236(ariety of b)-.25 F
X1.236(uild en)-.2 F 3.736(vironments. F)-.4 F(or)-.15 E -.15(ex)90 297 S .484(\
Xample, read-only source trees can be handled by pointing $\(SEARCH\) at a read\
X-only source code direc-).15 F .496(tory while pointing $\(LOCA)90 309 R .496
X(TE\) to a w)-1.11 F .496(orking directory)-.1 F 5.496(.A)-.65 G 2.996(sa)
X328.748 309 S .496(nother e)340.074 309 R .496
X(xample, \231sparse\232 source trees can be)-.15 F .323(handled by ha)90 321 R
X.324(ving $\(SEARCH\) contain tw)-.2 F 2.824(od)-.1 G .324
X(irectories: \214rst the de)276.072 321 R -.15(ve)-.25 G(loper').15 E 2.824(so)
X-.55 G .324(wn directory)405.588 321 R 2.824(,w)-.65 G .324(hich contains)
X468.626 321 R 1.097(only the \214les he is editing, and then his group')90 333
XR 3.597(sd)-.55 G(irectory)297.36 333 Q 3.597(,w)-.65 G 1.096
X(hich contains the master cop)341.127 333 R 3.596(yo)-.1 G 3.596(fa)472.878 333
XS 1.096(ll source.)484.244 333 R 1.932(Most importantly)90 345 R 4.432(,m)-.65
XG 1.932(uch of an)175.724 345 R 4.432(yb)-.15 G 1.933(uild en)230.88 345 R
X1.933(vironment can be encoded in the settings of $\(SEARCH\) and)-.4 F
X($\(LOCA)90 357 Q(TE\), which lea)-1.11 E -.15(ve)-.2 G 2.5(st).15 G
X(he \214le names used in rule in)201.85 357 Q -.2(vo)-.4 G
X(cations free from en).2 E(vironment.)-.4 E .774(The po)90 373.2 R .774
X(wer of $\(SEARCH\) and $\(LOCA)-.25 F .774(TE\) is realized when these v)-1.11
XF .774(ariables are set per)-.25 F(-tar)-.2 E .774(get rather than)-.18 F .486
X(just globally)90 385.2 R 5.486(.E)-.65 G .486(ach indi)153.662 385.2 R .486
X(vidual tar)-.25 F .486(get \214le can potentially be found along dif)-.18 F
X.486(ferent search paths.)-.25 F .486(In practice,)5.486 F 1.042
X(related \214les will ha)90 397.2 R 1.342 -.15(ve t)-.2 H 1.042
X(he same search path, b).15 F 1.042(ut Jam can ef)-.2 F 1.042
X(\214ciently accommodate the de)-.25 F 1.041(generate case of)-.15 F(ha)90
X409.2 Q .505(ving these v)-.2 F .505(ariables set per)-.25 F(-tar)-.2 E 3.005
X(get. In)-.18 F .505(this w)3.005 F(ay)-.1 E 3.005(,J)-.65 G .505(am can b)
X297.14 409.2 R .506(uild whole source trees, with source \214les scat-)-.2 F
X(tered across directories.)90 421.2 Q F0 2.75(4. Header)90 437.4 R
X(-File Inclusion)-.407 E F1 .581(Jam handles the incidental dependencies cause\
Xd when source \214les include other source \214les.)90 453.6 R 2.18 -.8
X(To \214)5.58 H .58(nd such).8 F 1.246
X(dependencies, Jam scans source \214les for header)90 465.6 R 1.246
X(-\214le inclusions, using a re)-.2 F 1.246(gular e)-.15 F 1.247
X(xpression pattern match)-.15 F([Spencer)90 477.6 Q 3.253(,1)-.4 G 3.253
X(986]. The)135.893 477.6 R(re)3.253 E .753(gular e)-.15 F .753(xpression is gi)
X-.15 F -.15(ve)-.25 G 3.253(ni).15 G 3.253(nt)296.351 477.6 S .752(he v)307.384
X477.6 R .752(ariable $\(HDRSCAN\).)-.25 F .752(The result of the scan is)5.752
XF .671(not interpreted directly by Jam; to arrange the necessary relationship,\
X Jam calls a user)90 489.6 R .672(-de\214ned rule named)-.2 F .796(in the v)90
X501.6 R .796(ariable $\(HDRR)-.25 F .796
X(ULE\), with the scanned \214le as <tar)-.4 F .796(gets> and the found header)
X-.18 F .796(-\214les as <sources>.)-.2 F(Usually)90 513.6 Q 3.034(,t)-.65 G
X.534(he de\214nition of $\(HDRR)128.774 513.6 R .534
X(ULE\) includes a call to the b)-.4 F .534
X(uilt-in rule INCLUDES, which updates the)-.2 F(dependenc)90 525.6 Q 2.5(yg)
X-.15 G(raph appropriately)145.11 525.6 Q 5(.A)-.65 G 2.5(ne)232.77 525.6 S
X(xample HDRSCAN that w)244.56 525.6 Q(orks for C preprocessor includes is:)-.1
XE/F3 10/Courier@0 SF
X(HDRSCAN = "^#[ \\t]*include[ \\t]*[<\\"]\(.*\)[\\">].*$" ;)130 541.8 Q F1
X1.693(The combination of $\(HDRSCAN\) and $\(HDRR)90 562.2 R 1.693
X(ULE\), when set per)-.4 F(-tar)-.2 E 1.693(get, enables Jam to handle just)
X-.18 F .679(about an)90 574.2 R 3.179(yi)-.15 G .679
X(nclude-\214le syntax or semantics.)135.648 574.2 R(Unfortunately)5.679 E 3.179
X(,t)-.65 G .679(his mechanism doesn')333.923 574.2 R 3.179(tu)-.18 G .68
X(nderstand conditional)434.94 574.2 R 1.103(includes \(#include within #ifdef\
X\), and can produce bogus dependencies that must be crudely pasted o)90 586.2 R
X-.15(ve)-.15 G(r).15 E(with the application of the b)90 598.2 Q
X(uilt-in NOCARE rule.)-.2 E F0 2.75(5. T)90 614.4 R(ime-Stamps)-.198 E F1(Lik)
X90 630.6 Q(e)-.1 E F2(mak)4.679 E(e)-.1 E F1 2.179
X(et. al., Jam uses time-stamps to determine when tar)4.679 F 2.18
X(gets are out-of-date.)-.18 F 2.18(Another possible)7.18 F 1.464
X(design, a more forw)90 642.6 R 1.464(ard-looking one, w)-.1 F 1.463(ould ha)
X-.1 F 1.763 -.15(ve J)-.2 H 1.463(am taking \214le update cues from an inte).15
XF 1.463(grated source)-.15 F .696(management system.)90 654.6 R .696(This w)
X5.696 F .696(as deferred for tw)-.1 F 3.196(or)-.1 G 3.196(easons: \214rst,)
X292.682 654.6 R .696(it w)3.196 F .696(ould require picking a source manage-)
X-.1 F .455(ment system with which to w)90 666.6 R .455
X(ork \(or attempting to engineer a generic interf)-.1 F .455
X(ace to source management sys-)-.1 F(tems\); second, it w)90 678.6 Q
X(ould preclude using Jam as a drop-in replacement for e)-.1 E(xisting uses of)
X-.15 E F2(mak)2.5 E(e)-.1 E F1(.)A .554(The code in Jam that checks dependenci\
Xes is isolated enough to be altered to w)90 694.8 R .554
X(ork with a source manage-)-.1 F .614(ment system.)90 706.8 R(Internally)5.613
XE 3.113(,J)-.65 G .613(am already distinguishes between updates due to ne)
X196.74 706.8 R .613(wer dependents and updates)-.25 F
X(due to updated dependents.)90 718.8 Q EP
X%%Page: 6 6
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 11/Times-Bold@0 SF 2.75(6. The)90 96 R(Base Rule Set)2.75 E/F1 10
X/Times-Roman@0 SF 2.838(Ac)90 112.2 S .338(ollection of rules pro)104.498 112.2
XR(viding)-.15 E/F2 10/Times-Italic@0 SF(mak)2.838 E(e)-.1 E F1(\255lik)A 2.839
X(ef)-.1 G .339(unctionality is supplied with Jam.)265.069 112.2 R .339
X(Called Jambase, the \214le pro-)5.339 F .685
X(vides a dozen-odd rules for compiling and linking C source code.)90 124.2 R
X(Dif)5.685 E .685(ferent v)-.25 F .685(ersions of Jambase e)-.15 F .685
X(xist for)-.15 F(UNIX, VMS, and NT)90 136.2 Q 2.5(,a)-.74 G(ll pro)185.63 136.2
XQ(viding the same rule set.)-.15 E(Figure 1 lists the rules de\214ned in the c\
Xurrent Jambase \(described comprehensi)90 152.4 Q -.15(ve)-.25 G(ly in).15 E F2
X-.35(Ja)2.5 G(mbase).35 E F1(\(5\)\).)A .4
X(The last act of Jambase is to include a \214le called Jam\214le from the in)90
X168.6 R -.2(vo)-.4 G .4(king user').2 F 2.9(sc)-.55 G .4(urrent directory)
X427.98 168.6 R 5.4(.U)-.65 G(sing)505.33 168.6 Q .33
X(the rules de\214ned in Jambase, the user')90 180.6 R 2.83(sJ)-.55 G .329
X(am\214le enumerates the source \214les and their relationship to the tar)
X254.51 180.6 R(-)-.2 E(gets to be b)90 192.6 Q(uilt.)-.2 E .231(The Jambase an\
Xd Jam\214le \214les share the same language; only their purposes distinguish t\
Xhem.)90 208.8 R .232(It is possible)5.232 F .012(to write a special-purpose re\
Xplacement Jambase that is totally self-contained and needs no directory-speci\
X\214c)90 220.8 R 3.499(Jam\214le. It)90 232.8 R .999
X(is also possible to use an)3.499 F 3.499(yJ)-.15 G 1
X(am syntax \212 including conditionals, rule de\214nitions, etc. \212 in a)
X252.842 232.8 R(Jam\214le.)90 244.8 Q F0 2.75(7. The)90 261 R(Example)2.75 E F1
X(Returning to our earlier e)90 277.2 Q(xample:)-.15 E/F3 10/Courier@0 SF
X(MAIN prog : prog.c ;)130 293.4 Q(LIBS prog : libaux.a ;)130 305.4 Q
X(LIBRARY libaux.a : compile.c gram.y scan.c ;)130 317.4 Q F1 .489(This e)90
X337.8 R .489(xample in)-.15 F -.2(vo)-.4 G -.1(ke).2 G 2.989(st).1 G .489
X(hree rules that instruct Jam to b)183.667 337.8 R .488(uild an archi)-.2 F
X.788 -.15(ve f)-.25 H .488(rom three source \214les, to compile a).15 F .528
X(fourth source \214le, and to link it ag)90 349.8 R .528(ainst the archi)-.05 F
X-.15(ve)-.25 G 5.528(.A).15 G .529
X(ll these rules are de\214ned by the Jambase \214le and do)311.19 349.8 R
X(most of their w)90 361.8 Q(ork by in)-.1 E -.2(vo)-.4 G
X(king other rules de\214ned in the Jambase.).2 E 1.068
X(MAIN calls LINK to set up the relationship between)90 378 R/F4 10/Times-Bold@0
XSF(pr)3.568 E(og)-.18 E F1(and)3.568 E F4(pr)3.568 E(og)-.18 E(.o)-.15 E F1
X3.568(,t)C 1.067(hen calls OBJECT to set up the)390.046 378 R .163
X(relationship between)90 390 R F4(pr)2.663 E(og)-.18 E(.o)-.15 E F1(and)2.664 E
XF4(pr)2.664 E(og)-.18 E(.c)-.15 E F1 5.164(.O)C .164
X(BJECT calls a rule speci\214c to the \214le suf)264.298 390 R .164
X(\214x, in this case, CC for)-.25 F F4(.c)90 402 Q F1 5(.A)C(long the w)111.66
X402 Q(ay)-.1 E 2.5(,t)-.65 G(he v)170.35 402 Q(arious rules in)-.25 E -.2(vo)
X-.4 G .2 -.1(ke t).2 H(he b).1 E(uilt-in DEPENDS rule to set up the dependenc)
X-.2 E 2.5(yg)-.15 G(raph.)483.18 402 Q .4 LW 95 441.6 90 441.6 DL 97 441.6 92
X441.6 DL 102 441.6 97 441.6 DL 107 441.6 102 441.6 DL 112 441.6 107 441.6 DL
X117 441.6 112 441.6 DL 122 441.6 117 441.6 DL 127 441.6 122 441.6 DL 132 441.6
X127 441.6 DL 137 441.6 132 441.6 DL 142 441.6 137 441.6 DL 147 441.6 142 441.6
XDL 152 441.6 147 441.6 DL 157 441.6 152 441.6 DL 162 441.6 157 441.6 DL 167
X441.6 162 441.6 DL 172 441.6 167 441.6 DL 177 441.6 172 441.6 DL 182 441.6 177
X441.6 DL 187 441.6 182 441.6 DL 192 441.6 187 441.6 DL 197 441.6 192 441.6 DL
X202 441.6 197 441.6 DL 207 441.6 202 441.6 DL 212 441.6 207 441.6 DL 217 441.6
X212 441.6 DL 222 441.6 217 441.6 DL 227 441.6 222 441.6 DL 232 441.6 227 441.6
XDL 237 441.6 232 441.6 DL 242 441.6 237 441.6 DL 247 441.6 242 441.6 DL 252
X441.6 247 441.6 DL 257 441.6 252 441.6 DL 262 441.6 257 441.6 DL 267 441.6 262
X441.6 DL 272 441.6 267 441.6 DL 277 441.6 272 441.6 DL 282 441.6 277 441.6 DL
X287 441.6 282 441.6 DL 292 441.6 287 441.6 DL 297 441.6 292 441.6 DL 302 441.6
X297 441.6 DL 307 441.6 302 441.6 DL 312 441.6 307 441.6 DL 317 441.6 312 441.6
XDL 322 441.6 317 441.6 DL 327 441.6 322 441.6 DL 332 441.6 327 441.6 DL 337
X441.6 332 441.6 DL 342 441.6 337 441.6 DL 347 441.6 342 441.6 DL 352 441.6 347
X441.6 DL 357 441.6 352 441.6 DL 362 441.6 357 441.6 DL 367 441.6 362 441.6 DL
X372 441.6 367 441.6 DL 377 441.6 372 441.6 DL 382 441.6 377 441.6 DL 387 441.6
X382 441.6 DL 392 441.6 387 441.6 DL 397 441.6 392 441.6 DL 402 441.6 397 441.6
XDL 407 441.6 402 441.6 DL 412 441.6 407 441.6 DL 417 441.6 412 441.6 DL 422
X441.6 417 441.6 DL 427 441.6 422 441.6 DL 432 441.6 427 441.6 DL 437 441.6 432
X441.6 DL 442 441.6 437 441.6 DL 447 441.6 442 441.6 DL 452 441.6 447 441.6 DL
X457 441.6 452 441.6 DL 462 441.6 457 441.6 DL 467 441.6 462 441.6 DL 472 441.6
X467 441.6 DL 477 441.6 472 441.6 DL 482 441.6 477 441.6 DL 487 441.6 482 441.6
XDL 492 441.6 487 441.6 DL 497 441.6 492 441.6 DL 502 441.6 497 441.6 DL 507
X441.6 502 441.6 DL 512 441.6 507 441.6 DL 517 441.6 512 441.6 DL 522 441.6 517
X441.6 DL/F5 9/Courier@0 SF(MAIN image : source ;)90 464.4 Q
X(link executable from compiled sources)246.6 464.4 Q(LIBS image : libraries ;)
X90 475.2 Q(link libraries onto a MAIN)246.6 475.2 Q
X(UNDEFINES image : symbols ;)90 486 Q(save undefs for linking)246.6 486 Q
X(SETUID image ;)90 496.8 Q(mark an executable SETUID)246.6 496.8 Q
X(LIBRARY lib : source ;)90 507.6 Q(archive library from compiled sources)246.6
X507.6 Q(OBJECT objname : source ;)90 518.4 Q(compile object from source)246.6
X518.4 Q(HDRRULE source : headers ;)90 529.2 Q(handle #includes)246.6 529.2 Q
X(CC obj.o : source.c ;)90 540 Q(.c -> .o)246.6 540 Q(LEX source.c : source.l ;)
X90 550.8 Q(.l -> .c)246.6 550.8 Q(YACC source.c : source.y ;)90 561.6 Q
X(.y -> .c)246.6 561.6 Q(YYACC source.y : source.yy ; .yy -> .y)90 572.4 Q
X(BULK dir : files ;)90 583.2 Q(populate directory with many files)246.6 583.2 Q
X(FILE dest : source ;)90 594 Q(copy file)246.6 594 Q(SHELL exe : source ;)90
X604.8 Q(install a shell executable)246.6 604.8 Q(RMTEMPS target : sources ;)90
X615.6 Q(remove temp sources after target made)246.6 615.6 Q
X(INSTALLBIN sources ;)90 626.4 Q(install binaries)246.6 626.4 Q
X(INSTALLLIB sources ;)90 637.2 Q(install files)246.6 637.2 Q
X(INSTALLMAN source ;)90 648 Q(install man pages)246.6 648 Q 95 660 90 660 DL 97
X660 92 660 DL 102 660 97 660 DL 107 660 102 660 DL 112 660 107 660 DL 117 660
X112 660 DL 122 660 117 660 DL 127 660 122 660 DL 132 660 127 660 DL 137 660 132
X660 DL 142 660 137 660 DL 147 660 142 660 DL 152 660 147 660 DL 157 660 152 660
XDL 162 660 157 660 DL 167 660 162 660 DL 172 660 167 660 DL 177 660 172 660 DL
X182 660 177 660 DL 187 660 182 660 DL 192 660 187 660 DL 197 660 192 660 DL 202
X660 197 660 DL 207 660 202 660 DL 212 660 207 660 DL 217 660 212 660 DL 222 660
X217 660 DL 227 660 222 660 DL 232 660 227 660 DL 237 660 232 660 DL 242 660 237
X660 DL 247 660 242 660 DL 252 660 247 660 DL 257 660 252 660 DL 262 660 257 660
XDL 267 660 262 660 DL 272 660 267 660 DL 277 660 272 660 DL 282 660 277 660 DL
X287 660 282 660 DL 292 660 287 660 DL 297 660 292 660 DL 302 660 297 660 DL 307
X660 302 660 DL 312 660 307 660 DL 317 660 312 660 DL 322 660 317 660 DL 327 660
X322 660 DL 332 660 327 660 DL 337 660 332 660 DL 342 660 337 660 DL 347 660 342
X660 DL 352 660 347 660 DL 357 660 352 660 DL 362 660 357 660 DL 367 660 362 660
XDL 372 660 367 660 DL 377 660 372 660 DL 382 660 377 660 DL 387 660 382 660 DL
X392 660 387 660 DL 397 660 392 660 DL 402 660 397 660 DL 407 660 402 660 DL 412
X660 407 660 DL 417 660 412 660 DL 422 660 417 660 DL 427 660 422 660 DL 432 660
X427 660 DL 437 660 432 660 DL 442 660 437 660 DL 447 660 442 660 DL 452 660 447
X660 DL 457 660 452 660 DL 462 660 457 660 DL 467 660 462 660 DL 472 660 467 660
XDL 477 660 472 660 DL 482 660 477 660 DL 487 660 482 660 DL 492 660 487 660 DL
X497 660 492 660 DL 502 660 497 660 DL 507 660 502 660 DL 512 660 507 660 DL 517
X660 512 660 DL 522 660 517 660 DL F1(Figure 1 \212 Rules supplied with Jam)
X232.665 684 Q EP
X%%Page: 7 7
X%%BeginPageSetup
XBP
X%%EndPageSetup
X.4 LW 95 108 90 108 DL 97 108 92 108 DL 102 108 97 108 DL 107 108 102 108 DL
X112 108 107 108 DL 117 108 112 108 DL 122 108 117 108 DL 127 108 122 108 DL 132
X108 127 108 DL 137 108 132 108 DL 142 108 137 108 DL 147 108 142 108 DL 152 108
X147 108 DL 157 108 152 108 DL 162 108 157 108 DL 167 108 162 108 DL 172 108 167
X108 DL 177 108 172 108 DL 182 108 177 108 DL 187 108 182 108 DL 192 108 187 108
XDL 197 108 192 108 DL 202 108 197 108 DL 207 108 202 108 DL 212 108 207 108 DL
X217 108 212 108 DL 222 108 217 108 DL 227 108 222 108 DL 232 108 227 108 DL 237
X108 232 108 DL 242 108 237 108 DL 247 108 242 108 DL 252 108 247 108 DL 257 108
X252 108 DL 262 108 257 108 DL 267 108 262 108 DL 272 108 267 108 DL 277 108 272
X108 DL 282 108 277 108 DL 287 108 282 108 DL 292 108 287 108 DL 297 108 292 108
XDL 302 108 297 108 DL 307 108 302 108 DL 312 108 307 108 DL 317 108 312 108 DL
X322 108 317 108 DL 327 108 322 108 DL 332 108 327 108 DL 337 108 332 108 DL 342
X108 337 108 DL 347 108 342 108 DL 352 108 347 108 DL 357 108 352 108 DL 362 108
X357 108 DL 367 108 362 108 DL 372 108 367 108 DL 377 108 372 108 DL 382 108 377
X108 DL 387 108 382 108 DL 392 108 387 108 DL 397 108 392 108 DL 402 108 397 108
XDL 407 108 402 108 DL 412 108 407 108 DL 417 108 412 108 DL 422 108 417 108 DL
X427 108 422 108 DL 432 108 427 108 DL 437 108 432 108 DL 442 108 437 108 DL 447
X108 442 108 DL 452 108 447 108 DL 457 108 452 108 DL 462 108 457 108 DL 467 108
X462 108 DL 472 108 467 108 DL 477 108 472 108 DL 482 108 477 108 DL 487 108 482
X108 DL 492 108 487 108 DL 497 108 492 108 DL 502 108 497 108 DL 507 108 502 108
XDL 512 108 507 108 DL 517 108 512 108 DL 522 108 517 108 DL/F0 9/Courier@0 SF
X(MAIN prog : prog.c ;)90 130.8 Q(DEPENDS exe : prog ;)100.8 141.6 Q
X(LINK prog : prog.o ;)100.8 152.4 Q(DEPENDS prog : prog.o ;)111.6 163.2 Q
X(OBJECT prog.o : prog.c ;)100.8 174 Q(CC prog.o : prog.c ;)111.6 184.8 Q
X(DEPENDS prog.o : prog.c ;)122.4 195.6 Q(LIBS prog : libaux.a ;)90 217.2 Q
X(DEPENDS prog : libaux.a ;)100.8 228 Q(NEEDLIBS on prog = libaux.a ;)100.8
X238.8 Q(LIBRARY libaux.a : compile.c gram.y scan.c ;)90 260.4 Q(DEPENDS libaux\
X.a : libaux.a\(compile.o\) libaux.a\(gram.o\) libaux.a\(scan.o\) ;)100.8 271.2
XQ(DEPENDS libaux.a\(compile.o\) : compile.o ;)100.8 282 Q
X(OBJECT compile.o : compile.c ;)100.8 292.8 Q(CC compile.o : compile.c ;)111.6
X303.6 Q(DEPENDS compile.o : compile.c)122.4 314.4 Q
X(DEPENDS libaux.a\(gram.o\) : gram.o ;)100.8 325.2 Q(OBJECT gram.o : gram.y ;)
X100.8 336 Q(CC gram.o : gram.c ;)111.6 346.8 Q(DEPENDS gram.o : gram.c)122.4
X357.6 Q(YACC gram.c : gram.y ;)111.6 368.4 Q(DEPENDS gram.c gram.h : gram.y ;)
X122.4 379.2 Q(INCLUDES gram.c : gram.h ;)122.4 390 Q
X(DEPENDS libaux.a\(scan.o\) : scan.o ;)100.8 400.8 Q(OBJECT scan.o : scan.c ;)
X100.8 411.6 Q(CC scan.o : scan.c ;)111.6 422.4 Q(DEPENDS scan.o : scan.c)122.4
X433.2 Q(ARCHIVE libaux.a : compile.o gram.o scan.o ;)100.8 444 Q
X(TEMPORARY compile.o gram.o scan.o ;)100.8 454.8 Q 95 466.8 90 466.8 DL 97
X466.8 92 466.8 DL 102 466.8 97 466.8 DL 107 466.8 102 466.8 DL 112 466.8 107
X466.8 DL 117 466.8 112 466.8 DL 122 466.8 117 466.8 DL 127 466.8 122 466.8 DL
X132 466.8 127 466.8 DL 137 466.8 132 466.8 DL 142 466.8 137 466.8 DL 147 466.8
X142 466.8 DL 152 466.8 147 466.8 DL 157 466.8 152 466.8 DL 162 466.8 157 466.8
XDL 167 466.8 162 466.8 DL 172 466.8 167 466.8 DL 177 466.8 172 466.8 DL 182
X466.8 177 466.8 DL 187 466.8 182 466.8 DL 192 466.8 187 466.8 DL 197 466.8 192
X466.8 DL 202 466.8 197 466.8 DL 207 466.8 202 466.8 DL 212 466.8 207 466.8 DL
X217 466.8 212 466.8 DL 222 466.8 217 466.8 DL 227 466.8 222 466.8 DL 232 466.8
X227 466.8 DL 237 466.8 232 466.8 DL 242 466.8 237 466.8 DL 247 466.8 242 466.8
XDL 252 466.8 247 466.8 DL 257 466.8 252 466.8 DL 262 466.8 257 466.8 DL 267
X466.8 262 466.8 DL 272 466.8 267 466.8 DL 277 466.8 272 466.8 DL 282 466.8 277
X466.8 DL 287 466.8 282 466.8 DL 292 466.8 287 466.8 DL 297 466.8 292 466.8 DL
X302 466.8 297 466.8 DL 307 466.8 302 466.8 DL 312 466.8 307 466.8 DL 317 466.8
X312 466.8 DL 322 466.8 317 466.8 DL 327 466.8 322 466.8 DL 332 466.8 327 466.8
XDL 337 466.8 332 466.8 DL 342 466.8 337 466.8 DL 347 466.8 342 466.8 DL 352
X466.8 347 466.8 DL 357 466.8 352 466.8 DL 362 466.8 357 466.8 DL 367 466.8 362
X466.8 DL 372 466.8 367 466.8 DL 377 466.8 372 466.8 DL 382 466.8 377 466.8 DL
X387 466.8 382 466.8 DL 392 466.8 387 466.8 DL 397 466.8 392 466.8 DL 402 466.8
X397 466.8 DL 407 466.8 402 466.8 DL 412 466.8 407 466.8 DL 417 466.8 412 466.8
XDL 422 466.8 417 466.8 DL 427 466.8 422 466.8 DL 432 466.8 427 466.8 DL 437
X466.8 432 466.8 DL 442 466.8 437 466.8 DL 447 466.8 442 466.8 DL 452 466.8 447
X466.8 DL 457 466.8 452 466.8 DL 462 466.8 457 466.8 DL 467 466.8 462 466.8 DL
X472 466.8 467 466.8 DL 477 466.8 472 466.8 DL 482 466.8 477 466.8 DL 487 466.8
X482 466.8 DL 492 466.8 487 466.8 DL 497 466.8 492 466.8 DL 502 466.8 497 466.8
XDL 507 466.8 502 466.8 DL 512 466.8 507 466.8 DL 517 466.8 512 466.8 DL 522
X466.8 517 466.8 DL/F1 10/Times-Roman@0 SF(Figure 2 \212 Rule e)186.125 490.8 Q
X-.15(xe)-.15 G(cution for the e).15 E(xample rule in)-.15 E -.2(vo)-.4 G
X(cations).2 E 1.039(LIBS is a rule that arranges for)90 514.8 R/F2 10
X/Times-Bold@0 SF(libaux.a)3.538 E F1 1.038(to become a dependenc)3.538 F 3.538
X(yo)-.15 G(f)371.432 514.8 Q F2(pr)3.538 E(og)-.18 E F1 3.538(,a)C 1.038
X(nd it sets the tar)408.598 514.8 R(get-speci\214c)-.18 E -.25(va)90 526.8 S
X1.096(riable NEEDLIBS to let the actions of LINK kno).25 F 3.596(wt)-.25 G(hat)
X317.944 526.8 Q F2(libaux.a)3.597 E F1 1.097
X(should be included on the link com-)3.597 F(mand line.)90 538.8 Q
X(LIBS has no actions of its o)5 E(wn.)-.25 E(LIBRAR)90 555 Q 2.79(Yi)-.65 G
X2.79(sar)138.81 555 S .289(ule that sets up the \(some)156.05 555 R .289
X(what complicated\) dependencies between the library)-.25 F F2(libaux.a)2.789 E
XF1 2.789(,i)C(ts)515.33 555 Q .167
X(members, and the temporary object modules that are to be its members.)90 567 R
X.167(It calls OBJECT to set up the rela-)5.167 F .65(tionship between each of \
Xthe temporary object modules and their source \214les.)90 579 R .65
X(It also calls the ARCHIVE)5.65 F(rule to handle the archi)90 591 Q
X(ving of the temporary object modules into)-.25 E F2(libaux.a)2.5 E F1(.)A 2.5
X(Am)90 607.2 S(ore complete list of rule in)107.5 607.2 Q -.2(vo)-.4 G
X(cations seen by Jam for this e).2 E(xample is gi)-.15 E -.15(ve)-.25 G 2.5(ni)
X.15 G 2.5(nF)408.54 607.2 S(igure 2.)421.6 607.2 Q .014
X(Probably lost in this litan)90 623.4 R 2.514(yo)-.15 G 2.515(fr)202.99 623.4 S
X.015(ules are some important features:)212.165 623.4 R .015
X(the OBJECT rule, when presented with the)5.015 F .527(task of making a \231.o\
X\232 \214le from a \231.y\232 \214le, called both the CC and Y)90 635.4 R -.4
X(AC)-1.2 G 3.027(Cr).4 G 3.027(ules. Note)393.185 635.4 R .527
X(that this is consider)3.027 F(-)-.2 E 1.117
X(ably easier and more deterministic than)90 647.4 R/F3 10/Times-Italic@0 SF
X(mak)3.617 E(e)-.1 E F1 2.217 -.55('s a)D 1.118
X(pproach of making a \231.o\232 from whate).55 F -.15(ve)-.25 G 3.618(rh).15 G
X1.118(appens to be)469.774 647.4 R -.2(av)90 659.4 S 4.267(ailable. Also,)-.05
XF 1.767(note that the Y)4.267 F -.4(AC)-1.2 G 4.266(Cr).4 G 1.766(ule took adv)
X251.59 659.4 R 1.766(antage of the INCLUDES b)-.25 F 1.766(uilt-in to mak)-.2 F
X4.266(es)-.1 G 1.766(ure the)492.744 659.4 R
X(dependencies on the generated \214le are accurately re)90 671.4 Q(gistered.)
X-.15 E(Actually)90 687.6 Q 3.479(,t)-.65 G .979
X(he rule de\214nitions include a fe)132.549 687.6 R 3.479(wm)-.25 G .979
X(ore machinations to gi)277.043 687.6 R 1.28 -.15(ve s)-.25 H .98(pecial v).15
XF .98(ariables sensible def)-.25 F(aults.)-.1 E -.15(Fo)90 699.6 S 4.64(rs).15
XG 2.139(ource code, $\(SEARCH\) is set to $\(SEARCH_SOURCE\); for object \214l\
Xes, $\(LOCA)112.27 699.6 R 2.139(TE\) is set to)-1.11 F($\(LOCA)90 711.6 Q
X1.111(TE_OBJECT\); for C source \214les, $\(HDRSCAN\) is set to the e)-1.11 F
X1.111(xample pattern mentioned abo)-.15 F -.15(ve)-.15 G(,).15 E(and $\(HDRR)90
X723.6 Q(ULE\) is set to \231HDRR)-.4 E(ULE\232, the generic header)-.4 E
X(-handling rule de\214ned in the Jambase \214le.)-.2 E EP
X%%Page: 8 8
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 11/Times-Bold@0 SF 2.75(8. Implementation)90 96 R/F1 10/Times-Roman@0 SF
X.618(The weight of Jam')90 112.2 R 3.118(si)-.55 G .618(mplementation is e)
X179.132 112.2 R -.15(ve)-.25 G .618(nly di).15 F .618
X(vided between its rule-processing subsystem \(dri)-.25 F -.15(ve)-.25 G 3.117
X(nb).15 G 3.117(ya)509.443 112.2 S/F2 10/Times-Italic@0 SF(yacc)90 124.2 Q F1
X(\(1\) grammar\), its recursi)A .3 -.15(ve b)-.25 H
X(inding and scanning subsystem, and its recursi).15 E .3 -.15(ve b)-.25 H
X(uild subsystem.)-.05 E .806(The rule-processing subsystem is entirely system \
Xindependent, only setting in-memory v)90 140.4 R .807(ariables, b)-.25 F
X(uilding)-.2 E 1.494(the dependenc)90 152.4 R 3.994(yg)-.15 G 1.494
X(raph, and associating update actions with tar)162.818 152.4 R 3.994(gets. The)
X-.18 F F2(yacc)3.994 E F1 1.494(grammar is less than 200)3.994 F(lines.)90
X164.4 Q .983(The recursi)90 180.6 R 1.283 -.15(ve b)-.25 H .983
X(inding and scanning subsystem is mostly system independent, b).15 F .984
X(ut calls system-dependent)-.2 F
X(routines to time-stamp \214les and to manipulate \214le names.)90 192.6 Q .754
X(The recursi)90 208.8 R 1.054 -.15(ve b)-.25 H .754
X(uild subsystem is mostly system independent, b)-.05 F .754
X(ut calls system-speci\214c routines to e)-.2 F -.15(xe)-.15 G(cute).15 E
X(shell commands \(which are system-speci\214c as well\).)90 220.8 Q 1.028
X(The system dependencies are hidden through three interf)90 237 R 1.028
X(aces: one to time-stamp \214les; one to manipulate)-.1 F
X(\214le names; and one to e)90 249 Q -.15(xe)-.15 G(cute shell commands.).15 E
X.524(The \214le time-stamp interf)90 265.2 R .524(ace has tw)-.1 F 3.024(ol)-.1
XG .524(ayers: a higher one that asks about indi)247.364 265.2 R .524
X(vidual \214les; and a lo)-.25 F .523(wer one)-.25 F .701
X(that scans directories and library archi)90 277.2 R -.15(ve)-.25 G 3.201(sw)
X.15 G 3.201(hole. The)269.316 277.2 R .701(latter is more ef)3.201 F .702
X(\214cient, and all current implementa-)-.25 F
X(tions \(UNIX, VMS, NT\) are coded ag)90 289.2 Q(ainst it.)-.05 E .479
X(The \214le name manipulation interf)90 305.4 R .479(ace consists of tw)-.1 F
X2.978(or)-.1 G .478(outines: one to break a \214le name do)309.71 305.4 R .478
X(wn into its com-)-.25 F 1.382(ponents and one to b)90 317.4 R 1.383
X(uild a \214le name from its components.)-.2 F 1.383
X(These are quite simple \212 e)6.383 F 1.383(xcept on VMS,)-.15 F
X(where concatenating path names is black art.)90 329.4 Q 1.049
X(The shell-command interf)90 345.6 R 1.049(ace currently approximates the UNIX)
X-.1 F F2(system)3.548 E F1 1.048(\(3\) call interf)B 1.048
X(ace, with an addition)-.1 F(for catching interrupts.)90 357.6 Q .649
X(Jam achie)90 373.8 R -.15(ve)-.25 G 3.149(si).15 G .649
X(ts functionality while going sparingly on features.)149.218 373.8 R .65
X(It has only four \215ags \(mostly to do with)5.649 F(deb)90 385.8 Q .292
X(ugging\), six b)-.2 F .292(uilt-in rules \(DEPENDS, INCLUDES, ECHO, NO)-.2 F
X.292(TIME, NOCARE, TEMPORAR)-.4 F .292(Y\) and)-.65 F .282(six special v)90
X397.8 R .283(ariables \($\(>\), $\(<\), $\(SEARCH\), $\(LOCA)-.25 F .283
X(TE\), $\(HDRSCAN\), $\(HDRR)-1.11 F 2.783(ULE\)\). The)-.4 F .283(whole of)
X2.783 F .079(Jam for UNIX is under 5,000 lines of code, e)90 409.8 R(xclusi)
X-.15 E .379 -.15(ve o)-.25 H 2.578(fH).15 G .078(enry Spencer')324.438 409.8 R
X(s)-.55 E F2 -.37(re)2.578 G -.1(ge)-.03 G(xp)-.1 E F1 .078(\(3\) re)B(gular)
X-.15 E(-e)-.2 E .078(xpression code)-.15 F(\(about another 1,300 lines\).)90
X421.8 Q 3.329(Ad)90 438 S .829(esign goal of Jam w)105.549 438 R .829
X(as portability)-.1 F 3.329(,s)-.65 G .83
X(peci\214cally so that the same mechanism could be used to b)251.153 438 R .83
X(uild the)-.2 F .365(same system on dif)90 450 R .365(ferent platforms.)-.25 F
X.364(Jam scores well in this cate)5.365 F .364(gory: the OS interf)-.15 F .364
X(ace is constricted, lea)-.1 F(v-)-.2 E .678(ing the b)90 462 R .679
X(ulk of the system dependencies in the Jambase \214le.)-.2 F(Ev)5.679 E .679
X(en the Jambase \214le is some)-.15 F .679(what portable,)-.25 F .194
X(with only the \214lename syntax and the actual update commands ha)90 474 R
X.193(ving to change between UNIX and VMS.)-.2 F(Jam\214le \214les themselv)90
X486 Q(es usually contain nothing system-speci\214c.)-.15 E F0 2.75(9. P)90 510
XR(erf)-.22 E(ormance)-.275 E F1 .17(Used to b)90 526.2 R .17
X(uild from scratch a lar)-.2 F .17(ge commerical softw)-.18 F .17
X(are system \(the INGRES relational DBMS\), lapse time)-.1 F(for Jam breaks do)
X90 538.2 Q(wn as follo)-.25 E(ws \(on an HP9000/710\):)-.25 E/F3 10/Courier@0
XSF(parsing 5,000 lines of Jamfiles)130 554.4 Q(16 seconds)418 554.4 Q
X(stat\(\)'ing 12,000 source files)130 566.4 Q 6(1m)418 566.4 S(inute)436 566.4
XQ(scanning 12,000 source files for headers)130 578.4 Q 6(9m)418 578.4 S(inutes)
X436 578.4 Q(actual building \(compiling, linking, etc\))130 590.4 Q(12 hours)
X418 590.4 Q F1 .702(The simple conclusion is that Jam')90 610.8 R 3.202(sp)-.55
XG .702(erformance in inconsequential.)244.212 610.8 R .701(When e)5.701 F -.15
X(ve)-.25 G .701(rything is up-to-date, only).15 F(fe)90 622.8 Q 2.595(wi)-.25 G
X(mpro)110.115 622.8 Q -.15(ve)-.15 G .095(ments could be made.).15 F F2(stat)
X5.095 E F1 .095(\(\)'ing \214les is essentially una)B -.2(vo)-.2 G .095
X(idable without resorting to other tech-).2 F 1.609
X(niques for determining outdated tar)90 634.8 R 4.109(gets. Scanning)-.18 F
X1.608(source \214les could be a)4.109 F -.2(vo)-.2 G 1.608
X(ided by caching header).2 F(-\214le)-.2 E(dependenc)90 646.8 Q 2.828(yi)-.15 G
X.328(nformation in state \214les.)143.218 646.8 R(SunOS)5.328 E F2(mak)2.829 E
X(e)-.1 E F1(and)2.829 E F2(nmak)2.829 E(e)-.1 E F1 .329(use this approach.)
X2.829 F .329(The only other recourse)5.329 F(is to hammer on the)90 658.8 Q F2
X-.37(re)2.5 G -.1(ge)-.03 G(xp)-.1 E F1(implementation.)2.5 E 1.428
X(The real performance limitation is in actual b)90 675 R 1.427(uilding time.)
X-.2 F 1.427(Jam does not yet support parallel command)6.427 F -.15(exe)90 687 S
X.934(cution, which on a lar).15 F .934(ge SMP system can reduce b)-.18 F .935
X(uild time by a f)-.2 F .935(actor of 5 or more.)-.1 F .935(This feature is)
X5.935 F(anticipated.)90 699 Q EP
X%%Page: 9 9
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 11/Times-Bold@0 SF 2.75(10. Comparisons)90 96 R/F1 10/Times-Roman@0 SF
X(Jam')90 112.2 Q 3.133(sp)-.55 G(er)120.913 112.2 Q(-tar)-.2 E .633(get v)-.18
XF .633(ariables are a con)-.25 F -.15(ve)-.4 G .633
X(nience approached only by SunOS).15 F/F2 10/Times-Italic@0 SF(mak)3.133 E(e)
X-.1 E F1 1.732 -.55('s \231)D(tar).55 E .632(get := macro = v)-.18 F(alue\232)
X-.25 E 3.447(syntax. Both)90 124.2 R .947(Jam and SunOS)3.447 F F2(mak)3.447 E
X(e)-.1 E F1(mak)3.447 E 3.447(eu)-.1 G .947(se of the v)271.139 124.2 R .947
X(alue when updating the tar)-.25 F .948(get, b)-.18 F .948(ut Jam gets added)
X-.2 F(mileage out of the f)90 136.2 Q(acility by using the v)-.1 E
X(alue during the binding and header)-.25 E(-\214le scanning.)-.2 E(Jam')90
X152.4 Q 3.749(ss)-.55 G 1.248(earching mechanism is superior to VP)120.419
X152.4 R -1.11(AT)-.92 G 3.748(Hi)1.11 G 3.748(nt)304.188 152.4 S 1.448 -.1
X(wo wa)315.716 152.4 T 3.748(ys: \214rst,).1 F 1.248(it pro)3.748 F 1.248
X(vides not only searching for)-.15 F -.15(ex)90 164.4 S .865(isting tar).15 F
X.865(gets, b)-.18 F .865(ut also binding for ne)-.2 F 3.365(wt)-.25 G(ar)
X264.155 164.4 Q .865(gets; second, Jam')-.18 F 3.365(sS)-.55 G .866
X(EARCH and LOCA)359.34 164.4 R .866(TE v)-1.11 F .866(ariables can be)-.25 F
X.167(set per)90 176.4 R(-tar)-.2 E 2.667(get. GNU)-.18 F F2(mak)2.667 E(e)-.1 E
XF1(allo)2.667 E .167(ws VP)-.25 F -1.11(AT)-.92 G 2.667(Ht)1.11 G 2.667(ob)
X263.202 176.4 S 2.667(es)275.869 176.4 S .166(et selecti)286.866 176.4 R -.15
X(ve)-.25 G(ly).15 E 2.666(,u)-.65 G .166
X(sing patterns, and the patterns could be full)348.638 176.4 R .51
X(\214le names, b)90 188.4 R .51(ut GNU)-.2 F F2(mak)3.01 E(e)-.1 E F1 .51
X(handles the de)3.01 F .51(generate case of separate v)-.15 F .51
X(alues per \214le poorly)-.25 F 5.51(.J)-.65 G(am')460.65 188.4 Q 3.01(sS)-.55
XG(EARCH)488.11 188.4 Q .777(and LOCA)90 200.4 R .777(TE mechanism can mak)-1.11
XF 3.277(et)-.1 G .777(he in)242.925 200.4 R -.2(vo)-.4 G -.1(ke).2 G(r').1 E
X3.276(sd)-.55 G .776(irectory irrele)300.438 200.4 R -.25(va)-.25 G .776
X(nt, which amounts to a complete solu-).25 F(tion.)90 212.4 Q(Jam')90 228.6 Q
X2.767(sp)-.55 G .267(attern-scanning method of header)120.547 228.6 R .267
X(-\214le scanning is f)-.2 F .267(aster than those that of)-.1 F .268
X(\215oad the problem to sepa-)-.25 F .078(rate programs \()90 240.6 R F2(dmak)A
X(e)-.1 E F1(,)A F2(cak)2.578 E(e)-.1 E F1 2.578(,G)C(NU)212.842 240.6 Q F2(mak)
X2.578 E(e)-.1 E F1 2.578(\). It)B .078(is not strictly correct, lik)2.578 F
X2.577(eS)-.1 G(unOS)381.295 240.6 Q F2(mak)2.577 E(e)-.1 E F1 .077(and GNU)
X2.577 F F2(mak)2.577 E(e)-.1 E F1 2.577(,w)C(hich)504.78 240.6 Q .574
X(use the C preprocessor)90 252.6 R 5.574(.J)-.55 G(am')193.946 252.6 Q 3.074
X(sm)-.55 G .575(echanism, dri)223.69 252.6 R -.15(ve)-.25 G 3.075(nb).15 G
X3.075(yp)300.26 252.6 S(er)313.335 252.6 Q(-tar)-.2 E .575(get v)-.18 F .575
X(ariables and user)-.25 F .575(-de\214ned relationships is,)-.2 F(ho)90 264.6 Q
X(we)-.25 E -.15(ve)-.25 G 2.032 -.4(r, q).15 H 1.232(uite \215e).4 F 3.732
X(xible. It)-.15 F 1.231(can handle languages that don')3.732 F 3.731(to)-.18 G
X-.25(ff)341.883 264.6 S 1.231(er a separate preprocessor).25 F 3.731(,a)-.4 G
X3.731(sw)465.817 264.6 S 1.231(ell as lan-)480.658 264.6 R .253(guages where t\
Xhe result of a \214le being included is more than just a simple dependenc)90
X276.6 R 4.054 -.65(y. F)-.15 H .254(or e).5 F .254(xample, when)-.15 F(a)90
X288.6 Q F2(yacc)3.527 E F1 1.027(\214le includes a C header)3.527 F 1.027(-\
X\214le, Jam can be made to understand that the generated C source \214le will)
X-.2 F(include the generated C header)90 300.6 Q 2.5(-\214le. Jam)-.2 F
X(supports these types of arrangements entirely in its language.)2.5 E .693
X(Jam is missing a fe)90 316.8 R 3.193(wf)-.25 G .693(eatures cherished by some)
X182.375 316.8 R F2(mak)3.194 E(e)-.1 E F1 .694
X(users: the ability to run update commands concur)3.194 F(-)-.2 E(rently and f)
X90 328.8 Q(anc)-.1 E 2.5(yv)-.15 G(ariable editing.)161.98 328.8 Q
X(These may appear in future v)5 E(ersions of Jam.)-.15 E F0 2.75
X(11. Discussion)90 345 R F1 .65(The comparison of Jam')90 361.2 R 3.15(sl)-.55
XG .65(anguage with)198.7 361.2 R F2(mak)3.15 E(e)-.1 E F1 1.75 -.55('s i)D 3.15
X(ss).55 G(ome)300.63 361.2 Q .65(what subjecti)-.25 F .95 -.15(ve a)-.25 H .65
X(nd complicated.).15 F .65(As stated in the)5.65 F .001
X(introduction, Jam is an attempt to replace)90 373.2 R F2(mak)2.502 E(e)-.1 E
XF1 1.102 -.55('s r)D .002(ule system with an e).55 F(xpressi)-.15 E .302 -.15
X(ve l)-.25 H .002(anguage that mak).15 F .002(es it pos-)-.1 F
X(sible to describe e)90 385.2 Q
X(xplicitly and cogently the compilation of programs.)-.15 E .563
X(In this respect, Jam is a success.)90 401.4 R -.15(Fo)5.563 G 3.063(rs).15 G
X.563(mall systems, the Jam\214le \214le is often not lar)247.944 401.4 R .563
X(ger than the three lines)-.18 F .217(that made up our e)90 413.4 R 2.717
X(xample. F)-.15 F .217(or lar)-.15 F .217(ge systems, an)-.18 F 2.717(ya)-.15 G
X.217(dded comple)299.623 413.4 R .217
X(xity can be centralized in the Jambase \214le,)-.15 F
X(while the Jam\214le \214le\(s\) in source directories remain simple.)90 425.4
XQ(Jam')90 441.6 Q 2.793(sr)-.55 G .293(ule semantics, that of e)118.903 441.6 R
X.293(xpressing named relationships among \214les, is Jam')-.15 F 2.793(ss)-.55
XG .292(ingle biggest adv)427.236 441.6 R(antage)-.25 E -.15(ove)90 453.6 S
X4.373(ri).15 G 1.873(ts contemporaries.)114.623 453.6 R 1.873(Its po)6.873 F
X1.873(wer and economy of e)-.25 F 1.874(xpression seem unmatched.)-.15 F 1.874
X(There are tw)6.874 F 4.374(oo)-.1 G(ther)506.45 453.6 Q 1.349
X(approaches deserving mention.)90 465.6 R F2(nmak)6.349 E(e)-.1 E F1(and)3.849
XE F2(dmak)3.849 E(e)-.1 E F1(allo)3.849 E 3.848(wn)-.25 G 1.848 -.25(ew o)
X331.992 465.6 T 1.348(perators \(replacements for the simple \231:\232).25 F
X(dependenc)90 477.6 Q 3.801(ys)-.15 G 1.302
X(tatement\) to be de\214ned as macros, and these can be used to create ne)
X145.301 477.6 R 3.802(wr)-.25 G 1.302(elationship types.)450.698 477.6 R
X(Unfortunately)90 489.6 Q 2.59(,t)-.65 G .09(he number of a)153.32 489.6 R -.25
X(va)-.2 G .09
X(ilable \231operator\232 characters is limited, and the coding of the macros w)
X.25 F(ould)-.1 E .744(curl the e)90 501.6 R(yebro)-.15 E .744(ws of e)-.25 F
X-.15(ve)-.25 G 3.244(ns).15 G(easoned)202.61 501.6 Q F2(sendmail)3.245 E F1
X(hack)3.245 E(ers.)-.1 E F2(cook)5.745 E F1(,)A F2(cak)3.245 E(e)-.1 E F1 3.245
X(,P)C .745(lan 9)370.255 501.6 R F2(mk)3.245 E F1 3.245(,a)C .745(nd NET2)
X415.81 501.6 R F2(mak)3.245 E(e)-.1 E F1 .745(promote a)3.245 F(dif)90 513.6 Q
X.55(ferent approach: that of de\214ning v)-.25 F .55
X(ariables and then #include'ing \231recipes\232 \(other)-.25 F F2(mak)3.05 E(e)
X-.1 E F1 .55(\214les\) that de\214ne)3.05 F .752(the relationships.)90 525.6 R
X.752(The recipes are the approximate equi)5.752 F -.25(va)-.25 G .753
X(lent of Jam rules, using pass-by-name v).25 F(ariables.)-.25 E .959
X(This scheme w)90 537.6 R .959(orks, b)-.1 F .959
X(ut it is an ugly ordeal to try to reco)-.2 F -.15(ve)-.15 G 3.458(rw).15 G
X.958(ith a preprocessor the functionality that is)350.162 537.6 R
X(lacking in a language.)90 549.6 Q .745(The Jam language turns out to be f)90
X565.8 R .745(airly straightforw)-.1 F .745(ard to program.)-.1 F -.4(Wi)5.745 G
X.745(th its reliance on k).4 F -.15(ey)-.1 G -.1(wo).15 G .745(rds rather).1 F
X.349(than special characters and its use of a \231;\232 to terminate statement\
Xs, it is easier reading than most)90 577.8 R F2(mak)2.849 E(e)-.1 E F1(syn-)
X2.848 E(tax.)90 589.8 Q(Abandoning)90 606 Q F2(mak)2.505 E(e)-.1 E F1 .005
X(syntax w)2.505 F .005(as an easy decision: e)-.1 F -.15(ve)-.25 G 2.505(nt).15
XG .005(hose ne)306.62 606 R(w)-.25 E F2(mak)2.505 E(e)-.1 E F1 2.506(st)C .006
X(hat understand traditional)376.546 606 R F2(mak)2.506 E(e)-.1 E F1(syn-)2.506
XE 1.092(tax get their added functionality through incompatible syntax.)90 618 R
X1.091(If compatibility with)6.091 F F2(mak)3.591 E(e)-.1 E F1 1.091
X(is the priority)3.591 F(,)-.65 E(users can just use)90 630 Q F2(mak)2.5 E(e)
X-.1 E F1 5(.I)C 2.5(fu)194.04 630 S(sers w)204.87 630 Q
X(ant greater functionality)-.1 E 2.5(,t)-.65 G(he)333.26 630 Q 2.5(yc)-.15 G
X(an')354.49 630 Q 2.5(tu)-.18 G(se v)377.36 630 Q(anilla)-.25 E F2(mak)2.5 E(e)
X-.1 E F1(an)2.5 E(yw)-.15 E(ay)-.1 E(.)-.65 E 1.509
X(The proof of Jam is in the pudding \(sorry)90 646.2 R 4.009(...\): it)-.65 F
X1.51(is w)4.009 F 1.51(orth mentioning that the timing information gi)-.1 F
X-.15(ve)-.25 G(n).15 E(abo)90 658.2 Q 1.062 -.15(ve i)-.15 H 3.262(sf).15 G
X.762(or a single, non-recursi)130.104 658.2 R 1.061 -.15(ve i)-.25 H -1.9 -.4
X(nv o).15 H .761
X(cation of Jam to compile 12,000 source \214les scattered throughout).4 F 1.495
X(300 directories, producing 7,000 intermediate tar)90 670.2 R 1.495
X(gets and 1,000 deli)-.18 F -.15(ve)-.25 G 1.495(rable \214les.).15 F 1.495
X(Each source directory)6.495 F .218(contains a single Jam\214le with an a)90
X682.2 R -.15(ve)-.2 G .218(rage of 1.5 w).15 F .218
X(ords per source \214le \(including the source \214le name\).)-.1 F(The)5.217 E
X(author kno)90 694.2 Q(ws of no other)-.25 E F2(mak)2.5 E(e)-.1 E F1
X(that can approach such completeness with such economy)2.5 E(.)-.65 E EP
X%%Page: 10 10
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 11/Times-Bold@0 SF 2.75(12. A)90 96 R -.11(va)-1.1 G(ilability).11 E/F1 10
X/Times-Roman@0 SF .643(Jam is freely a)90 112.2 R -.25(va)-.2 G .643
X(ilable in V).25 F .643(olume 27 of the comp.sources.unix archi)-1.29 F -.15
X(ve)-.25 G 3.144(s. It).15 F .644(is kno)3.144 F .644(wn to compile and w)-.25
XF(ork)-.1 E .452(on VMS \(Alpha and V)90 124.2 R .451(AX\) and the follo)-1.35
XF .451(wing v)-.25 F .451(ariants of UNIX: BSD/386, OSF/1, DGUX 5.4, HPUX 9.0,)
X-.25 F .462
X(AIX, IRIX 5.0, PTX V2.1.0, SunOS 4, Solaris 2, Ultrix 4.2, and Linux.)90 136.2
XR .462(Support for NT is not part of that)5.462 F(initial release b)90 148.2 Q
X(ut is a)-.2 E -.25(va)-.2 G(ilable from the author).25 E(.)-.55 E F0 2.75
X(13. Bibliograph)90 172.2 R(y)-.165 E F1([Brokk)90 188.4 Q(en, 1994])-.1 E .225
X(Frank B. Brokk)115 200.4 R .225(en and Karel K)-.1 F .225
X(ubat, \231ICMAKE \212 the Intelligent C-lik)-.15 F 2.724(eM)-.1 G(AKEr)416.254
X200.4 Q 2.724(,o)-.4 G 2.724(rt)449.958 200.4 S .224(he ICce MAKE)458.792 200.4
XR(utility\232, Linux Sources, 1994)115 212.4 Q([BSD, 1991])90 228.6 Q
X(BSD NET2 mak)115 240.6 Q
X(e\(1\) manual page, BSD NET2 documentation, July 1991.)-.1 E([Feldman, 1986])
X90 256.8 Q .57(S. I. Feldman, \231Mak)115 268.8 R 3.071(e\212AP)-.1 G .571
X(rogram for Maintaining Computer Programs\232, BSD NET2 documenta-)234.703
X268.8 R(tion, April 1986 \(re)115 280.8 Q(vision\).)-.25 E([Flandrena])90 297 Q
X(R. Flandrena, \231Plan 9 Mk\214les\232, a)115 309 Q -.25(va)-.2 G
X(ilable via anon).25 E(ymous FTP from plan9.att.com.)-.15 E([F)90 325.2 Q -.25
X(ow)-.15 G(ler).25 E 2.5(,1)-.4 G(985])130.86 325.2 Q 1.447(Glenn F)115 337.2 R
X-.25(ow)-.15 G(ler).25 E 3.947<2c99>-.4 G 1.447(The F)181.804 337.2 R 1.447
X(ourth Generation Mak)-.15 F 1.446
X(e\232, Proceedings of the USENIX Summer Conference,)-.1 F(June 1985.)115 349.2
XQ([Miller)90 365.4 Q 2.5(,1)-.4 G(993])127.93 365.4 Q(Peter Miller)115 377.4 Q
X2.5<2c99>-.4 G(Cook \212 A File Construction T)172.09 377.4 Q(ool\232, V)-.8 E
X(olume 26, comp.sources.unix archi)-1.29 E -.15(ve)-.25 G(s, 1993.).15 E([Seiw)
X90 393.6 Q(ald, 1993])-.1 E .386(Christopher Seiw)115 405.6 R .386
X(ald, Jam\(1\) and Jambase\(5\) manual pages, V)-.1 F .386
X(olume 27, comp.sources.unix archi)-1.29 F -.15(ve)-.25 G(s,).15 E(1993.)115
X417.6 Q([Spencer)90 433.8 Q 2.5(,1)-.4 G(986])135.14 433.8 Q(Henry Spencer)115
X445.8 Q 2.5(,R)-.4 G -.15(eg)185.97 445.8 S -.15(ex).15 G 2.5(pc).15 G
X(ode and comment, comp.sources.unix archi)216.49 445.8 Q -.15(ve)-.25 G
X(s, 1986.).15 E([Stallman, 1991])90 462 Q .124
X(Richard M. Stallman and Roland McGrath, \231GNU Mak)115 474 R 2.624(e\212AP)
X-.1 G .123(rogram for Directed Recompilation\232,)373.33 474 R(Free Softw)115
X486 Q(are F)-.1 E(oundation, 1991)-.15 E([Somogyi, 1987])90 502.2 Q .771
X(Zoltan Somogyi, \231Cak)115 514.2 R .771(e, a Fifth Generation V)-.1 F .772
X(ersion of Mak)-1.11 F .772(e\232, Australian Unix System User Group)-.1 F(Ne)
X115 526.2 Q(wsletter)-.25 E 2.5(,A)-.4 G(pril 1987.)169.89 526.2 Q([Sun, 1989])
X90 542.4 Q .351(Sun Microssytems Corporation, SunOS mak)115 554.4 R .351
X(e\(1\) manual page, SunOS 4.1.2 documentation, Septem-)-.1 F(ber 1989.)115
X566.4 Q([V)90 582.6 Q(adura, 1990])-1.11 E(Dennis V)115 594.6 Q(adura, dmak)
X-1.11 E(e\(1\) manual page, V)-.1 E(olume 27, comp.sources.misc archi)-1.29 E
X-.15(ve)-.25 G(s, 1990.).15 E EP
X%%Trailer
Xend
X%%EOF
END_OF_FILE
if test 70543 -ne `wc -c <'Paper.ps'`; then
echo shar: \"'Paper.ps'\" unpacked with wrong size!
fi
# end of 'Paper.ps'
fi
if test -f 'filent.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'filent.c'\"
else
echo shar: Extracting \"'filent.c'\" \(6563 characters\)
sed "s/^X//" >'filent.c' <<'END_OF_FILE'
X/*
X * Copyright 1993, 1995 Christopher Seiwald.
X *
X * This file is part of Jam - see jam.c for Copyright information.
X */
X
X# ifdef NT
X
X# include "jam.h"
X# include "filesys.h"
X
X# include <io.h>
X
X/*
X * fileunix.c - manipulate file names and scan directories on UNIX
X *
X * External routines:
X *
X * file_parse() - split a file name into dir/base/suffix/member
X * file_build() - build a filename given dir/base/suffix/member
X * file_dirscan() - scan a directory for files
X * file_time() - get timestamp of file, if not done by file_dirscan()
X * file_archscan() - scan an archive for files
X *
X * File_parse() and file_build() just manipuate a string and a structure;
X * they do not make system calls.
X *
X * File_dirscan() and file_archscan() call back a caller provided function
X * for each file found. A flag to this callback function lets file_dirscan()
X * and file_archscan() indicate that a timestamp is being provided with the
X * file. If file_dirscan() or file_archscan() do not provide the file's
X * timestamp, interested parties may later call file_time().
X *
X * 12/21/94 (wingerd) Use backslashes for pathnames - the NT way.
X * 02/23/95 (wingerd) Compilers on NT can handle "/" in pathnames, so we
X * should expect hdr searches to come up with strings
X * like "thing/thing.h". So we need to test for "/" as
X * well as "\" when parsing pathnames.
X * 02/14/95 (seiwald) - parse and build /xxx properly
X */
X
X/*
X * file_parse() - split a file name into dir/base/suffix/member
X */
X
Xvoid
Xfile_parse( file, f )
Xchar *file;
XFILENAME *f;
X{
X char *p, *p1;
X char *end;
X
X memset( (char *)f, 0, sizeof( *f ) );
X
X /* Look for <grist> */
X
X if( file[0] == '<' && ( p = strchr( file, '>' ) ) )
X {
X f->f_grist.ptr = file + 1;
X f->f_grist.len = p - file - 1;
X file = p + 1;
X }
X
X /* Look for dir/ */
X
X p = strrchr( file, '\\' );
X p1 = strrchr( file, '/' );
X p = p1 > p ? p1 : p
X
X /* Special case for \ - dirname is \, not "" */
X
X if( p )
X {
X f->f_dir.ptr = file;
X f->f_dir.len = p == file ? 1 : p - file;
X file = p + 1;
X }
X
X end = file + strlen( file );
X
X /* Look for (member) */
X
X if( ( p = strchr( file, '(' ) ) && end[-1] == ')' )
X {
X f->f_member.ptr = p + 1;
X f->f_member.len = end - p - 2;
X end = p;
X }
X
X /* Look for .suffix */
X
X if( ( p = strchr( file, '.' ) ) && p < end )
X {
X f->f_suffix.ptr = p;
X f->f_suffix.len = end - p;
X end = p;
X }
X
X /* Leaves base */
X
X f->f_base.ptr = file;
X f->f_base.len = end - file;
X}
X
X/*
X * file_build() - build a filename given dir/base/suffix/member
X */
X
Xvoid
Xfile_build( f, file )
XFILENAME *f;
Xchar *file;
X{
X if( f->f_grist.len )
X {
X *file++ = '<';
X memcpy( file, f->f_grist.ptr, f->f_grist.len );
X file += f->f_grist.len;
X *file++ = '>';
X }
X
X /* Don't prepend root if it's . or directory is rooted */
X
X if( f->f_root.len
X && !( f->f_root.len == 1 && f->f_root.ptr[0] == '.' )
X && !( f->f_dir.len && f->f_dir.ptr[0] == '\\' )
X && !( f->f_dir.len && f->f_dir.ptr[0] == '/' )
X && !( f->f_dir.len && f->f_dir.ptr[1] == ':' ) )
X {
X memcpy( file, f->f_root.ptr, f->f_root.len );
X file += f->f_root.len;
X *file++ = '\\';
X }
X
X if( f->f_dir.len )
X {
X memcpy( file, f->f_dir.ptr, f->f_dir.len );
X file += f->f_dir.len;
X }
X
X /* Put \ between dir and file */
X
X if( f->f_dir.len && ( f->f_base.len || f->f_suffix.len ) )
X {
X /* Special case for dir \ : don't add another \ */
X
X if( !( f->f_dir.len == 1 && f->f_dir.ptr[0] == '\\' ) )
X *file++ = '\\';
X }
X
X if( f->f_base.len )
X {
X memcpy( file, f->f_base.ptr, f->f_base.len );
X file += f->f_base.len;
X }
X
X if( f->f_suffix.len )
X {
X memcpy( file, f->f_suffix.ptr, f->f_suffix.len );
X file += f->f_suffix.len;
X }
X
X if( f->f_member.len )
X {
X *file++ = '(';
X memcpy( file, f->f_member.ptr, f->f_member.len );
X file += f->f_member.len;
X *file++ = ')';
X }
X *file = 0;
X}
X
X/*
X * file_dirscan() - scan a directory for files
X */
X
Xvoid
Xfile_dirscan( dir, func )
Xchar *dir;
Xvoid (*func)();
X{
X FILENAME f;
X char filespec[ MAXPATH ];
X char filename[ MAXPATH ];
X long handle;
X struct _finddata_t fileinfo[1];
X
X /* First enter directory itself */
X
X memset( (char *)&f, '\0', sizeof( f ) );
X
X f.f_dir.ptr = dir;
X f.f_dir.len = strlen(dir);
X
X dir = *dir ? dir : ".";
X
X /* Special case \ : enter it */
X
X if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '\\' )
X (*func)( dir, 0 /* not stat()'ed */, (time_t)0 );
X
X /* Now enter contents of directory */
X
X sprintf( filespec, "%s/*", dir );
X
X if( ( handle = _findfirst( filespec, fileinfo ) ) < 0 )
X return;
X
X if( DEBUG_BINDSCAN )
X printf( "scan directory %s\n", dir );
X
X while( _findnext( handle, fileinfo ) >= 0 )
X {
X f.f_base.ptr = fileinfo->name;
X f.f_base.len = strlen( fileinfo->name );
X
X file_build( &f, filename );
X
X (*func)( filename, 1 /* stat()'ed */, fileinfo->time_write );
X }
X
X _findclose( handle );
X}
X
X/*
X * file_time() - get timestamp of file, if not done by file_dirscan()
X */
X
Xint
Xfile_time( filename, time )
Xchar *filename;
Xtime_t *time;
X{
X return 0;
X}
X
X/*
X * file_archscan() - scan an archive for files
X */
X
X/* Straight from SunOS */
X
X#define ARMAG "!<arch>\n"
X#define SARMAG 8
X
X#define ARFMAG "`\n"
X
Xstruct ar_hdr {
X char ar_name[16];
X char ar_date[12];
X char ar_uid[6];
X char ar_gid[6];
X char ar_mode[8];
X char ar_size[10];
X char ar_fmag[2];
X};
X
X# define SARFMAG 2
X# define SARHDR sizeof( struct ar_hdr )
X
Xvoid
Xfile_archscan( archive, func )
Xchar *archive;
Xvoid (*func)();
X{
X struct ar_hdr ar_hdr;
X char buf[ MAXPATH ];
X long offset;
X int fd;
X
X if( ( fd = open( archive, O_RDONLY, 0 ) ) < 0 )
X return;
X
X if( read( fd, buf, SARMAG ) != SARMAG ||
X strncmp( ARMAG, buf, SARMAG ) )
X {
X close( fd );
X return;
X }
X
X offset = SARMAG;
X
X if( DEBUG_BINDSCAN )
X printf( "scan archive %s\n", archive );
X
X while( read( fd, &ar_hdr, SARHDR ) == SARHDR &&
X !memcmp( ar_hdr.ar_fmag, ARFMAG, SARFMAG ) )
X {
X char lar_name[16];
X long lar_date;
X long lar_size;
X char *c;
X
X strncpy( lar_name, ar_hdr.ar_name, sizeof(ar_hdr.ar_name) );
X c = lar_name + sizeof( lar_name );
X while( *--c == ' ' || *c == '\\' || *c == '/' )
X ;
X *++c = '\0';
X
X sscanf( ar_hdr.ar_date, "%ld", &lar_date );
X sscanf( ar_hdr.ar_size, "%ld", &lar_size );
X
X sprintf( buf, "%s(%s)", archive, lar_name );
X
X (*func)( buf, 1 /* time valid */, (time_t)lar_date );
X
X offset += SARHDR + ( ( lar_size + 1 ) & ~1 );
X lseek( fd, offset, 0 );
X }
X
X close( fd );
X}
X
X# endif /* NT */
END_OF_FILE
if test 6563 -ne `wc -c <'filent.c'`; then
echo shar: \"'filent.c'\" unpacked with wrong size!
fi
# end of 'filent.c'
fi
echo shar: End of archive 1 \(of 7\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 7 archives.
rm -f ark[1-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# Contents: jam.ps jamgram.y option.h regexp.c
# Wrapped by kent@ftp on Sat Mar 25 12:04:10 1995
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 3 (of 7)."'
if test -f 'jam.ps' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jam.ps'\"
else
echo shar: Extracting \"'jam.ps'\" \(42813 characters\)
sed "s/^X//" >'jam.ps' <<'END_OF_FILE'
X%!PS-Adobe-3.0
X%%Creator: groff version 1.08
X%%DocumentNeededResources: font Times-Roman
X%%+ font Times-Bold
X%%+ font Times-Italic
X%%DocumentSuppliedResources: procset grops 1.08 0
X%%Pages: 7
X%%IncludeResource: font Times-Roman
X%%IncludeResource: font Times-Bold
X%%IncludeResource: font Times-Italic
X/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE
X/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE
X%%EndProlog
X%%Page: 1 1
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF -.6(JA)72 48 S 403.38(M\(1\) J).6 F(AM\(1\))-.6 E/F1 9
X/Times-Bold@0 SF -.18(NA)72 84 S(ME).18 E/F2 10/Times-Bold@0 SF(jam)108 96 Q F0
X<ad>2.5 E F2(mak)2.5 E(e)-.1 E F0(\(1\) redux)A F1(SYNOPSIS)72 124.8 Q F2(jam)
X108 136.8 Q F0([)2.5 E F2(-a)2.5 E F0 2.5(][)2.5 G F2(-n)A F0 2.5(][)2.5 G F2
X(-v)A F0 2.5(][)2.5 G F2(-d)A/F3 10/Times-Italic@0 SF(deb)2.5 E(ug)-.2 E F0 2.5
X(][)2.5 G F2(-f)A F3 -.35(Ja)2.5 G(mbase).35 E F0(... ] [)2.5 E F2(-j)2.5 E F3
X(jobs)2.5 E F0 2.5(][)2.5 G F2(-t)A F3(tar)2.5 E -.1(ge)-.37 G(t).1 E F0
X(... ] [)2.5 E F3(tar)2.5 E -.1(ge)-.37 G(t).1 E F0(... ])2.5 E F1(DESCRIPTION)
X72 165.6 Q F2 -.15(Ja)108 177.6 S(m).15 E F0(recursi)3.449 E -.15(ve)-.25 G
X.949(ly b).15 F .949(uilds tar)-.2 F .949
X(get \214les from their source \214les, using tw)-.18 F 3.449<6f8c>-.1 G .948
X(les to de\214ne the dependenc)396.829 177.6 R 3.448(yg)-.15 G(raph)522.23
X177.6 Q .862(and the updating actions for all tar)108 189.6 R 3.362(gets. The)
X-.18 F(\214le)3.362 E F2 -.15(Ja)3.362 G(mbase).15 E F0 .862
X(\(usually located in /usr/local/lib\) de\214nes rules,)3.362 F .89
X(and the \214le)108 201.6 R F2 -.15(Ja)3.39 G(m\214le).15 E F0 .89
X(\(located in the current directory\) lists the tar)3.39 F .889
X(gets and sources in terms of those rules.)-.18 F F2 -.15(Ja)108 213.6 S(m).15
XE F0 1.238(does not need to rely on suf)3.738 F(\214x-dri)-.25 E -.15(ve)-.25 G
X3.738(ni).15 G 1.238(mplicit rules or directory contents.)293.194 213.6 R(A)
X6.238 E F2 -.15(Ja)3.738 G(mbase).15 E F0 1.239(is pro)3.739 F(vided)-.15 E
X(with)108 225.6 Q F2(jam)2.5 E F0 2.5(;t)C(he user supplies the)153 225.6 Q F2
X-.15(Ja)2.5 G(m\214le).15 E F0(.)A(See)108 242.4 Q F2 -.15(Ja)2.658 G(m\214le)
X.15 E F0 .158(\(5\) for information on writing Jam\214les.)B .158
X(This manual page describes the program that interprets)5.158 F F2 -.15(Ja)108
X254.4 S(mbase).15 E F0(and)2.5 E F2 -.15(Ja)2.5 G(m\214le).15 E F0(.)A F1
X(OPTIONS)72 283.2 Q F0(If)108 295.2 Q F3(tar)3.789 E -.1(ge)-.37 G(t).1 E F0
X1.289(is pro)3.789 F 1.289(vided on the command line,)-.15 F F2(jam)3.789 E F0
X1.289(attempts to b)3.789 F 1.29(uild that tar)-.2 F 1.29(get; otherwise)-.18 F
XF2(jam)3.79 E F0 1.29(attempts to)3.79 F -.2(bu)108 307.2 S(ild the tar).2 E
X(get)-.18 E F3(all)2.5 E F0(.)A F2 -.15(Ja)108 324 S(m).15 E F0
X(supports the follo)2.5 E(wing options:)-.25 E 25.73(-a Build)108 340.8 R
X(all tar)2.5 E(gets, e)-.18 E -.15(ve)-.25 G 2.5(ni).15 G 2.5(ft)236.47 340.8 S
X(he)245.08 340.8 Q 2.5(ya)-.15 G(re up-to-date.)266.31 340.8 Q(-d)108 357.6 Q
XF3(<n>)A F0(Set the deb)9.17 E(ug le)-.2 E -.15(ve)-.25 G 2.5(lt).15 G(o)225.06
X357.6 Q F3(<n>)2.5 E F0 5(.I)C(nteresting v)261.89 357.6 Q(alues are:)-.25 E
X2.5(0E)144 374.4 S(mit only errors)157.61 374.4 Q 2.5(1E)144 386.4 S
X(mit update action tracing \(def)157.61 386.4 Q(ault\))-.1 E 2.5(2E)144 398.4 S
X(mit update commands)157.61 398.4 Q 2.5(3P)144 410.4 S(roduce dependenc)157.06
X410.4 Q 2.5(yi)-.15 G(nformation)239.66 410.4 Q 2.5(4S)144 422.4 S(ho)157.06
X422.4 Q 2.5(wm)-.25 G(odi\214cation times of bound \214les)184.31 422.4 Q 2.5
X(5S)144 434.4 S(ho)157.06 434.4 Q 2.5(wr)-.25 G(ule in)179.86 434.4 Q -.2(vo)
X-.4 G(cation).2 E(6-9 deb)144 446.4 Q(ugging)-.2 E(-f)108 463.2 Q F3(<\214le>)A
XF0(Read)144 475.2 Q F3(<\214le>)2.5 E F0(instead of)2.5 E F2 -.15(Ja)2.5 G
X(mbase).15 E F0(.)A(-j)108 492 Q F3(<jobs>)A F0(Run up to)144 504 Q F3(<jobs>)
X2.5 E F0(shell commands concurrently \(UNIX only\).)2.5 E(The def)5 E
X(ault is 1.)-.1 E 25.17(-n Don')108 520.8 R 2.5(ta)-.18 G(ctually e)174.09
X520.8 Q -.15(xe)-.15 G(cute the updating actions, b).15 E(ut do e)-.2 E -.15
X(ve)-.25 G(rything else.).15 E(This implies)5 E F2(-d)2.5 E F3(2)A F0(.)A(-t)
X108 537.6 Q F3(<tar)A -.1(ge)-.37 G(t>).1 E F0(Reb)144 549.6 Q(uild)-.2 E F3
X(<tar)2.5 E -.1(ge)-.37 G(t>).1 E F0 2.5(,e)C -.15(ve)224.08 549.6 S 2.5(ni).15
XG 2.5(fi)243.65 549.6 S 2.5(ti)252.26 549.6 S 2.5(su)260.32 549.6 S(p-to-date.)
X271.71 549.6 Q 25.17(-v Print)108 566.4 R(the v)2.5 E(ersion of)-.15 E F2(jam)
X2.5 E F0(and e)2.5 E(xit.)-.15 E F1(THE J)72 595.2 Q(AM LANGU)-.27 E -.495(AG)
X-.54 G(E).495 E F0(The)108 607.2 Q F2(jam)3.061 E F0 .561
X(language supports de\214ning rules, in)3.061 F -.2(vo)-.4 G .561
X(king rules, and setting v).2 F 3.06(ariables. It)-.25 F .56(also has a fe)3.06
XF 3.06<778d>-.25 G -.25(ow)513.04 607.2 S(-of-).25 E(control statements.)108
X619.2 Q F2 -.15(Ja)5 G(mbase).15 E F0(and)2.5 E F2 -.15(Ja)2.5 G(m\214le).15 E
XF0(share this language.)2.5 E F2(Lexical F)87 636 Q(eatur)-.25 E(es)-.18 E -.15
X(Ja)108 648 S(m).15 E F0 2.292
X(treats its input \214les as whitespace-separated tok)4.792 F 2.292
X(ens, with tw)-.1 F 4.792(oe)-.1 G 2.292(xceptions: double quotes \("\) can)
X401.77 648 R .503(enclose whitespace to embed it into a tok)108 660 R .502
X(en, and e)-.1 F -.15(ve)-.25 G .502
X(rything between the matching curly braces \({}\) in the).15 F
X(de\214nition of a rule action is treated as a single string.)108 672 Q 2.5(Ab)
X5 G(ackslash \(\\\) can escape a double quote.)339.64 672 Q F2 -.15(Ja)108
X688.8 S(m).15 E F0 1.615(requires whitespace \(blanks, tabs, or ne)4.115 F
X1.615(wlines\) to surround all tok)-.25 F 1.616
X(ens, including the colon \(:\) and)-.1 F .377(semicolon \(;\) tok)108 700.8 R
X2.877(ens. This)-.1 F .377(is because)2.877 F F2(jam)2.877 E F0 .377
X(runs on man)2.877 F 2.877(yp)-.15 G .377(latforms and no characters, sa)345.38
X700.8 R .676 -.15(ve w)-.2 H .376(hitespace, are).15 F
X(uncommon in the \214le names on all of those platforms.)108 712.8 Q
X(10 March 1995)275.45 768 Q(1)535 768 Q EP
X%%Page: 2 2
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF -.6(JA)72 48 S 403.38(M\(1\) J).6 F(AM\(1\))-.6 E/F1 10
X/Times-Bold@0 SF -.92(Ta)87 84 S -.1(rg).92 G(ets).1 E F0 -.8(Ta)108 96 S -.18
X(rg).8 G .077(ets are \214les to be updated and sources are the \214les used i\
Xn updating those tar).18 F 2.577(gets. Collecti)-.18 F -.15(ve)-.25 G(ly).15 E
X2.577(,t)-.65 G(he)510.923 96 Q 2.577(ya)-.15 G(re)532.23 96 Q .054
X(just referred to as "tar)108 108 R 2.554(gets". A)-.18 F(tar)2.554 E .053
X(get is simply a \214le name, either rooted or relati)-.18 F .353 -.15(ve t)
X-.25 H 2.553(ot).15 G .053(he directory of)455.141 108 R F1(jam)2.553 E F0 -.55
X('s)C(in)108 120 Q -.2(vo)-.4 G 4.843(cation. The).2 F 2.344(special syntax,)
X4.843 F/F2 10/Times-Italic@0 SF(\214le\(member\))4.844 E F0 4.844(,r)C 2.344
X(efers to an)307.688 120 R F1(ar)4.844 E F0 2.344(\(1\) library member)B 7.344
X(.T)-.55 G 2.344(he special syntax,)464.492 120 R F2(<grist>\214le)108 132 Q F0
X4.037(,p)C 1.537(erturbs a \214le name to distinguish it from other \214les wi\
Xth the same name.)163.597 132 R(The)6.536 E F2(<grist>)4.036 E F0(is)4.036 E
X(stripped from the name during binding \(q.v)108 144 Q(., belo)-.65 E(w\).)-.25
XE F1(Rules)87 160.8 Q -.15(Ja)108 172.8 S(m).15 E F0 1.562 -.55('s b)D .462
X(asic entity is called a rule, which is used to relate tar).55 F .463
X(gets to their sources.)-.18 F 2.963(Ar)5.463 G .463(ule is de\214ned in tw)
X457.138 172.8 R(o)-.1 E .313(parts: the)108 184.8 R F1(jam)2.813 E F0 .313
X(statements to e)2.813 F -.15(xe)-.15 G .312(cute when the rule is in).15 F -.2
X(vo)-.4 G -.1(ke).2 G 2.812(d\().1 G .312
X(essentially a procedure call\), and the actions)361.228 184.8 R .285
X(\(shell commands\) to e)108 196.8 R -.15(xe)-.15 G .286
X(cute in order to update the tar).15 F .286(gets of the rule.)-.18 F 2.786(Ar)
X5.286 G .286(ule may ha)407.57 196.8 R .586 -.15(ve a p)-.2 H .286
X(rocedure de\214ni-).15 F(tion, actions, or both.)108 208.8 Q(The)108 225.6 Q
XF1(jam)3.339 E F0 .838(statements for de\214ning and in)3.339 F -.2(vo)-.4 G
X.838(king rules are as follo).2 F(ws.)-.25 E F2(<tar)5.838 E -.1(ge)-.37 G(ts>)
X.1 E F0(and)3.338 E F2(<sour)3.338 E(ces>)-.37 E F0 .838(are lists of)3.338 F
X(\214le names;)108 237.6 Q F2(<statements>)2.5 E F0(are)2.5 E F1(jam)2.5 E F0
X(statements; and)2.5 E F2(<string>)2.5 E F0(is a shell script:)2.5 E(rule)144
X254.4 Q F2(<rulename>)2.5 E F0({)2.5 E F2(<statements>)2.5 E F0(})2.5 E
X(actions [)144 271.2 Q F2(modi\214er)2.5 E(s)-.1 E F0(])2.5 E F2(<rulename>)2.5
XE F0({)2.5 E F2(<string>)2.5 E F0(})2.5 E F2(<rulename> <tar)144 288 Q -.1(ge)
X-.37 G(ts>).1 E F0 2.5([:)2.5 G F2(<sour)A(ces>)-.37 E F0 2.5(];)2.5 G .832
X(The \214rst form de\214nes a rule')108 304.8 R 3.332(sp)-.55 G .832
X(rocedure; the second de\214nes the rule')238.53 304.8 R 3.332(su)-.55 G .832
X(pdating actions; the third in)404.042 304.8 R -.2(vo)-.4 G -.1(ke).2 G(s).1 E
X(the rule.)108 316.8 Q(Rede\214ning a rule')5 E 2.5(sp)-.55 G
X(rocedure or actions replaces the pre)228.82 316.8 Q(vious de\214nition.)-.25 E
X(In)108 333.6 Q -.2(vo)-.4 G .118(king a rule e).2 F -.15(xe)-.15 G .117
X(cutes the procedure for the rule \(if an).15 F .117(y\) and associates an)-.15
XF 2.617(yu)-.15 G .117(pdate actions for the tar)426.682 333.6 R(gets.)-.18 E
X.179(More than one update action may be associated with a tar)108 345.6 R .18
X(get: the actions are e)-.18 F -.15(xe)-.15 G .18(cuted in the order in which)
X.15 F(the)108 357.6 Q 2.5(ya)-.15 G(re added.)132.01 357.6 Q .26
X(In both the rule')108 374.4 R 2.76(sp)-.55 G .26
X(rocedure de\214nition and the rule')184.59 374.4 R 2.759(sa)-.55 G .259
X(ctions, the special v)325.029 374.4 R .259
X(ariables $\(<\) and $\(>\) refer to the)-.25 F F2(<tar)108 386.4 Q -.1(ge)-.37
XG(ts>).1 E F0(and)2.517 E F2(<sour)2.517 E(ces>)-.37 E F0(gi)2.517 E -.15(ve)
X-.25 G 2.517(na).15 G 2.517(tr)243.258 386.4 S .017(ule in)251.885 386.4 R -.2
X(vo)-.4 G 2.518(cation. Ho).2 F(we)-.25 E -.15(ve)-.25 G .818 -.4(r, i).15 H
X2.518(nt).4 G .018(he rule')369.456 386.4 R 2.518(sa)-.55 G .018
X(ctions, $\(<\) and $\(>\) refer to the)410.592 386.4 R F2(<tar)108 398.4 Q -.1
X(ge)-.37 G(ts>).1 E F0(and)3.782 E F2(<sour)3.782 E(ces>)-.37 E F0 1.282
X(after the)3.782 F 3.782(yh)-.15 G -2.25 -.2(av e)266.23 398.4 T 1.282
X(been bound by the binding phase \(q.v)3.982 F 1.282(., belo)-.65 F(w\).)-.25 E
XF1 -.15(Ja)6.282 G(m).15 E F0 1.281(issues a)3.781 F -.1(wa)108 410.4 S
X(rning if $\(<\) or $\(>\) ha).1 E .3 -.15(ve e)-.2 H
X(lements not in the dependenc).15 E 2.5(yg)-.15 G(raph.)356.68 410.4 Q
X(The follo)108 427.2 Q(wing action)-.25 E F2(modi\214er)2.5 E(s)-.1 E F0
X(are understood:)2.5 E F1(actions existing)144 444 Q F0
X($\(>\) includes only tar)180 456 Q(gets currently e)-.18 E(xisting.)-.15 E F1
X(actions ignor)144 472.8 Q(e)-.18 E F0
X(The return status of the shell commands is ignored.)180 484.8 Q F1
X(actions piecemeal)144 501.6 Q F0 .284(The shell commands are repeatedly in)180
X513.6 R -.2(vo)-.4 G -.1(ke).2 G 2.784(dw).1 G .285
X(ith a subset of $\(>\) small enough to \214t in a)367.074 513.6 R(command b)
X180 525.6 Q(uf)-.2 E(fer)-.25 E(.)-.55 E F1(actions quietly)144 542.4 Q F0
X(The action is not echoed to the standard output.)180 554.4 Q F1
X(actions together)144 571.2 Q F0 1.559
X(The $\(>\) from multiple instances of the same action on the same tar)180
X583.2 R 1.558(get are glommed)-.18 F(together)180 595.2 Q(.)-.55 E F1
X(actions updated)144 612 Q F0($\(>\) includes only tar)180 624 Q(gets mark)-.18
XE(ed for updating.)-.1 E F1(Built-in Rules)87 640.8 Q -.15(Ja)108 652.8 S(m).15
XE F0(has ten b)2.5 E(uilt-in rules, none of which ha)-.2 E .3 -.15(ve u)-.2 H
X(pdating actions:).15 E(AL)144 674.4 Q -1.15 -1.2(WA Y)-.74 H(S)1.2 E F2(<tar)
X2.5 E -.1(ge)-.37 G(ts>).1 E F0(;)2.5 E(Reb)180 686.4 Q(uilds)-.2 E F2(<tar)2.5
XE -.1(ge)-.37 G(ts>).1 E F0 2.5(,e)C -.15(ve)267.86 686.4 S 2.5(ni).15 G 2.5
X(ft)287.43 686.4 S(he)296.04 686.4 Q 2.5(ya)-.15 G(re up-to-date.)317.27 686.4
XQ(DEPENDS)144 703.2 Q F2(<tar)2.5 E -.1(ge)-.37 G(ts>).1 E F0(:)2.5 E F2(<sour)
X2.5 E(ces>)-.37 E F0(;)2.5 E(Mak)180 715.2 Q(es)-.1 E F2(<sour)2.5 E(ces>)-.37
XE F0(dependencies of)2.5 E F2(<tar)2.5 E -.1(ge)-.37 G(ts>).1 E F0(.)A
X(10 March 1995)275.45 768 Q(2)535 768 Q EP
X%%Page: 3 3
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF -.6(JA)72 48 S 403.38(M\(1\) J).6 F(AM\(1\))-.6 E(ECHO)
X144 84 Q/F1 10/Times-Italic@0 SF(<ar)2.5 E(gs>)-.37 E F0(;)2.5 E
X(Blurts out the message)180 96 Q F1(<ar)2.5 E(gs>)-.37 E F0(to stdout.)2.5 E
X(EXIT)144 112.8 Q F1(<ar)2.5 E(gs>)-.37 E F0(;)2.5 E(Blurts out the message)180
X124.8 Q F1(<ar)2.5 E(gs>)-.37 E F0(to stdout and then e)2.5 E(xits with a f)
X-.15 E(ailure status.)-.1 E(INCLUDES)144 141.6 Q F1(<tar)2.5 E -.1(ge)-.37 G
X(ts>).1 E F0(:)2.5 E F1(<sour)2.5 E(ces>)-.37 E F0(;)2.5 E(Mak)180 153.6 Q(es)
X-.1 E F1(<sour)2.5 E(ces>)-.37 E F0(dependencies of an)2.5 E(ything of which)
X-.15 E F1(<tar)2.5 E -.1(ge)-.37 G(ts>).1 E F0(are dependencies.)2.5 E(LEA)144
X170.4 Q(VES)-1.35 E F1(<tar)2.5 E -.1(ge)-.37 G(ts>).1 E F0(;)2.5 E(Mak)180
X182.4 Q 1.135(es each of)-.1 F F1(<tar)3.635 E -.1(ge)-.37 G(ts>).1 E F0 1.135
X(depend only on its leaf sources, and not on an)3.635 F 3.635(yi)-.15 G
X(ntermediate)492.79 182.4 Q(tar)180 194.4 Q 2.5(gets. Its)-.18 F
X(leaf sources are those dependencies without an)2.5 E 2.5(yd)-.15 G
X(ependencies themselv)426 194.4 Q(es.)-.15 E(NOCARE)144 211.2 Q F1(<tar)2.5 E
X-.1(ge)-.37 G(ts>).1 E F0(;)2.5 E(Marks)180 223.2 Q F1(<tar)2.5 E -.1(ge)-.37 G
X(ts>).1 E F0(as possibly being bogus.)2.5 E(NO)144 240 Q(TFILE)-.4 E F1(<tar)
X2.5 E -.1(ge)-.37 G(ts>).1 E F0(;)2.5 E(Marks)180 252 Q F1(<tar)2.5 E -.1(ge)
X-.37 G(ts>).1 E F0(as not being \214les.)2.5 E(NOUPD)144 268.8 Q -1.11(AT)-.4 G
X(E)1.11 E F1(<tar)2.5 E -.1(ge)-.37 G(ts>).1 E F0(;)2.5 E .112
X(Causes the timestamps of)180 280.8 R F1(<tar)2.612 E -.1(ge)-.37 G(ts>).1 E F0
X.112(to be ignored: either the tar)2.612 F .112(get e)-.18 F .112
X(xists or it doesn')-.15 F 2.612(t. If)-.18 F(it e)180 292.8 Q
X(xists, it is considered eternally old.)-.15 E(TEMPORAR)144 309.6 Q(Y)-.65 E F1
X(<tar)2.5 E -.1(ge)-.37 G(ts>).1 E F0(;)2.5 E(Marks)180 321.6 Q F1(<tar)2.5 E
X-.1(ge)-.37 G(ts>).1 E F0(as temporary)2.5 E(.)-.65 E(The)108 338.4 Q F1(AL)
X4.539 E -1.85 -.6(WA Y)-.55 H(S).6 E F0(,)A F1(LEA)4.539 E(VES)-1.05 E F0(,)A
XF1(NOCARE)4.539 E F0(,)A F1(NO)4.539 E(TFILE)-.4 E F0(,)A F1(NOUPD)4.539 E -.37
X(AT)-.35 G(E).37 E F0 4.539(,a)C(nd)367.194 338.4 Q F1(TEMPORAR)4.539 E(Y)-.18
XE F0(af)4.539 E 2.039(fect only the binding)-.25 F(phase \(q.v)108 350.4 Q
X(.\).)-.65 E/F2 10/Times-Bold@0 SF(Flo)87 367.2 Q(w-of-Contr)-.1 E(ol)-.18 E
X-.15(Ja)108 379.2 S(m).15 E F0(has se)2.5 E -.15(ve)-.25 G(ral simple \215o).15
XE(w-of-control statements:)-.25 E(include)144 396 Q F1(<a>)2.5 E F0(;)2.5 E
X(for)144 412.8 Q F1(<a>)2.5 E F0(in)2.5 E F1(<ar)2.5 E(gs>)-.37 E F0({)2.5 E F1
X(<statements>)2.5 E F0(})2.5 E(switch)144 429.6 Q F1(<a>)2.5 E F0 2.5({c)2.5 G
X(ase)205.35 429.6 Q F1(<v1>)2.5 E F0(:)2.5 E F1(<statements>)2.5 E F0 2.5(;c)
X2.5 G(ase)319.28 429.6 Q F1(<v2>)2.5 E F0(:)2.5 E F1(<statements>)2.5 E F0 2.5
X(;.)2.5 G(.. })431.27 429.6 Q(if)144 446.4 Q F1(<cond>)2.5 E F0({)2.5 E F1
X(<statements>)2.5 E F0 2.5(}[e)2.5 G(lse {)271.14 446.4 Q F1(<statements>)2.5 E
XF0 2.5(}])2.5 G(The)108 463.2 Q F2(include)2.809 E F0 .308
X(statement includes the named \214le.)2.809 F .308(The \214le is bound lik)
X5.308 F 2.808(er)-.1 G -.15(eg)394.918 463.2 S .308(ular tar).15 F .308
X(gets \(see)-.18 F F2(Binding)2.808 E F0 2.808(,b)C(elo)514.98 463.2 Q(w\),)
X-.25 E -.2(bu)108 475.2 S 2.5(tu).2 G(nlik)128.08 475.2 Q 2.5(er)-.1 G -.15(eg)
X153.81 475.2 S(ular tar).15 E(gets the include \214le cannot be b)-.18 E(uilt.)
X-.2 E(The)108 492 Q F2 -.25(fo)2.5 G(r).25 E F0(loop e)2.5 E -.15(xe)-.15 G
X(cutes).15 E F1(<statements>)2.5 E F0(for each v)2.5 E(alue in)-.25 E F1(<ar)
X2.5 E(gs>)-.37 E F0 2.5(,s)C(etting the v)365.17 492 Q(ariable)-.25 E F1(<a>)
X2.5 E F0(to the v)2.5 E(alue.)-.25 E(The)108 508.8 Q F2(switch)3.134 E F0 .634
X(statement e)3.134 F -.15(xe)-.15 G .635(cutes zero or one of the enclosed).15
XF F1(<statements>)3.135 E F0 3.135(,d)C .635(epending on which v)416.45 508.8 R
X(alue)-.25 E F1(<a>)3.135 E F0 3.898(matches. The)108 520.8 R F1(<v>)3.898 E F0
X-.25(va)3.898 G 1.398(lues are not v).25 F(ariable-e)-.25 E 3.898(xpanded. The)
X-.15 F F1(<v>)3.898 E F0 -.25(va)3.898 G 1.398(lues may include the follo).25 F
X1.397(wing wild-)-.25 F(cards:)108 532.8 Q 67.56(?m)144 549.6 S(atch an)223.78
X549.6 Q 2.5(ys)-.15 G(ingle character)263.62 549.6 Q 67(*m)144 561.6 S
X(atch zero or more characters)223.78 561.6 Q([)144 573.6 Q F1(<c)A(har)-.15 E
X(s>)-.1 E F0 29.87(]m)C(atch an)223.78 573.6 Q 2.5(ys)-.15 G
X(ingle character in)263.62 573.6 Q F1(<c)2.5 E(har)-.15 E(s>)-.1 E F0(The)108
X590.4 Q F2(if)2.5 E F0(statement does the ob)2.5 E(vious; the)-.15 E F2(else)
X2.5 E F0(clause is optional.)2.5 E F1(<cond>)5 E F0(is b)2.5 E(uilt of:)-.2 E
XF1(<a>)144 607.2 Q F0(true if)216 607.2 Q F1(<a>)2.5 E F0
X(is a non-zero-length string)2.5 E F1(<a>)144 619.2 Q F0(=)2.5 E F1(<b>)2.5 E
XF0(strings equal)216 619.2 Q F1(<a>)144 631.2 Q F0(!=)2.5 E F1(<b>)2.5 E F0
X(strings not equal)216 631.2 Q F1(<a>)144 643.2 Q F0(<)2.5 E F1(<b>)2.5 E F0
X(string less than)216 643.2 Q F1(<a>)144 655.2 Q F0(<=)2.5 E F1(<b>)2.5 E F0
X(string less than or equal to)216 655.2 Q F1(<a>)144 667.2 Q F0(>)2.5 E F1(<b>)
X2.5 E F0(string greater than)216 667.2 Q F1(<a>)144 679.2 Q F0(>=)2.5 E F1(<b>)
X2.5 E F0(string greater than or equal to)216 679.2 Q(!)144 696 Q F1(<cond>)2.5
XE F0(condition not true)252 696 Q F1(<cond>)144 708 Q F0(&&)2.5 E F1(<cond>)2.5
XE F0(conjunction)252 708 Q F1(<cond>)144 720 Q F0(||)2.5 E F1(<cond>)2.5 E F0
X(disjunction)252 720 Q(10 March 1995)275.45 768 Q(3)535 768 Q EP
X%%Page: 4 4
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF -.6(JA)72 48 S 403.38(M\(1\) J).6 F(AM\(1\))-.6 E(\()
X144 84 Q/F1 10/Times-Italic@0 SF(<cond>)2.5 E F0 63.4(\)g)2.5 G(rouping)257 84
XQ .322(In comparisons, the ar)108 100.8 R .322(guments may \(through v)-.18 F
X.322(ariable e)-.25 F .323(xpansion\) be more than one tok)-.15 F .323(en, b)
X-.1 F .323(ut only the \214rst)-.2 F(tok)108 112.8 Q 1.035(en tak)-.1 F 1.035
X(es part in the comparison.)-.1 F 1.035(If, through v)6.035 F 1.035(ariable e)
X-.25 F 1.035(xpansion, the ar)-.15 F 1.035(gument is zero tok)-.18 F 1.035
X(ens, a single)-.1 F(tok)108 124.8 Q
X(en of a zero-length string is used instead.)-.1 E/F2 10/Times-Bold@0 SF -.92
X(Va)87 141.6 S(riables).92 E -.15(Ja)108 153.6 S(m).15 E F0 -.25(va)3.272 G
X.773(riables are lists of strings, with zero or more elements.).25 F .773
X(An unde\214ned v)5.773 F .773(ariable is indistinguishable)-.25 F .032
X(from a v)108 165.6 R .032(ariable whose v)-.25 F .031(alue is an empty list.)
X-.25 F -1.11(Va)5.031 G .031(riables are either global or tar)1.11 F 2.531
X(get-speci\214c. All)-.18 F -.25(va)2.531 G .031(riables are).25 F
X(referenced as $\(V)108 177.6 Q(ARIABLE\).)-1.35 E 2.5(Av)108 194.4 S
X(ariable is de\214ned with:)122.47 194.4 Q F1(<variable>)144 211.2 Q F0(=)2.5 E
XF1(<values>)2.5 E F0(;)2.5 E F1(<variable>)144 228 Q F0(+=)2.5 E F1(<values>)
X2.5 E F0(;)2.5 E F1(<variable>)144 244.8 Q F0(on)2.5 E F1(<tar)2.5 E -.1(ge)
X-.37 G(ts>).1 E F0(=)2.5 E F1(<values>)2.5 E F0(;)2.5 E F1(<variable>)144 261.6
XQ F0(on)2.5 E F1(<tar)2.5 E -.1(ge)-.37 G(ts>).1 E F0(+=)2.5 E F1(<values>)2.5
XE F0(;)2.5 E F1(<variable>)144 278.4 Q F0(def)2.5 E(ault =)-.1 E F1(<values>)
X2.5 E F0(;)2.5 E .314(The \214rst tw)108 295.2 R 2.814(of)-.1 G .314(orms set)
X165.782 295.2 R F1(<variable>)2.814 E F0(globally)2.814 E 5.314(.T)-.65 G .315
X(he third and forth forms set a tar)298.218 295.2 R .315(get-speci\214c v)-.18
XF .315(ariable, where)-.25 F F1(<variable>)108 307.2 Q F0(tak)2.834 E .333
X(es on a v)-.1 F .333(alue only during the binding and updating)-.25 F F1(<tar)
X2.833 E -.1(ge)-.37 G(ts>).1 E F0 5.333(.T)C(he)433.158 307.2 Q F2(=)2.833 E F0
X.333(operator replaces an)2.833 F(y)-.15 E(pre)108 319.2 Q .946(vious v)-.25 F
X.946(alue of)-.25 F F1(<variable>)3.446 E F0(with)3.446 E F1(<values>)3.446 E
XF0 3.446(;t)C(he)301.826 319.2 Q F2(+=)3.446 E F0 .947(operation appends)3.446
XF F1(<values>)3.447 E F0 .947(to an)3.447 F 3.447(yp)-.15 G(re)483.453 319.2 Q
X.947(vious v)-.25 F(alue.)-.25 E(The \214nal form sets)108 331.2 Q F1
X(<variable>)2.5 E F0(globally)2.5 E 2.5(,b)-.65 G(ut only if it w)277.03 331.2
XQ(as pre)-.1 E(viously unset.)-.25 E .364(On program start-up,)108 348 R F2
X(jam)2.863 E F0 .363(imports the en)2.863 F .363(vironment v)-.4 F .363
X(ariable settings into)-.25 F F2(jam)2.863 E F0 -.25(va)2.863 G 2.863
X(riables. En).25 F .363(vironment v)-.4 F(ari-)-.25 E .92
X(ables are split at blanks with each w)108 360 R .92
X(ord becomming an element in the v)-.1 F(ariable')-.25 E 3.42(sl)-.55 G .92
X(ist v)445.48 360 R 3.42(alue. En)-.25 F(vironment)-.4 E -.25(va)108 372 S .11
X(riables whose names end in).25 F F2 -.74(PA)2.61 G(TH)-.21 E F0 .11
X(are split at colons \(")2.61 F F2(:)A F0("\).)A F2 -.15(Ja)5.109 G(m).15 E F0
X-.25(va)2.609 G .109(riables are not re-e).25 F .109(xported to the shell)-.15
XF 1.827(that e)108 384 R -.15(xe)-.15 G 1.827(cutes the updating actions, b).15
XF 1.827(ut the updating actions can reference)-.2 F F2(jam)4.327 E F0 -.25(va)
X4.327 G 1.828(riables with $\(V).25 F(ARI-)-1.35 E(ABLE\).)108 396 Q F2 -.92
X(Va)87 412.8 S(riable Expansion).92 E F0 .322(Before e)108 424.8 R -.15(xe)-.15
XG .322(cuting a statement,).15 F F2(jam)2.822 E F0 .322(performs v)2.822 F .322
X(ariable e)-.25 F .322(xpansion on each tok)-.15 F .322(en that is not a k)-.1
XF -.15(ey)-.1 G -.1(wo).15 G .321(rd or rule).1 F .246(name. Such tok)108 436.8
XR .246(ens with embedded v)-.1 F .247
X(ariable references are replaced with zero or more tok)-.25 F 2.747(ens. V)-.1
XF .247(ariable ref-)-1.11 F(erences are of the form $\()108 448.8 Q F1(v)A F0
X2.5(\)o)C 2.5(r$)226.28 448.8 S(\()237.11 448.8 Q F1(vm)A F0(\), where)A F1(v)
X2.5 E F0(is the v)2.5 E(ariable name, and)-.25 E F1(m)2.5 E F0
X(are optional modi\214ers.)2.5 E -1.11(Va)108 465.6 S .676(riable e)1.11 F .676
X(xpansion in a rule')-.15 F 3.176(sa)-.55 G .676(ctions is similar to v)236.48
X465.6 R .676(ariable e)-.25 F .675(xpansion in statements, e)-.15 F .675
X(xcept that the action)-.15 F(string is tok)108 477.6 Q
X(enized at whitespace re)-.1 E -.05(ga)-.15 G(rdless of quoting.).05 E .967
X(The result of a tok)108 494.4 R .968(en after v)-.1 F .968(ariable e)-.25 F
X.968(xpansion is the product of the components of the tok)-.15 F .968
X(en, where each)-.1 F
X(component is a literal substring or a list substituting a v)108 506.4 Q
X(ariable reference.)-.25 E -.15(Fo)5 G 2.5(re).15 G(xample:)424.35 506.4 Q
X50.62($\(X\) ->)144 523.2 R 2.5(abc)2.5 G 47.84(t$\(X\) ->)144 535.2 R
X(ta tb tc)2.5 E 46.18($\(X\)z ->)144 547.2 R(az bz cz)2.5 E 28.41
X($\(X\)-$\(X\) ->)144 559.2 R(a-a a-b a-c b-a b-b b-c c-a c-b c-c)2.5 E .162
X(The v)108 576 R .162(ariable name and modi\214ers can themselv)-.25 F .162
X(es contain a v)-.15 F .162(ariable reference, and this partak)-.25 F .161
X(es of the prod-)-.1 F(uct as well:)108 588 Q 50.62($\(X\) ->)144 604.8 R 2.5
X(abc)2.5 G 50.62($\(Y\) ->)144 616.8 R 2.5(12)2.5 G 51.73($\(Z\) ->)144 628.8 R
X2.5(XY)2.5 G 40.07($\($\(Z\)\) ->)144 640.8 R 2.5(abc12)2.5 G .161
X(Because of this product e)108 657.6 R .161(xpansion, if an)-.15 F 2.661(yv)
X-.15 G .161(ariable reference in a tok)281.327 657.6 R .161
X(en is unde\214ned, the result of the e)-.1 F(xpan-)-.15 E
X(sion is an empty list.)108 669.6 Q(Modi\214ers to a v)108 686.4 Q
X(ariable are of tw)-.25 E 2.5(ov)-.1 G
X(arieties: sub-element selection and \214le name editing.)248.76 686.4 Q(The)5
XE 2.5(ya)-.15 G(re:)491.35 686.4 Q([)108 708 Q F1(<n>)A F0 10.84(]S)C .083
X(elect only element number)149.56 708 R F1(<n>)2.583 E F0 .083
X(\(starting at 1\).)2.583 F .083(If the v)5.083 F .082(ariable contains fe)-.25
XF .082(wer than)-.25 F F1(<n>)2.582 E F0(elements,)2.582 E
X(the result is a zero-element list.)144 720 Q(10 March 1995)275.45 768 Q(4)535
X768 Q EP
X%%Page: 5 5
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF -.6(JA)72 48 S 403.38(M\(1\) J).6 F(AM\(1\))-.6 E([)108
X84 Q/F1 10/Times-Italic@0 SF(<n>)A F0(-)A F1(<m>)A F0(])A
X(Select only elements number)144 96 Q F1(<n>)2.5 E F0(through)2.5 E F1(<m>)2.5
XE F0(.)A([)108 112.8 Q F1(<n>)A F0 5.01(-] Select)B(only elements number)2.5 E
XF1(<n>)2.5 E F0(through the last.)2.5 E(:G=)108 129.6 Q F1(<grist>)A F0
X(Replace the grist of the \214le name with)144 141.6 Q F1(<grist>)2.5 E F0(.)A
X(:D=)108 158.4 Q F1(<path>)A F0
X(Replace directory component of \214le name with)144 170.4 Q F1(<path>)2.5 E F0
X(.)A(:B=)108 187.2 Q F1(<base>)A F0(Replace the base part of \214le name with)
X144 199.2 Q F1(<base>)2.5 E F0(.)A(:S=)108 216 Q F1(<suf>)A F0(Replace the suf)
X144 228 Q(\214x of \214le name with)-.25 E F1(<suf>)2.5 E F0(.)A(:M=)108 244.8
XQ F1(<mem>)A F0(Replace the archi)144 256.8 Q .3 -.15(ve m)-.25 H
X(ember name with).15 E F1(<mem>)2.5 E F0(.)A(:R=)108 273.6 Q F1(<r)A(oot>)-.45
XE F0(Prepend)144 285.6 Q F1(<r)2.5 E(oot>)-.45 E F0
X(to the whole \214le name, if not already rooted.)2.5 E(:)108 302.4 Q F1
X(<components>)A F0(Remo)144 314.4 Q .3 -.15(ve c)-.15 H
X(omponents not listed; components is one or more of).15 E/F2 10/Times-Bold@0 SF
X(GDBSM)2.5 E F0(.)A/F3 9/Times-Bold@0 SF(OPERA)72 343.2 Q(TION)-.855 E F2 -.15
X(Ja)108 355.2 S(m).15 E F0
X(has three phases of operation: parsing, binding, and updating.)2.5 E F2 -.1
X(Pa)87 372 S(rsing).1 E -.15(Ja)108 384 S(m).15 E F0 .323(parses the)2.823 F F2
X-.15(Ja)2.823 G(mbase).15 E F0 .324(\214le, which includes)2.823 F F2 -.15(Ja)
X2.824 G(m\214le).15 E F0 5.324(.T)C .324
X(he results of parsing are: the dependenc)338.168 384 R 2.824(yg)-.15 G .324
X(raph of)511.076 384 R(tar)108 396 Q
X(gets; update actions associated with the tar)-.18 E(gets; and v)-.18 E
X(ariables set to speci\214c v)-.25 E(alues.)-.25 E F2(Binding)87 417.6 Q F0
X1.393(After parsing,)108 429.6 R F2(jam)3.893 E F0(recursi)3.893 E -.15(ve)-.25
XG 1.393(ly descends the dependenc).15 F 3.893(yg)-.15 G 1.393
X(raph, attempting to locate each tar)349.911 429.6 R 1.392(get \214le and)-.18
XF(determine if it is in need of updating.)108 441.6 Q(If)5 E F2(jam)2.5 E F0
X(detects a c)2.5 E(ycle in the graph, it issues a w)-.15 E(arning.)-.1 E .038
X(By def)108 458.4 R .038(ault, a tar)-.1 F .038
X(get is located at the actual path of the tar)-.18 F .039(get, relati)-.18 F
X.339 -.15(ve t)-.25 H 2.539(ot).15 G .039(he directory of)396.825 458.4 R F2
X(jam)2.539 E F0 1.139 -.55('s i)D -1.9 -.4(nv o).55 H 2.539(cation. If).4 F
X.378(the special v)108 470.4 R .377(ariable $\(LOCA)-.25 F .377
X(TE\) is set to a directory name,)-1.11 F F2(jam)2.877 E F0 .377
X(prepends that directory name to the tar)2.877 F(get;)-.18 E .093
X(else if the special v)108 482.4 R .093
X(ariable $\(SEARCH\) is set to a directory list,)-.25 F F2(jam)2.593 E F0 .093
X(searches along the directory list for the)2.593 F(tar)108 494.4 Q .284
X(get \214le, and if the \214le is found prepends the directory name to the tar)
X-.18 F 2.784(get. If)-.18 F .284(the tar)2.784 F .283(get name has a rooted)
X-.18 F .001(directory component then $\(SEARCH\) and $\(LOCA)108 506.4 R .001
X(TE\) do not apply: the tar)-1.11 F .002(get is located at the actual path)-.18
XF .028(of the tar)108 518.4 R 2.528(get. If)-.18 F 2.528(at)2.528 G(ar)182.66
X518.4 Q .028(get is mark)-.18 F .028(ed as not being a \214le \(using the b)-.1
XF .028(uilt-in rule NO)-.2 F .027(TFILE\), it is left unbound to)-.4 F 2.5
X<618c>108 530.4 S(le name.)120.5 530.4 Q .235(After binding each tar)108 547.2
XR(get,)-.18 E F2(jam)2.735 E F0 .235(determines whether the tar)2.735 F .235
X(get needs updating, and marks the tar)-.18 F .235(get if neces-)-.18 F
X(sary for the updating phase.)108 559.2 Q 2.5(At)5 G(ar)236.31 559.2 Q
X(get is mark)-.18 E(ed for updating for an)-.1 E 2.5(yo)-.15 G 2.5(ft)387.79
X559.2 S(hese three reasons:)396.4 559.2 Q(It is missing.)144 576 Q
X(Its \214lesystem modi\214cation time is older than an)144 592.8 Q 2.5(yo)-.15
XG 2.5(fi)346.63 592.8 S(ts sources.)355.24 592.8 Q(An)144 609.6 Q 2.5(yo)-.15 G
X2.5(fi)168.57 609.6 S(ts sources are mark)177.18 609.6 Q(ed for updating.)-.1 E
X(This basic beha)108 626.4 Q
X(vior can be modi\214ed applying \(usually one of\) the follo)-.2 E(wing six b)
X-.25 E(uilt-in rules to the tar)-.2 E(get:)-.18 E(AL)144 643.2 Q -1.15 -1.2
X(WA Y)-.74 H(S)1.2 E(The tar)180 655.2 Q(get is al)-.18 E -.1(wa)-.1 G
X(ys updated.).1 E(LEA)144 672 Q(VES)-1.35 E .059(The tar)180 684 R .059
X(get is only updated if it is missing or if its leaf sources are ne)-.18 F(wer)
X-.25 E 5.059(.L)-.55 G .058(eaf sources are)480.474 684 R
X(those dependencies of the tar)180 696 Q(get that ha)-.18 E .3 -.15(ve n)-.2 H
X2.5(od).15 G(ependencies themselv)366.65 696 Q(es.)-.15 E(10 March 1995)275.45
X768 Q(5)535 768 Q EP
X%%Page: 6 6
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF -.6(JA)72 48 S 403.38(M\(1\) J).6 F(AM\(1\))-.6 E
X(NOCARE)144 84 Q .244(The tar)180 96 R .244
X(get is ignored if it is missing and has no updating actions.)-.18 F(Normally)
X5.245 E(,)-.65 E/F1 10/Times-Bold@0 SF(jam)2.745 E F0 .245(issues a)2.745 F -.1
X(wa)180 108 S(rning and skips other tar).1 E(gets that depend on missing tar)
X-.18 E(gets without updating actions.)-.18 E(TEMPORAR)144 124.8 Q(Y)-.65 E 2.28
X(If the tar)180 136.8 R 2.28(get is missing, then its parent')-.18 F 4.78(sm)
X-.55 G 2.28(odi\214cation time is used when comparing)366.11 136.8 R(ag)180
X148.8 Q(ainst sources.)-.05 E(NO)144 165.6 Q(TFILE)-.4 E(The tar)180 177.6 Q
X(get is only updated if an)-.18 E 2.5(yo)-.15 G 2.5(fi)317.15 177.6 S
X(ts sources are mark)325.76 177.6 Q(ed for updating.)-.1 E(NOUPD)144 194.4 Q
X-1.11(AT)-.4 G(E)1.11 E .722(The tar)180 206.4 R .722
X(get is only updated if it is missing.)-.18 F .722(Also, if it e)5.722 F .723
X(xists, it will appear eternally old;)-.15 F(that is, older than an)180 218.4 Q
X(ything that depends on it.)-.15 E .373(If a tar)108 235.2 R .373
X(get is a source \214le that includes other \214les,)-.18 F F1(jam)2.872 E F0
X.372(scans the source \214le for header \214le include lines.)2.872 F(It)5.372
XE .707(scans the \214le by matching each line ag)108 247.2 R .707(ainst a)-.05
XF F1 -.18(re)3.207 G(gexp).18 E F0 .707(\(3\) pattern that has \(\)')B 3.207
X(ss)-.55 G .707(urrounding the included \214le)426.498 247.2 R 5.495(name. The)
X108 259.2 R 2.995(pattern is pro)5.495 F 2.994
X(vided by the user through the special v)-.15 F 2.994
X(ariable $\(HDRSCAN\) \(see)-.25 F F1(HDR-)5.494 E -.74(PA)108 271.2 S(TTERN)
X-.21 E F0(in)3.143 E F1 -.15(Ja)3.143 G(mbase).15 E F0 .644(for an e)3.144 F
X3.144(xample\). The)-.15 F .644(result of the scan is formed into a rule in)
X3.144 F -.2(vo)-.4 G .644(cation, with the).2 F .638(scanned \214le as the tar)
X108 283.2 R .638(get and the found included \214le names as the sources.)-.18 F
X.638(The rule in)5.638 F -.2(vo)-.4 G -.1(ke).2 G 3.138(di).1 G 3.137(sn)
X493.176 283.2 S .637(amed by)505.203 283.2 R .129(the special v)108 295.2 R
X.129(ariable $\(HDRR)-.25 F(ULE\).)-.4 E F1 -.15(Ja)5.129 G(m).15 E F0 .129
X(only scans \214les if $\(HDRSCAN\) is set, and $\(HDRSCAN\) is nor)2.629 F(-)
X-.2 E(mally set tar)108 307.2 Q(get-speci\214c.)-.18 E
X(Between binding and updating,)108 324 Q F1(jam)2.5 E F0
X(announces the number of tar)2.5 E(gets to be updated.)-.18 E F1(Updating)87
X340.8 Q F0 .095(After binding,)108 352.8 R F1(jam)2.595 E F0(ag)2.595 E .095
X(ain recursi)-.05 F -.15(ve)-.25 G .094(ly descends the dependenc).15 F 2.594
X(yg)-.15 G .094(raph, this time e)366.146 352.8 R -.15(xe)-.15 G .094
X(cuting the update actions).15 F .513(for each tar)108 364.8 R .513(get mark)
X-.18 F .513(ed for update during the binding phase.)-.1 F .513(If a tar)5.513 F
X(get')-.18 E 3.014(su)-.55 G .514(pdating actions f)409.97 364.8 R .514
X(ail, then all tar)-.1 F(-)-.2 E(gets which depend on it are skipped.)108 376.8
XQ .095(\(UNIX only\).)108 393.6 R(The)5.095 E F1(-j)2.595 E F0 .095
X(\215ag instructs)2.595 F F1(jam)2.595 E F0 .095(to b)2.595 F .095
X(uild more than one tar)-.2 F .095(get at a time.)-.18 F .095
X(If there are multiple actions)5.095 F(on a single tar)108 405.6 Q(get, the)
X-.18 E 2.5(ya)-.15 G(re run sequentially)205.43 405.6 Q(.)-.65 E .001
X(\(UNIX only\).)108 422.4 R .001(The special v)5.001 F .001(ariable $\(J)-.25 F
X.001(AMSHELL\) gi)-.6 F -.15(ve)-.25 G(s).15 E F1(jam)2.501 E F0 2.501(ac)2.501
XG .001(ommand e)368.639 422.4 R -.15(xe)-.15 G .002
X(cution shell to be used instead).15 F .371(of /bin/sh.)108 434.4 R .371
X(This v)5.371 F(ariable')-.25 E 2.871(sv)-.55 G .371
X(alue must be a multi-element list, corresponding to the ar)221.204 434.4 R .37
X(gument v)-.18 F .37(ector for the)-.15 F 1.8(command shell.)108 446.4 R 1.8
X(An element ")6.8 F F1(%)A F0 4.3("i)C 4.3(sr)257.65 446.4 S 1.801
X(eplaced with the command string to e)269.17 446.4 R -.15(xe)-.15 G 4.301
X(cute. An).15 F 1.801(element ")4.301 F F1(!)A F0 4.301("i)C(s)536.11 446.4 Q
X.45(replaced with the multiprocess slot number)108 458.4 R 2.949(,w)-.4 G .449
X(hich is \(inclusi)294.999 458.4 R -.15(ve)-.25 G .449
X(ly\) between 1 and the maximum number of).15 F .074
X(concurrent jobs speci\214ed with the)108 470.4 R F1(-j)2.574 E F0 .074
X(\215ag \(def)2.574 F .074(ault 1\).)-.1 F .075(If no element of the list is ")
X5.074 F F1(%)A F0 .075(", the command string is)B(tack)108 482.4 Q
X(ed on as the last ar)-.1 E 2.5(gument. The)-.18 F(def)2.5 E(ault v)-.1 E
X(alue is: "/bin/sh -c %".)-.25 E/F2 9/Times-Bold@0 SF(DIA)72 511.2 Q(GNOSTICS)
X-.495 E F0(In addition to generic error messages,)108 523.2 Q F1(jam)2.5 E F0
X(may emit one of the follo)2.5 E(wing:)-.25 E -.1(wa)108 540 S(rning: unkno).1
XE(wn rule X)-.25 E 2.5(Ar)144 556.8 S(ule w)157.05 556.8 Q(as in)-.1 E -.2(vo)
X-.4 G -.1(ke).2 G 2.5(dt).1 G
X(hat has not been de\214ned with an "actions" or "rule" statement.)226.52 556.8
XQ(using N temp tar)108 573.6 Q(get\(s\))-.18 E -.8(Ta)144 590.4 S -.18(rg).8 G
X(ets mark).18 E(ed as being temporary \(b)-.1 E(ut nonetheless present\) ha)-.2
XE .3 -.15(ve b)-.2 H(een found.).15 E(updating N tar)108 607.2 Q(get\(s\))-.18
XE -.8(Ta)144 624 S -.18(rg).8 G(ets are out-of-date and will be updated.).18 E
X(can')108 640.8 Q 2.5<748c>-.18 G(nd N tar)135.87 640.8 Q(get\(s\))-.18 E
X(Source \214les can')144 657.6 Q 2.5(tb)-.18 G 2.5(ef)220.75 657.6 S
X(ound and there are no actions to create them.)231.02 657.6 Q(can')108 674.4 Q
X2.5(tm)-.18 G(ak)138.09 674.4 Q 2.5(eNt)-.1 G(ar)166.87 674.4 Q(get\(s\))-.18 E
X(Due to sources not being found, other tar)144 691.2 Q(gets cannot be made.)
X-.18 E -.1(wa)108 708 S(rning: X depends on itself).1 E(10 March 1995)275.45
X768 Q(6)535 768 Q EP
X%%Page: 7 7
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF -.6(JA)72 48 S 403.38(M\(1\) J).6 F(AM\(1\))-.6 E 2.5
X(At)144 84 S(ar)156.5 84 Q
X(get depends on itself either directly or through its sources.)-.18 E(don')108
X100.8 Q 2.5(tk)-.18 G(no)136.43 100.8 Q 2.5(wh)-.25 G .5 -.25(ow t)160.9 100.8
XT 2.5(om).25 G(ak)193.43 100.8 Q 2.5(eX)-.1 G 2.5(At)144 117.6 S(ar)156.5 117.6
XQ(get is not present and no actions ha)-.18 E .3 -.15(ve b)-.2 H
X(een de\214ned to create it.).15 E 2.5(Xs)108 134.4 S(kipped for lack of Y)
X121.61 134.4 Q 2.5(As)144 151.2 S(ource f)157.61 151.2 Q(ailed to b)-.1 E
X(uild, and thus a tar)-.2 E(get cannot be b)-.18 E(uilt.)-.2 E -.1(wa)108 168 S
X(rning: using independent tar).1 E(get X)-.18 E 2.5(At)144 184.8 S(ar)156.5
X184.8 Q(get that does is not a dependenc)-.18 E 2.5(yo)-.15 G 2.5(fa)303.64
X184.8 S .3 -.15(ny o)313.91 184.8 T(ther tar).15 E
X(get is being referenced with $\(<\) or $\(>\).)-.18 E 2.5(Xr)108 201.6 S(emo)
X121.05 201.6 Q -.15(ve)-.15 G(d).15 E/F1 10/Times-Bold@0 SF -.15(Ja)144 218.4 S
X(m).15 E F0(remo)2.5 E -.15(ve)-.15 G 2.5(dap).15 G(artially b)213.81 218.4 Q
X(uilt tar)-.2 E(get after being interrupted.)-.18 E/F2 9/Times-Bold@0 SF(FILES)
X72 247.2 Q F0(/usr/local/lib/Jambase)108 259.2 Q(Jam\214le)108 271.2 Q F2 -.09
X(BU)72 300 S(GS, LIMIT).09 E -.855(AT)-.81 G(IONS).855 E F0 .752(Because the)
X108 312 R F1(include)3.252 E F0 .751(statement w)3.251 F .751
X(orks by pushing a ne)-.1 F 3.251<778c>-.25 G .751
X(le in the input stream of the scanner rather than)344.671 312 R(recursi)108
X324 Q -.15(ve)-.25 G .294(ly in).15 F -.2(vo)-.4 G .294
X(king the parser on the ne).2 F 2.794<778c>-.25 G .294
X(le, multiple include statements in a rule')287.388 324 R 2.795(sp)-.55 G .295
X(rocedure causes the)461.11 324 R(\214les to be included in re)108 336 Q -.15
X(ve)-.25 G(rse order).15 E(.)-.55 E .069(If the)108 352.8 R F1(include)2.569 E
XF0 .069(statement appears inside an)2.569 F F1(if)2.569 E F0 .069
X(block, the parser')2.569 F 2.568(sa)-.55 G .068(ttempt to \214nd the)367.048
X352.8 R F1(else)2.568 E F0 .068(will cause the te)2.568 F .068(xt of)-.15 F
X2.183(the included \214le to appear after the \214rst tok)108 364.8 R 2.184
X(en follo)-.1 F 2.184(wing the statement block.)-.25 F 2.184
X(This is rarely what is)7.184 F(intended.)108 376.8 Q .993(In a rule')108 393.6
XR 3.492(sa)-.55 G .992
X(ctions, only $\(<\) and $\(>\) refer to the bound \214le names: all other v)
X157.908 393.6 R .992(ariable references get the)-.25 F(unbound names.)108 405.6
XQ -.4(Wi)108 422.4 S .285(th the).4 F F1(-j)2.785 E F0 .285
X(\215ag, errors from f)2.785 F .285(ailed commands can get staggeringly mix)-.1
XF .285(ed up.)-.15 F .286(Also, because tar)5.286 F .286(gets tend to)-.18 F
X.226(get b)108 434.4 R .226(uilt in a quick)-.2 F .226
X(est-\214rst ordering, dependenc)-.1 F 2.726(yi)-.15 G .226
X(nformation must be quite e)308.552 434.4 R 2.726(xact. Finally)-.15 F 2.726
X(,b)-.65 G -2.1 -.25(ew a)479.378 434.4 T .226(re of paral-).25 F
X(lelizing commands that drop \214x)108 446.4 Q
X(ed-named \214les into the current directory)-.15 E 2.5(,l)-.65 G(ik)403 446.4
XQ(e)-.1 E F1(yacc)2.5 E F0(\(1\) does.)A 2.5(Ap)108 463.2 S(oorly set $\(J)
X122.72 463.2 Q(AMSHELL\) is lik)-.6 E(ely to result in silent f)-.1 E(ailure.)
X-.1 E F2(SEE ALSO)72 492 Q F1 -.15(Ja)108 504 S(mbase).15 E F0(\(5\),)A F1 -.15
X(Ja)2.5 G(m\214le).15 E F0(\(5\))A(10 March 1995)275.45 768 Q(7)535 768 Q EP
X%%Trailer
Xend
X%%EOF
END_OF_FILE
if test 42813 -ne `wc -c <'jam.ps'`; then
echo shar: \"'jam.ps'\" unpacked with wrong size!
fi
# end of 'jam.ps'
fi
if test -f 'jamgram.y' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jamgram.y'\"
else
echo shar: Extracting \"'jamgram.y'\" \(6303 characters\)
sed "s/^X//" >'jamgram.y' <<'END_OF_FILE'
X%token _BANG
X%token _BANG_EQUALS
X%token _AMPERAMPER
X%token _LPAREN
X%token _RPAREN
X%token _PLUS_EQUALS
X%token _COLON
X%token _SEMIC
X%token _LANGLE
X%token _LANGLE_EQUALS
X%token _EQUALS
X%token _RANGLE
X%token _RANGLE_EQUALS
X%token _QUESTION_EQUALS
X%token ACTIONS
X%token CASE
X%token DEFAULT
X%token ELSE
X%token EXISTING
X%token FOR
X%token IF
X%token IGNORE
X%token IN
X%token INCLUDE
X%token ON
X%token PIECEMEAL
X%token QUIETLY
X%token RULE
X%token SWITCH
X%token TOGETHER
X%token UPDATED
X%token _LBRACE
X%token _BARBAR
X%token _RBRACE
X/*
X * Copyright 1993, 1995 Christopher Seiwald.
X *
X * This file is part of Jam - see jam.c for Copyright information.
X */
X
X/*
X * jamgram.yy - jam grammar
X *
X * 04/13/94 (seiwald) - added shorthand L0 for null list pointer
X * 06/01/94 (seiwald) - new 'actions existing' does existing sources
X * 08/23/94 (seiwald) - Support for '+=' (append to variable)
X * 08/31/94 (seiwald) - Allow ?= as alias for "default =".
X * 09/15/94 (seiwald) - if conditionals take only single arguments, so
X * that 'if foo == bar' gives syntax error (use =).
X * 02/11/95 (seiwald) - when scanning arguments to rules, only treat
X * punctuation keywords as keywords. All arg lists
X * are terminated with punctuation keywords.
X */
X
X%token ARG STRING
X
X%left _BARBAR
X%left _AMPERAMPER
X%left _BANG
X
X%{
X#include "lists.h"
X#include "parse.h"
X#include "scan.h"
X#include "compile.h"
X#include "newstr.h"
X
X# define F0 (void (*)())0
X# define P0 (PARSE *)0
X# define S0 (char *)0
X
X# define pset( l,r,a ) parse_make( compile_set,P0,P0,S0,S0,l,r,a )
X# define pset1( l,p,a ) parse_make( compile_settings,p,P0,S0,S0,l,L0,a )
X# define pstng( p,l,r,a ) pset1( p, parse_make( F0,P0,P0,S0,S0,l,r,0 ), a )
X# define prule( s,l,r ) parse_make( compile_rule,P0,P0,s,S0,l,r,0 )
X# define prules( l,r ) parse_make( compile_rules,l,r,S0,S0,L0,L0,0 )
X# define pfor( s,p,l ) parse_make( compile_foreach,p,P0,s,S0,l,L0,0 )
X# define psetc( s,p ) parse_make( compile_setcomp,p,P0,s,S0,L0,L0,0 )
X# define psete( s,s1,f ) parse_make( compile_setexec,P0,P0,s,s1,L0,L0,f )
X# define pincl( l ) parse_make( compile_include,P0,P0,S0,S0,l,L0,0 )
X# define pswitch( l,p ) parse_make( compile_switch,p,P0,S0,S0,l,L0,0 )
X# define pcases( l,r ) parse_make( F0,l,r,S0,S0,L0,L0,0 )
X# define pcase( s,p ) parse_make( F0,p,P0,s,S0,L0,L0,0 )
X# define pif( l,r ) parse_make( compile_if,l,r,S0,S0,L0,L0,0 )
X# define pthen( l,r ) parse_make( F0,l,r,S0,S0,L0,L0,0 )
X# define pcond( c,l,r ) parse_make( F0,l,r,S0,S0,L0,L0,c )
X# define pcomp( c,l,r ) parse_make( F0,P0,P0,S0,S0,l,r,c )
X
X%}
X
X%%
X
X/*
X * stmts - the contents of a JAMFILE
X */
X
Xstmts :
X {
X compile_builtins();
X }
X | stmts rule
X {
X (*($2.parse->func))( $2.parse, L0, L0 );
X parse_free( $2.parse );
X }
X ;
X
X/*
X * rules - a strings of rule's together
X * rule - any one of jam's rules
X */
X
Xrules : /* empty */
X { $$.parse = prules( P0, P0 ); }
X | rules rule
X { $$.parse = prules( $1.parse, $2.parse ); }
X ;
X
Xrule : INCLUDE args _SEMIC
X { $$.parse = pincl( $2.list ); }
X | ARG args _SEMIC
X { $$.parse = prule( $1.string, $2.list, L0 ); }
X | ARG args _COLON args _SEMIC
X { $$.parse = prule( $1.string, $2.list, $4.list ); }
X | arg1 assign args _SEMIC
X { $$.parse = pset( $1.list, $3.list, $2.number ); }
X | arg1 ON args assign args _SEMIC
X { $$.parse = pstng( $3.list, $1.list, $5.list, $4.number ); }
X | arg1 DEFAULT _EQUALS args _SEMIC
X { $$.parse = pset( $1.list, $4.list, ASSIGN_DEFAULT ); }
X | FOR ARG IN args _LBRACE rules _RBRACE
X { $$.parse = pfor( $2.string, $6.parse, $4.list ); }
X | SWITCH args _LBRACE cases _RBRACE
X { $$.parse = pswitch( $2.list, $4.parse ); }
X | IF cond _LBRACE rules _RBRACE
X { $$.parse = pif( $2.parse, pthen( $4.parse, P0 ) ); }
X | IF cond _LBRACE rules _RBRACE ELSE rule
X { $$.parse = pif( $2.parse, pthen( $4.parse, $7.parse ) ); }
X | RULE ARG rule
X { $$.parse = psetc( $2.string, $3.parse ); }
X | ACTIONS eflags ARG
X { yymode( SCAN_STRING ); }
X STRING
X { $$.parse = psete( $3.string, $5.string, $2.number );
X yymode( SCAN_NORMAL ); }
X | _LBRACE rules _RBRACE
X { $$.parse = $2.parse; }
X ;
X
X/*
X * assign - = or +=
X */
X
Xassign : _EQUALS
X { $$.number = ASSIGN_SET; }
X | _PLUS_EQUALS
X { $$.number = ASSIGN_APPEND; }
X | _QUESTION_EQUALS
X { $$.number = ASSIGN_DEFAULT; }
X ;
X
X/*
X * cond - a conditional for 'if'
X */
X
Xcond : arg1
X { $$.parse = pcomp( COND_EXISTS, $1.list, L0 ); }
X | arg1 _EQUALS arg1
X { $$.parse = pcomp( COND_EQUALS, $1.list, $3.list ); }
X | arg1 _BANG_EQUALS arg1
X { $$.parse = pcomp( COND_NOTEQ, $1.list, $3.list ); }
X | arg1 _LANGLE arg1
X { $$.parse = pcomp( COND_LESS, $1.list, $3.list ); }
X | arg1 _LANGLE_EQUALS arg1
X { $$.parse = pcomp( COND_LESSEQ, $1.list, $3.list ); }
X | arg1 _RANGLE arg1
X { $$.parse = pcomp( COND_MORE, $1.list, $3.list ); }
X | arg1 _RANGLE_EQUALS arg1
X { $$.parse = pcomp( COND_MOREEQ, $1.list, $3.list ); }
X | _BANG cond
X { $$.parse = pcond( COND_NOT, $2.parse, P0 ); }
X | cond _AMPERAMPER cond
X { $$.parse = pcond( COND_AND, $1.parse, $3.parse ); }
X | cond _BARBAR cond
X { $$.parse = pcond( COND_OR, $1.parse, $3.parse ); }
X | _LPAREN cond _RPAREN
X { $$.parse = $2.parse; }
X ;
X
X/*
X * cases - action elements inside a 'switch'
X * case - a single action element inside a 'switch'
X *
X * Unfortunately, a right-recursive rule.
X */
X
Xcases : /* empty */
X { $$.parse = P0; }
X | case cases
X { $$.parse = pcases( $1.parse, $2.parse ); }
X ;
X
Xcase : CASE ARG _COLON rules
X { $$.parse = pcase( $2.string, $4.parse ); }
X ;
X
X/*
X * args - zero or more ARGs in a LIST
X * arg1 - exactly one ARG in a LIST
X */
X
Xargs : argsany
X { yymode( SCAN_NORMAL ); }
X ;
X
Xargsany : /* empty */
X { $$.list = L0; yymode( SCAN_PUNCT ); }
X | argsany ARG
X { $$.list = list_new( $1.list, copystr( $2.string ) ); }
X ;
X
Xarg1 : ARG
X { $$.list = list_new( L0, copystr( $1.string ) ); }
X ;
X
X/*
X * eflags - zero or more modifiers to 'executes'
X * eflag - a single modifier to 'executes'
X */
X
Xeflags : /* empty */
X { $$.number = 0; }
X | eflags eflag
X { $$.number = $1.number | $2.number; }
X ;
X
Xeflag : UPDATED
X { $$.number = EXEC_UPDATED; }
X | TOGETHER
X { $$.number = EXEC_TOGETHER; }
X | IGNORE
X { $$.number = EXEC_IGNORE; }
X | QUIETLY
X { $$.number = EXEC_QUIETLY; }
X | PIECEMEAL
X { $$.number = EXEC_PIECEMEAL; }
X | EXISTING
X { $$.number = EXEC_EXISTING; }
X ;
X
END_OF_FILE
if test 6303 -ne `wc -c <'jamgram.y'`; then
echo shar: \"'jamgram.y'\" unpacked with wrong size!
fi
# end of 'jamgram.y'
fi
if test -f 'option.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'option.h'\"
else
echo shar: Extracting \"'option.h'\" \(504 characters\)
sed "s/^X//" >'option.h' <<'END_OF_FILE'
X/*
X * Copyright 1993, 1995 Christopher Seiwald.
X *
X * This file is part of Jam - see jam.c for Copyright information.
X */
X
X/*
X * option.h - command line option processing
X *
X * {o >o
X * \ -) "Command line option."
X */
X
Xtypedef struct option
X{
X char flag; /* filled in by getoption() */
X char *val; /* set to random address if true */
X} option;
X
X# define N_OPTS 10
X
Xint getoptions( /* int argc, char **argv, char *opts, option *optv */ );
Xchar *getoptval( /* option *optv, char opt, int subopt */ );
END_OF_FILE
if test 504 -ne `wc -c <'option.h'`; then
echo shar: \"'option.h'\" unpacked with wrong size!
fi
# end of 'option.h'
fi
if test -f 'regexp.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'regexp.c'\"
else
echo shar: Extracting \"'regexp.c'\" \(31610 characters\)
sed "s/^X//" >'regexp.c' <<'END_OF_FILE'
X/*
X * regcomp and regexec -- regsub and regerror are elsewhere
X *
X * Copyright (c) 1986 by University of Toronto.
X * Written by Henry Spencer. Not derived from licensed software.
X *
X * Permission is granted to anyone to use this software for any
X * purpose on any computer system, and to redistribute it freely,
X * subject to the following restrictions:
X *
X * 1. The author is not responsible for the consequences of use of
X * this software, no matter how awful, even if they arise
X * from defects in it.
X *
X * 2. The origin of this software must not be misrepresented, either
X * by explicit claim or by omission.
X *
X * 3. Altered versions must be plainly marked as such, and must not
X * be misrepresented as being the original software.
X *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
X *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to |
X *** to assist in implementing egrep.
X *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
X *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching
X *** as in BSD grep and ex.
X *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
X *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \.
X *** THIS IS AN ALTERED VERSION. It was altered by James A. Woods,
X *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy.
X *** THIS IS AN ALTERED VERSION. It was altered by Christopher Seiwald
X *** sei...@vix.com, on 28 August 1993, for use in jam. Regmagic.h
X *** was moved into regexp.h, and the include of regexp.h now uses "'s
X *** to avoid conflicting with the system regexp.h. Const, bless its
X *** soul, was removed so it can compile everywhere. The declaration
X *** of strchr() was in conflict on AIX, so it was removed (as it is
X *** happily defined in string.h).
X *
X * Beware that some of this code is subtly aware of the way operator
X * precedence is structured in regular expressions. Serious changes in
X * regular-expression syntax might require a total rethink.
X */
X#include "regexp.h"
X#include <stdio.h>
X#include <ctype.h>
X#ifndef ultrix
X#include <stdlib.h>
X#endif
X#include <string.h>
X
X/*
X * The "internal use only" fields in regexp.h are present to pass info from
X * compile to execute that permits the execute phase to run lots faster on
X * simple cases. They are:
X *
X * regstart char that must begin a match; '\0' if none obvious
X * reganch is the match anchored (at beginning-of-line only)?
X * regmust string (pointer into program) that match must include, or NULL
X * regmlen length of regmust string
X *
X * Regstart and reganch permit very fast decisions on suitable starting points
X * for a match, cutting down the work a lot. Regmust permits fast rejection
X * of lines that cannot possibly match. The regmust tests are costly enough
X * that regcomp() supplies a regmust only if the r.e. contains something
X * potentially expensive (at present, the only such thing detected is * or +
X * at the start of the r.e., which can involve a lot of backup). Regmlen is
X * supplied because the test in regexec() needs it and regcomp() is computing
X * it anyway.
X */
X
X/*
X * Structure for regexp "program". This is essentially a linear encoding
X * of a nondeterministic finite-state machine (aka syntax charts or
X * "railroad normal form" in parsing technology). Each node is an opcode
X * plus a "next" pointer, possibly plus an operand. "Next" pointers of
X * all nodes except BRANCH implement concatenation; a "next" pointer with
X * a BRANCH on both ends of it is connecting two alternatives. (Here we
X * have one of the subtle syntax dependencies: an individual BRANCH (as
X * opposed to a collection of them) is never concatenated with anything
X * because of operator precedence.) The operand of some types of node is
X * a literal string; for others, it is a node leading into a sub-FSM. In
X * particular, the operand of a BRANCH node is the first node of the branch.
X * (NB this is *not* a tree structure: the tail of the branch connects
X * to the thing following the set of BRANCHes.) The opcodes are:
X */
X
X/* definition number opnd? meaning */
X#define END 0 /* no End of program. */
X#define BOL 1 /* no Match "" at beginning of line. */
X#define EOL 2 /* no Match "" at end of line. */
X#define ANY 3 /* no Match any one character. */
X#define ANYOF 4 /* str Match any character in this string. */
X#define ANYBUT 5 /* str Match any character not in this string. */
X#define BRANCH 6 /* node Match this alternative, or the next... */
X#define BACK 7 /* no Match "", "next" ptr points backward. */
X#define EXACTLY 8 /* str Match this string. */
X#define NOTHING 9 /* no Match empty string. */
X#define STAR 10 /* node Match this (simple) thing 0 or more times. */
X#define PLUS 11 /* node Match this (simple) thing 1 or more times. */
X#define WORDA 12 /* no Match "" at wordchar, where prev is nonword */
X#define WORDZ 13 /* no Match "" at nonwordchar, where prev is word */
X#define OPEN 20 /* no Mark this point in input as start of #n. */
X /* OPEN+1 is number 1, etc. */
X#define CLOSE 30 /* no Analogous to OPEN. */
X
X/*
X * Opcode notes:
X *
X * BRANCH The set of branches constituting a single choice are hooked
X * together with their "next" pointers, since precedence prevents
X * anything being concatenated to any individual branch. The
X * "next" pointer of the last BRANCH in a choice points to the
X * thing following the whole choice. This is also where the
X * final "next" pointer of each individual branch points; each
X * branch starts with the operand node of a BRANCH node.
X *
X * BACK Normal "next" pointers all implicitly point forward; BACK
X * exists to make loop structures possible.
X *
X * STAR,PLUS '?', and complex '*' and '+', are implemented as circular
X * BRANCH structures using BACK. Simple cases (one character
X * per match) are implemented with STAR and PLUS for speed
X * and to minimize recursive plunges.
X *
X * OPEN,CLOSE ...are numbered at compile time.
X */
X
X/*
X * A node is one char of opcode followed by two chars of "next" pointer.
X * "Next" pointers are stored as two 8-bit pieces, high order first. The
X * value is a positive offset from the opcode of the node containing it.
X * An operand, if any, simply follows the node. (Note that much of the
X * code generation knows about this implicit relationship.)
X *
X * Using two bytes for the "next" pointer is vast overkill for most things,
X * but allows patterns to get big without disasters.
X */
X#define OP(p) (*(p))
X#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
X#define OPERAND(p) ((p) + 3)
X
X/*
X * See regmagic.h for one further detail of program structure.
X */
X
X
X/*
X * Utility definitions.
X */
X#ifndef CHARBITS
X#define UCHARAT(p) ((int)*(unsigned char *)(p))
X#else
X#define UCHARAT(p) ((int)*(p)&CHARBITS)
X#endif
X
X#define FAIL(m) { regerror(m); return(NULL); }
X#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
X
X/*
X * Flags to be passed up and down.
X */
X#define HASWIDTH 01 /* Known never to match null string. */
X#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */
X#define SPSTART 04 /* Starts with * or +. */
X#define WORST 0 /* Worst case. */
X
X/*
X * Global work variables for regcomp().
X */
Xstatic char *regparse; /* Input-scan pointer. */
Xstatic int regnpar; /* () count. */
Xstatic char regdummy;
Xstatic char *regcode; /* Code-emit pointer; ®dummy = don't. */
Xstatic long regsize; /* Code size. */
X
X/*
X * Forward declarations for regcomp()'s friends.
X */
X#ifndef STATIC
X#define STATIC static
X#endif
XSTATIC char *reg();
XSTATIC char *regbranch();
XSTATIC char *regpiece();
XSTATIC char *regatom();
XSTATIC char *regnode();
XSTATIC char *regnext();
XSTATIC void regc();
XSTATIC void reginsert();
XSTATIC void regtail();
XSTATIC void regoptail();
X#ifdef STRCSPN
XSTATIC int strcspn();
X#endif
X
X/*
X - regcomp - compile a regular expression into internal code
X *
X * We can't allocate space until we know how big the compiled form will be,
X * but we can't compile it (and thus know how big it is) until we've got a
X * place to put the code. So we cheat: we compile it twice, once with code
X * generation turned off and size counting turned on, and once "for real".
X * This also means that we don't allocate space until we are sure that the
X * thing really will compile successfully, and we never have to move the
X * code and thus invalidate pointers into it. (Note that it has to be in
X * one piece because free() must be able to free it all.)
X *
X * Beware that the optimization-preparation code in here knows about some
X * of the structure of the compiled regexp.
X */
Xregexp *
Xregcomp(exp)
Xchar *exp;
X{
X register regexp *r;
X register char *scan;
X register char *longest;
X register int len;
X int flags;
X
X if (exp == NULL)
X FAIL("NULL argument");
X
X /* First pass: determine size, legality. */
X#ifdef notdef
X if (exp[0] == '.' && exp[1] == '*') exp += 2; /* aid grep */
X#endif
X regparse = (char *)exp;
X regnpar = 1;
X regsize = 0L;
X regcode = ®dummy;
X regc(MAGIC);
X if (reg(0, &flags) == NULL)
X return(NULL);
X
X /* Small enough for pointer-storage convention? */
X if (regsize >= 32767L) /* Probably could be 65535L. */
X FAIL("regexp too big");
X
X /* Allocate space. */
X r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize);
X if (r == NULL)
X FAIL("out of space");
X
X /* Second pass: emit code. */
X regparse = (char *)exp;
X regnpar = 1;
X regcode = r->program;
X regc(MAGIC);
X if (reg(0, &flags) == NULL)
X return(NULL);
X
X /* Dig out information for optimizations. */
X r->regstart = '\0'; /* Worst-case defaults. */
X r->reganch = 0;
X r->regmust = NULL;
X r->regmlen = 0;
X scan = r->program+1; /* First BRANCH. */
X if (OP(regnext(scan)) == END) { /* Only one top-level choice. */
X scan = OPERAND(scan);
X
X /* Starting-point info. */
X if (OP(scan) == EXACTLY)
X r->regstart = *OPERAND(scan);
X else if (OP(scan) == BOL)
X r->reganch++;
X
X /*
X * If there's something expensive in the r.e., find the
X * longest literal string that must appear and make it the
X * regmust. Resolve ties in favor of later strings, since
X * the regstart check works with the beginning of the r.e.
X * and avoiding duplication strengthens checking. Not a
X * strong reason, but sufficient in the absence of others.
X */
X if (flags&SPSTART) {
X longest = NULL;
X len = 0;
X for (; scan != NULL; scan = regnext(scan))
X if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
X longest = OPERAND(scan);
X len = strlen(OPERAND(scan));
X }
X r->regmust = longest;
X r->regmlen = len;
X }
X }
X
X return(r);
X}
X
X/*
X - reg - regular expression, i.e. main body or parenthesized thing
X *
X * Caller must absorb opening parenthesis.
X *
X * Combining parenthesis handling with the base level of regular expression
X * is a trifle forced, but the need to tie the tails of the branches to what
X * follows makes it hard to avoid.
X */
Xstatic char *
Xreg(paren, flagp)
Xint paren; /* Parenthesized? */
Xint *flagp;
X{
X register char *ret;
X register char *br;
X register char *ender;
X register int parno;
X int flags;
X
X *flagp = HASWIDTH; /* Tentatively. */
X
X /* Make an OPEN node, if parenthesized. */
X if (paren) {
X if (regnpar >= NSUBEXP)
X FAIL("too many ()");
X parno = regnpar;
X regnpar++;
X ret = regnode(OPEN+parno);
X } else
X ret = NULL;
X
X /* Pick up the branches, linking them together. */
X br = regbranch(&flags);
X if (br == NULL)
X return(NULL);
X if (ret != NULL)
X regtail(ret, br); /* OPEN -> first. */
X else
X ret = br;
X if (!(flags&HASWIDTH))
X *flagp &= ~HASWIDTH;
X *flagp |= flags&SPSTART;
X while (*regparse == '|' || *regparse == '\n') {
X regparse++;
X br = regbranch(&flags);
X if (br == NULL)
X return(NULL);
X regtail(ret, br); /* BRANCH -> BRANCH. */
X if (!(flags&HASWIDTH))
X *flagp &= ~HASWIDTH;
X *flagp |= flags&SPSTART;
X }
X
X /* Make a closing node, and hook it on the end. */
X ender = regnode((paren) ? CLOSE+parno : END);
X regtail(ret, ender);
X
X /* Hook the tails of the branches to the closing node. */
X for (br = ret; br != NULL; br = regnext(br))
X regoptail(br, ender);
X
X /* Check for proper termination. */
X if (paren && *regparse++ != ')') {
X FAIL("unmatched ()");
X } else if (!paren && *regparse != '\0') {
X if (*regparse == ')') {
X FAIL("unmatched ()");
X } else
X FAIL("junk on end"); /* "Can't happen". */
X /* NOTREACHED */
X }
X
X return(ret);
X}
X
X/*
X - regbranch - one alternative of an | operator
X *
X * Implements the concatenation operator.
X */
Xstatic char *
Xregbranch(flagp)
Xint *flagp;
X{
X register char *ret;
X register char *chain;
X register char *latest;
X int flags;
X
X *flagp = WORST; /* Tentatively. */
X
X ret = regnode(BRANCH);
X chain = NULL;
X while (*regparse != '\0' && *regparse != ')' &&
X *regparse != '\n' && *regparse != '|') {
X latest = regpiece(&flags);
X if (latest == NULL)
X return(NULL);
X *flagp |= flags&HASWIDTH;
X if (chain == NULL) /* First piece. */
X *flagp |= flags&SPSTART;
X else
X regtail(chain, latest);
X chain = latest;
X }
X if (chain == NULL) /* Loop ran zero times. */
X (void) regnode(NOTHING);
X
X return(ret);
X}
X
X/*
X - regpiece - something followed by possible [*+?]
X *
X * Note that the branching code sequences used for ? and the general cases
X * of * and + are somewhat optimized: they use the same NOTHING node as
X * both the endmarker for their branch list and the body of the last branch.
X * It might seem that this node could be dispensed with entirely, but the
X * endmarker role is not redundant.
X */
Xstatic char *
Xregpiece(flagp)
Xint *flagp;
X{
X register char *ret;
X register char op;
X register char *next;
X int flags;
X
X ret = regatom(&flags);
X if (ret == NULL)
X return(NULL);
X
X op = *regparse;
X if (!ISMULT(op)) {
X *flagp = flags;
X return(ret);
X }
X
X if (!(flags&HASWIDTH) && op != '?')
X FAIL("*+ operand could be empty");
X *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
X
X if (op == '*' && (flags&SIMPLE))
X reginsert(STAR, ret);
X else if (op == '*') {
X /* Emit x* as (x&|), where & means "self". */
X reginsert(BRANCH, ret); /* Either x */
X regoptail(ret, regnode(BACK)); /* and loop */
X regoptail(ret, ret); /* back */
X regtail(ret, regnode(BRANCH)); /* or */
X regtail(ret, regnode(NOTHING)); /* null. */
X } else if (op == '+' && (flags&SIMPLE))
X reginsert(PLUS, ret);
X else if (op == '+') {
X /* Emit x+ as x(&|), where & means "self". */
X next = regnode(BRANCH); /* Either */
X regtail(ret, next);
X regtail(regnode(BACK), ret); /* loop back */
X regtail(next, regnode(BRANCH)); /* or */
X regtail(ret, regnode(NOTHING)); /* null. */
X } else if (op == '?') {
X /* Emit x? as (x|) */
X reginsert(BRANCH, ret); /* Either x */
X regtail(ret, regnode(BRANCH)); /* or */
X next = regnode(NOTHING); /* null. */
X regtail(ret, next);
X regoptail(ret, next);
X }
X regparse++;
X if (ISMULT(*regparse))
X FAIL("nested *?+");
X
X return(ret);
X}
X
X/*
X - regatom - the lowest level
X *
X * Optimization: gobbles an entire sequence of ordinary characters so that
X * it can turn them into a single node, which is smaller to store and
X * faster to run. Backslashed characters are exceptions, each becoming a
X * separate node; the code is simpler that way and it's not worth fixing.
X */
Xstatic char *
Xregatom(flagp)
Xint *flagp;
X{
X register char *ret;
X int flags;
X
X *flagp = WORST; /* Tentatively. */
X
X switch (*regparse++) {
X /* FIXME: these chars only have meaning at beg/end of pat? */
X case '^':
X ret = regnode(BOL);
X break;
X case '$':
X ret = regnode(EOL);
X break;
X case '.':
X ret = regnode(ANY);
X *flagp |= HASWIDTH|SIMPLE;
X break;
X case '[': {
X register int class;
X register int classend;
X
X if (*regparse == '^') { /* Complement of range. */
X ret = regnode(ANYBUT);
X regparse++;
X } else
X ret = regnode(ANYOF);
X if (*regparse == ']' || *regparse == '-')
X regc(*regparse++);
X while (*regparse != '\0' && *regparse != ']') {
X if (*regparse == '-') {
X regparse++;
X if (*regparse == ']' || *regparse == '\0')
X regc('-');
X else {
X class = UCHARAT(regparse-2)+1;
X classend = UCHARAT(regparse);
X if (class > classend+1)
X FAIL("invalid [] range");
X for (; class <= classend; class++)
X regc(class);
X regparse++;
X }
X } else
X regc(*regparse++);
X }
X regc('\0');
X if (*regparse != ']')
X FAIL("unmatched []");
X regparse++;
X *flagp |= HASWIDTH|SIMPLE;
X }
X break;
X case '(':
X ret = reg(1, &flags);
X if (ret == NULL)
X return(NULL);
X *flagp |= flags&(HASWIDTH|SPSTART);
X break;
X case '\0':
X case '|':
X case '\n':
X case ')':
X FAIL("internal urp"); /* Supposed to be caught earlier. */
X break;
X case '?':
X case '+':
X case '*':
X FAIL("?+* follows nothing");
X break;
X case '\\':
X switch (*regparse++) {
X case '\0':
X FAIL("trailing \\");
X break;
X case '<':
X ret = regnode(WORDA);
X break;
X case '>':
X ret = regnode(WORDZ);
X break;
X /* FIXME: Someday handle \1, \2, ... */
X default:
X /* Handle general quoted chars in exact-match routine */
X goto de_fault;
X }
X break;
X de_fault:
X default:
X /*
X * Encode a string of characters to be matched exactly.
X *
X * This is a bit tricky due to quoted chars and due to
X * '*', '+', and '?' taking the SINGLE char previous
X * as their operand.
X *
X * On entry, the char at regparse[-1] is going to go
X * into the string, no matter what it is. (It could be
X * following a \ if we are entered from the '\' case.)
X *
X * Basic idea is to pick up a good char in ch and
X * examine the next char. If it's *+? then we twiddle.
X * If it's \ then we frozzle. If it's other magic char
X * we push ch and terminate the string. If none of the
X * above, we push ch on the string and go around again.
X *
X * regprev is used to remember where "the current char"
X * starts in the string, if due to a *+? we need to back
X * up and put the current char in a separate, 1-char, string.
X * When regprev is NULL, ch is the only char in the
X * string; this is used in *+? handling, and in setting
X * flags |= SIMPLE at the end.
X */
X {
X char *regprev;
X register char ch;
X
X regparse--; /* Look at cur char */
X ret = regnode(EXACTLY);
X for ( regprev = 0 ; ; ) {
X ch = *regparse++; /* Get current char */
X switch (*regparse) { /* look at next one */
X
X default:
X regc(ch); /* Add cur to string */
X break;
X
X case '.': case '[': case '(':
X case ')': case '|': case '\n':
X case '$': case '^':
X case '\0':
X /* FIXME, $ and ^ should not always be magic */
X magic:
X regc(ch); /* dump cur char */
X goto done; /* and we are done */
X
X case '?': case '+': case '*':
X if (!regprev) /* If just ch in str, */
X goto magic; /* use it */
X /* End mult-char string one early */
X regparse = regprev; /* Back up parse */
X goto done;
X
X case '\\':
X regc(ch); /* Cur char OK */
X switch (regparse[1]){ /* Look after \ */
X case '\0':
X case '<':
X case '>':
X /* FIXME: Someday handle \1, \2, ... */
X goto done; /* Not quoted */
X default:
X /* Backup point is \, scan * point is after it. */
X regprev = regparse;
X regparse++;
X continue; /* NOT break; */
X }
X }
X regprev = regparse; /* Set backup point */
X }
X done:
X regc('\0');
X *flagp |= HASWIDTH;
X if (!regprev) /* One char? */
X *flagp |= SIMPLE;
X }
X break;
X }
X
X return(ret);
X}
X
X/*
X - regnode - emit a node
X */
Xstatic char * /* Location. */
Xregnode(op)
Xchar op;
X{
X register char *ret;
X register char *ptr;
X
X ret = regcode;
X if (ret == ®dummy) {
X regsize += 3;
X return(ret);
X }
X
X ptr = ret;
X *ptr++ = op;
X *ptr++ = '\0'; /* Null "next" pointer. */
X *ptr++ = '\0';
X regcode = ptr;
X
X return(ret);
X}
X
X/*
X - regc - emit (if appropriate) a byte of code
X */
Xstatic void
Xregc(b)
Xchar b;
X{
X if (regcode != ®dummy)
X *regcode++ = b;
X else
X regsize++;
X}
X
X/*
X - reginsert - insert an operator in front of already-emitted operand
X *
X * Means relocating the operand.
X */
Xstatic void
Xreginsert(op, opnd)
Xchar op;
Xchar *opnd;
X{
X register char *src;
X register char *dst;
X register char *place;
X
X if (regcode == ®dummy) {
X regsize += 3;
X return;
X }
X
X src = regcode;
X regcode += 3;
X dst = regcode;
X while (src > opnd)
X *--dst = *--src;
X
X place = opnd; /* Op node, where operand used to be. */
X *place++ = op;
X *place++ = '\0';
X *place++ = '\0';
X}
X
X/*
X - regtail - set the next-pointer at the end of a node chain
X */
Xstatic void
Xregtail(p, val)
Xchar *p;
Xchar *val;
X{
X register char *scan;
X register char *temp;
X register int offset;
X
X if (p == ®dummy)
X return;
X
X /* Find last node. */
X scan = p;
X for (;;) {
X temp = regnext(scan);
X if (temp == NULL)
X break;
X scan = temp;
X }
X
X if (OP(scan) == BACK)
X offset = scan - val;
X else
X offset = val - scan;
X *(scan+1) = (offset>>8)&0377;
X *(scan+2) = offset&0377;
X}
X
X/*
X - regoptail - regtail on operand of first argument; nop if operandless
X */
Xstatic void
Xregoptail(p, val)
Xchar *p;
Xchar *val;
X{
X /* "Operandless" and "op != BRANCH" are synonymous in practice. */
X if (p == NULL || p == ®dummy || OP(p) != BRANCH)
X return;
X regtail(OPERAND(p), val);
X}
X
X/*
X * regexec and friends
X */
X
X/*
X * Global work variables for regexec().
X */
Xstatic char *reginput; /* String-input pointer. */
Xstatic char *regbol; /* Beginning of input, for ^ check. */
Xstatic char **regstartp; /* Pointer to startp array. */
Xstatic char **regendp; /* Ditto for endp. */
X
X/*
X * Forwards.
X */
XSTATIC int regtry();
XSTATIC int regmatch();
XSTATIC int regrepeat();
X
X#ifdef DEBUG
Xint regnarrate = 0;
Xvoid regdump();
XSTATIC char *regprop();
X#endif
X
X/*
X - regexec - match a regexp against a string
X */
Xint
Xregexec(prog, string)
Xregister regexp *prog;
Xregister char *string;
X{
X register char *s;
X
X /* Be paranoid... */
X if (prog == NULL || string == NULL) {
X regerror("NULL parameter");
X return(0);
X }
X
X /* Check validity of program. */
X if (UCHARAT(prog->program) != MAGIC) {
X regerror("corrupted program");
X return(0);
X }
X
X /* If there is a "must appear" string, look for it. */
X if (prog->regmust != NULL) {
X s = (char *)string;
X while ((s = strchr(s, prog->regmust[0])) != NULL) {
X if (strncmp(s, prog->regmust, prog->regmlen) == 0)
X break; /* Found it. */
X s++;
X }
X if (s == NULL) /* Not present. */
X return(0);
X }
X
X /* Mark beginning of line for ^ . */
X regbol = (char *)string;
X
X /* Simplest case: anchored match need be tried only once. */
X if (prog->reganch)
X return(regtry(prog, string));
X
X /* Messy cases: unanchored match. */
X s = (char *)string;
X if (prog->regstart != '\0')
X /* We know what char it must start with. */
X while ((s = strchr(s, prog->regstart)) != NULL) {
X if (regtry(prog, s))
X return(1);
X s++;
X }
X else
X /* We don't -- general case. */
X do {
X if (regtry(prog, s))
X return(1);
X } while (*s++ != '\0');
X
X /* Failure. */
X return(0);
X}
X
X/*
X - regtry - try match at specific point
X */
Xstatic int /* 0 failure, 1 success */
Xregtry(prog, string)
Xregexp *prog;
Xchar *string;
X{
X register int i;
X register char **sp;
X register char **ep;
X
X reginput = string;
X regstartp = prog->startp;
X regendp = prog->endp;
X
X sp = prog->startp;
X ep = prog->endp;
X for (i = NSUBEXP; i > 0; i--) {
X *sp++ = NULL;
X *ep++ = NULL;
X }
X if (regmatch(prog->program + 1)) {
X prog->startp[0] = string;
X prog->endp[0] = reginput;
X return(1);
X } else
X return(0);
X}
X
X/*
X - regmatch - main matching routine
X *
X * Conceptually the strategy is simple: check to see whether the current
X * node matches, call self recursively to see whether the rest matches,
X * and then act accordingly. In practice we make some effort to avoid
X * recursion, in particular by going through "ordinary" nodes (that don't
X * need to know whether the rest of the match failed) by a loop instead of
X * by recursion.
X */
Xstatic int /* 0 failure, 1 success */
Xregmatch(prog)
Xchar *prog;
X{
X register char *scan; /* Current node. */
X char *next; /* Next node. */
X
X scan = prog;
X#ifdef DEBUG
X if (scan != NULL && regnarrate)
X fprintf(stderr, "%s(\n", regprop(scan));
X#endif
X while (scan != NULL) {
X#ifdef DEBUG
X if (regnarrate)
X fprintf(stderr, "%s...\n", regprop(scan));
X#endif
X next = regnext(scan);
X
X switch (OP(scan)) {
X case BOL:
X if (reginput != regbol)
X return(0);
X break;
X case EOL:
X if (*reginput != '\0')
X return(0);
X break;
X case WORDA:
X /* Must be looking at a letter, digit, or _ */
X if ((!isalnum(*reginput)) && *reginput != '_')
X return(0);
X /* Prev must be BOL or nonword */
X if (reginput > regbol &&
X (isalnum(reginput[-1]) || reginput[-1] == '_'))
X return(0);
X break;
X case WORDZ:
X /* Must be looking at non letter, digit, or _ */
X if (isalnum(*reginput) || *reginput == '_')
X return(0);
X /* We don't care what the previous char was */
X break;
X case ANY:
X if (*reginput == '\0')
X return(0);
X reginput++;
X break;
X case EXACTLY: {
X register int len;
X register char *opnd;
X
X opnd = OPERAND(scan);
X /* Inline the first character, for speed. */
X if (*opnd != *reginput)
X return(0);
X len = strlen(opnd);
X if (len > 1 && strncmp(opnd, reginput, len) != 0)
X return(0);
X reginput += len;
X }
X break;
X case ANYOF:
X if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
X return(0);
X reginput++;
X break;
X case ANYBUT:
X if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
X return(0);
X reginput++;
X break;
X case NOTHING:
X break;
X case BACK:
X break;
X case OPEN+1:
X case OPEN+2:
X case OPEN+3:
X case OPEN+4:
X case OPEN+5:
X case OPEN+6:
X case OPEN+7:
X case OPEN+8:
X case OPEN+9: {
X register int no;
X register char *save;
X
X no = OP(scan) - OPEN;
X save = reginput;
X
X if (regmatch(next)) {
X /*
X * Don't set startp if some later
X * invocation of the same parentheses
X * already has.
X */
X if (regstartp[no] == NULL)
X regstartp[no] = save;
X return(1);
X } else
X return(0);
X }
X break;
X case CLOSE+1:
X case CLOSE+2:
X case CLOSE+3:
X case CLOSE+4:
X case CLOSE+5:
X case CLOSE+6:
X case CLOSE+7:
X case CLOSE+8:
X case CLOSE+9: {
X register int no;
X register char *save;
X
X no = OP(scan) - CLOSE;
X save = reginput;
X
X if (regmatch(next)) {
X /*
X * Don't set endp if some later
X * invocation of the same parentheses
X * already has.
X */
X if (regendp[no] == NULL)
X regendp[no] = save;
X return(1);
X } else
X return(0);
X }
X break;
X case BRANCH: {
X register char *save;
X
X if (OP(next) != BRANCH) /* No choice. */
X next = OPERAND(scan); /* Avoid recursion. */
X else {
X do {
X save = reginput;
X if (regmatch(OPERAND(scan)))
X return(1);
X reginput = save;
X scan = regnext(scan);
X } while (scan != NULL && OP(scan) == BRANCH);
X return(0);
X /* NOTREACHED */
X }
X }
X break;
X case STAR:
X case PLUS: {
X register char nextch;
X register int no;
X register char *save;
X register int min;
X
X /*
X * Lookahead to avoid useless match attempts
X * when we know what character comes next.
X */
X nextch = '\0';
X if (OP(next) == EXACTLY)
X nextch = *OPERAND(next);
X min = (OP(scan) == STAR) ? 0 : 1;
X save = reginput;
X no = regrepeat(OPERAND(scan));
X while (no >= min) {
X /* If it could work, try it. */
X if (nextch == '\0' || *reginput == nextch)
X if (regmatch(next))
X return(1);
X /* Couldn't or didn't -- back up. */
X no--;
X reginput = save + no;
X }
X return(0);
X }
X break;
X case END:
X return(1); /* Success! */
X break;
X default:
X regerror("memory corruption");
X return(0);
X break;
X }
X
X scan = next;
X }
X
X /*
X * We get here only if there's trouble -- normally "case END" is
X * the terminating point.
X */
X regerror("corrupted pointers");
X return(0);
X}
X
X/*
X - regrepeat - repeatedly match something simple, report how many
X */
Xstatic int
Xregrepeat(p)
Xchar *p;
X{
X register int count = 0;
X register char *scan;
X register char *opnd;
X
X scan = reginput;
X opnd = OPERAND(p);
X switch (OP(p)) {
X case ANY:
X count = strlen(scan);
X scan += count;
X break;
X case EXACTLY:
X while (*opnd == *scan) {
X count++;
X scan++;
X }
X break;
X case ANYOF:
X while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
X count++;
X scan++;
X }
X break;
X case ANYBUT:
X while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
X count++;
X scan++;
X }
X break;
X default: /* Oh dear. Called inappropriately. */
X regerror("internal foulup");
X count = 0; /* Best compromise. */
X break;
X }
X reginput = scan;
X
X return(count);
X}
X
X/*
X - regnext - dig the "next" pointer out of a node
X */
Xstatic char *
Xregnext(p)
Xregister char *p;
X{
X register int offset;
X
X if (p == ®dummy)
X return(NULL);
X
X offset = NEXT(p);
X if (offset == 0)
X return(NULL);
X
X if (OP(p) == BACK)
X return(p-offset);
X else
X return(p+offset);
X}
X
X#ifdef DEBUG
X
XSTATIC char *regprop();
X
X/*
X - regdump - dump a regexp onto stdout in vaguely comprehensible form
X */
Xvoid
Xregdump(r)
Xregexp *r;
X{
X register char *s;
X register char op = EXACTLY; /* Arbitrary non-END op. */
X register char *next;
X
X
X s = r->program + 1;
X while (op != END) { /* While that wasn't END last time... */
X op = OP(s);
X printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */
X next = regnext(s);
X if (next == NULL) /* Next ptr. */
X printf("(0)");
X else
X printf("(%d)", (s-r->program)+(next-s));
X s += 3;
X if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
X /* Literal string, where present. */
X while (*s != '\0') {
X putchar(*s);
X s++;
X }
X s++;
X }
X putchar('\n');
X }
X
X /* Header fields of interest. */
X if (r->regstart != '\0')
X printf("start `%c' ", r->regstart);
X if (r->reganch)
X printf("anchored ");
X if (r->regmust != NULL)
X printf("must have \"%s\"", r->regmust);
X printf("\n");
X}
X
X/*
X - regprop - printable representation of opcode
X */
Xstatic char *
Xregprop(op)
Xchar *op;
X{
X register char *p;
X static char buf[50];
X
X (void) strcpy(buf, ":");
X
X switch (OP(op)) {
X case BOL:
X p = "BOL";
X break;
X case EOL:
X p = "EOL";
X break;
X case ANY:
X p = "ANY";
X break;
X case ANYOF:
X p = "ANYOF";
X break;
X case ANYBUT:
X p = "ANYBUT";
X break;
X case BRANCH:
X p = "BRANCH";
X break;
X case EXACTLY:
X p = "EXACTLY";
X break;
X case NOTHING:
X p = "NOTHING";
X break;
X case BACK:
X p = "BACK";
X break;
X case END:
X p = "END";
X break;
X case OPEN+1:
X case OPEN+2:
X case OPEN+3:
X case OPEN+4:
X case OPEN+5:
X case OPEN+6:
X case OPEN+7:
X case OPEN+8:
X case OPEN+9:
X sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
X p = NULL;
X break;
X case CLOSE+1:
X case CLOSE+2:
X case CLOSE+3:
X case CLOSE+4:
X case CLOSE+5:
X case CLOSE+6:
X case CLOSE+7:
X case CLOSE+8:
X case CLOSE+9:
X sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
X p = NULL;
X break;
X case STAR:
X p = "STAR";
X break;
X case PLUS:
X p = "PLUS";
X break;
X case WORDA:
X p = "WORDA";
X break;
X case WORDZ:
X p = "WORDZ";
X break;
X default:
X regerror("corrupted opcode");
X break;
X }
X if (p != NULL)
X (void) strcat(buf, p);
X return(buf);
X}
X#endif
X
X/*
X * The following is provided for those people who do not have strcspn() in
X * their C libraries. They should get off their butts and do something
X * about it; at least one public-domain implementation of those (highly
X * useful) string routines has been published on Usenet.
X */
X#ifdef STRCSPN
X/*
X * strcspn - find length of initial segment of s1 consisting entirely
X * of characters not from s2
X */
X
Xstatic int
Xstrcspn(s1, s2)
Xchar *s1;
Xchar *s2;
X{
X register char *scan1;
X register char *scan2;
X register int count;
X
X count = 0;
X for (scan1 = s1; *scan1 != '\0'; scan1++) {
X for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */
X if (*scan1 == *scan2++)
X return(count);
X count++;
X }
X return(count);
X}
X#endif
END_OF_FILE
if test 31610 -ne `wc -c <'regexp.c'`; then
echo shar: \"'regexp.c'\" unpacked with wrong size!
fi
# end of 'regexp.c'
fi
echo shar: End of archive 3 \(of 7\).
cp /dev/null ark3isdone
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# Contents: Jambase.5 Jambase.ps Jamfile.5 variable.h
# Wrapped by kent@ftp on Sat Mar 25 12:04:10 1995
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 4 (of 7)."'
if test -f 'Jambase.5' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Jambase.5'\"
else
echo shar: Extracting \"'Jambase.5'\" \(11960 characters\)
sed "s/^X//" >'Jambase.5' <<'END_OF_FILE'
X.TH JAMBASE 5 "10 March 1995"
X.SH NAME
X\fBJambase\fR \- \fBjam\fR(1) boilerplate
X.SH FILES
X\fB/usr/local/lib/Jambase\fR
X.br
X\fBJamfile\fR
X
X.SH DESCRIPTION
X.PP
X\fBJambase\fR contains a set of \fBjam\fR rule definitions that provide
Xroughly \fBmake\fR(1)-like functionality. \fBJam\fR reads
X\fBJambase\fR, which in turn includes the \fBJamfile\fR from the
Xcurrent directory.
X.PP
XThis manual page lists the rules and variables defined in
X\fBJambase\fR. For a more readable guide to writing a \fBJamfile\fR,
Xsee \fBJamfile\fR(5).
X.SS Rules
X.de RP
X.IP "\fI\\$1\fR \\$2"
X.IP
X..
X.RP As "obj.o : source.s ;"
XAssemble the file \fIsource.s\fR. Called by the \fIObject\fR rule.
X.RP Bulk "directory : sources ;"
XCopies \fIsources\fR into \fIdirectory\fR. Dependencies of \fIfiles\fR.
X.RP Cc "object : source ;"
XCompile the file \fIsource\fR into \fIobject\fR, using the C compiler
X$(CC), its flags $(CCFLAGS) and $(OPTIM), and the header file
Xdirectories $(HDRS). Called by the \fIObject\fR rule.
X.RP C++ "obj.o : source.cc ;"
XCompile the C++ source file \fIsource.cc\fR. Called by the
X\fIObject\fR rule.
X.RP Clean "clean : targets ;"
XRemoves existing \fItargets\fR when \fIclean\fR is built. \fIclean\fR
Xis not a dependency of \fIall\fR, and must be built explicitly for
X\fItargets\fR to be removed.
X.RP File "target : source ;"
XCopies \fIsource\fR into \fItarget\fR. Dependency of \fIfiles\fR.
X.RP Fortran "obj.o : source.f ;"
XCompile the Fortran source file \fIsource.f\fR. Called by the
X\fIObject\fR rule.
X.RP HardLink "target : source ;"
XMakes \fItarget\fR a hard link to \fIsource\fR, if it isn't one
Xalready.
X.RP HdrRule "source : headers ;"
XArranges the proper dependencies when the file \fIsource\fR includes
Xthe files \fIheaders\fR through the "#include" C preprocessor
Xdirective. The \fIObject\fR rule arranges for this rule to be called
Xwhen \fBjam\fR does its header file scan of \fIsource\fR.
X.RP Install "target : source ;"
XCopies \fIsource\fR into \fItarget\fR, using \fIinstall\fR(1). Used by
Xthe other \fIInstall\fR* rules.
X.RP InstallBin "dir : sources ; "
XCopy \fIsources\fR into \fIdir\fR with mode $(EXEMODE). Dependencies of
X\fIinstall\fR.
X.RP InstallLib "dir : sources ;"
XCopy \fIsources\fR into \fIdir\fR with mode $(FILEMODE). Dependencies of
X\fIinstall\fR.
X.RP InstallMan "dir : sources ;"
XCopy \fIsources\fR into the appropriate subdirectory of \fIdir\fR with
Xmode $(FILEMODE). The subdirectory is \fBman\fIs\fR, where \fIs\fR
Xis the suffix of each of \fIsources\fR. Dependencies of \fIinstall\fR.
X.RP InstallShell "dir : sources ;"
XCopy \fIsources\fR into \fIdir\fR with mode $(SHELLMODE). Dependencies
Xof \fIinstall\fR.
X.RP Lex "source.c : source.l ;"
XProcess the \fBlex\fR(1) source file \fIsource.l\fR and rename the
Xlex.yy.c to \fIsource.c\fR. Called by the \fIObject\fR rule.
X.RP Library "library : sources ;"
XCompiles \fIsources\fR and archives them into \fIlibrary\fR. The
Xintermediate objects are deleted. Calls \fIObjects\fR and
X\fILibraryFromObjects\fR. Dependency of \fIlib\fR.
X.RP LibraryFromObjects "library : objects ;"
XArchives \fIobjects\fR into \fIlibrary\fR. The \fIobjects\fR are then
Xdeleted. Dependency of \fIlib\fR.
X.RP LinkLibraries "image : libraries ;"
XMakes \fIimage\fR depend on \fIlibraries\fR and includes them during
Xthe linking.
X.RP Main "image : sources ;"
XCompiles \fIsources\fR and links them into \fIimage\fR. Calls
X\fIObjects\fR and \fIMainFromObjects\fR. Dependency of \fIexe\fR.
X.RP MainFromObjects "image : objects ;"
XLinks \fIobjects\fR into \fIimage\fR. Dependency of \fIexe\fR.
X.RP Object "object : source ;"
XCompiles a single source file \fIsource\fR into \fIobject\fR. Makes
X\fIobject\fR depend on all header files included by \fIsource\fR. Such
Xdependencies are "soft": missing headers are not an error.
X.IP
XCalls one of the rules listed to do the actual compiling, depending
Xon the suffix of \fIsource\fR:
X.RS
X.IP
Xsource.c: \fICc\fR
X.br
Xsource.cc: \fIC++\fR
X.br
Xsource.cpp: \fIC++\fR
X.br
Xsource.C: \fIC++\fR
X.br
Xsource.l: \fILex\fR
X.br
Xsource.y: \fIYacc\fR
X.br
Xsource.*: \fIUserObject\fR
X.RE
X.IP
XThis rule is used by \fBObjects\fR.
X.RP ObjectCcFlags "source : flags ;"
XAdd \fIflags\fR to the \fIsource\fR-specific value of $(CCFLAGS) when
Xcompiling \fIsource\fR. Any file suffix on \fIsource\fR is ignored.
X.RP ObjectHdrs "source : dirs ;"
XAdd \fIdirs\fR to the \fIsource\fR-specific value of $(HDRS) when
Xscanning and compiling \fIsource\fR. Any file suffix on \fIsource\fR
Xis ignored.
X.RP Objects "sources ;"
XFor each source file in \fIsources\fR,
Xcalls \fIObject\fR to compile the source file into a similarly named
Xobject file.
X.RP RmTemps "targets : sources ;"
XMarks \fIsources\fR as temporary with the \fBTEMPORARY\fR rule, and
Xdeletes \fIsources\fR once \fItargets\fR are built. Must be the last
Xrule invoked on \fItargets\fR. Used internally by \fBObject\fR.
X.RP Setuid "images ;"
XSets the setuid bit on each of \fIimages\fR after linking.
X.RP Shell "image : source ;"
XCopies \fIsource\fR into the executable \fBsh\fR(1) script \fIimage\fR.
XEnsures that the first line of the script is $(SHELLHEADER) (default
X\fI#!/bin/sh\fR). Dependency of \fIshell\fR.
X.RP Undefines "images : symbols ;"
XTries to convince the linker that symbols need to be "undefined" for
Xthe linking of \fIimages\fR.
X.RP UserObject "object : source ;"
XComplains that the suffix on \fIsource\fR is unknown. This rule is called
Xby \fIObject\fR for source files with unknown suffixes, and should be replaced
Xwith a user-provided rule to handle the source file types.
X.RP Yacc "source.c : source.y ;"
XProcess the \fByacc\fR(1) file \fIsource.y\fR and renamed the resulting
Xy.tab.c and y.tab.h to \fIsource.c\fR. Produces a y.tab.h and renames it
Xto \fIsource\fR.h. Called by the \fIObject\fR rule.
X.SS Variables
X.PP
XThese variables are set in \fBJambase\fR only if they are not set in the
Xuser's environment, and so can be overridden with environment settings.
XMost variables are used by the actions of the related rules. When the
Xvariable is used by a rule's procedure (and therefore must be set before
Xinvoking the rule), it is marked with a \(bu.
X.PP
XAR (default \fI"ar ru"\fR)
X.IP
XThe archiver used for \fBLibrary\fR.
X.PP
XAS (default \fIas\fR)
X.IP
XThe assembler for \fBAs\fR.
X.PP
XASFLAGS (no default)
X.IP
XFlags handed to the assembler for \fBAs\fR.
X.PP
XAWK (\fIawk\fR)
X.IP
XThe name of awk interpreter, used when copying a shell script for
Xthe \fIShell\fR rule.
X.PP
XBINDIR (default \fI/usr/local/bin\fR)
X.IP
XNot used. Set for convenience.
X.PP
XCC (default \fIcc\fR)
X.IP
XC compiler used for \fBCc\fR.
X.PP
XCCFLAGS (no default) \(bu
X.IP
XFlags handed to the C compiler for \fBObject\fR. \fBOPTIM\fR is also
Xhanded to the C compiler.
X.PP
XC++ (default \fIgcc\fR)
X.IP
XC++ compiler used for \fBC++\fR.
X.PP
XC++FLAGS (no default) \(bu
X.IP
XFlags handed to the C++ compiler for \fBC++\fR. \fBOPTIM\fR is also
Xhanded to the C++ compiler.
X.PP
XCP (default \fIcp\fR)
X.IP
XThe file copy program, used by \fIFile\fR and \fIInstall\fR.
X.PP
XEXEMODE (default \fI711\fR)
X.IP
XPermissions for executables linked with \fBMain\fR.
X.PP
XFILEMODE (default \fI644\fR) \(bu
X.IP
XPermissions for files copied by \fBFile\fR or \fBBulk\fR.
X.PP
XFORTRAN (default \fIf77\fR)
X.IP
XThe Fortran compiler used by \fBFortran\fR.
X.PP
XFORTRANFLAGS (no default)
X.IP
XFlags handed to the Fortran compiler for \fBFortran\fR.
X.PP
XGROUP (no default)
X.IP
XThe group owner of installed filed. Used by \fIInstall\fR.
X.PP
XHDRPATTERN (default ^#[\\t ]*include[\\t ]*[<"](.*)[">].*$) \(bu
X.IP
XThe \fBregexp\fR(3) pattern for finding header file includes in source
Xfiles. The \fBObject\fR rule sets the \fBjam\fR-special variable
X\fBHDRSCAN\fR to $(HDRPATTERN) for all of its sources. The
Xcorresponding target of the \fBObject\fR rule invocation depends on all
Xheader files found.
X.PP
XHDRRULE (default HdrRule)
X.IP
XThe rule to invoke with the results of header file scanning.
XThis is a \fBjam\fR-special variable.
X.PP
XHDRSCAN (default $(HDRPATTERN))
X.IP
XThe \fBregexp\fR(3) pattern for header file scanning. This variable
Xand $(HDRRULE) trigger the scanning. This is a \fBjam\fR-special
Xvariable.
X.PP
XHDRS (no default) \(bu
X.IP
XDirectories to be scanned for header files and handed to the C compiler
Xwith -I. The \fBObject\fR rule sets \fBHDRS\fR to $(HDRS) for each of
Xits sources.
X.PP
XINSTALL (default \fIinstall\fR)
X.IP
XThe file copying program for the \fIInstall\fR rule. If not set
X\fIInstall\fR uses $(CP).
X.PP
XJAMFILE (default \fIJamfile\fR)
X.IP
XThe user-provided file listing the sources to be built.
X.PP
XJAMRULES (default \fIJamrules\fR)
X.IP
XThe name of the file included by the \fISubDir\fR rule.
X.PP
XLEX (default \fIlex\fR )
X.IP
XThe \fBlex\fR(1) command and flags.
X.PP
XLIBDIR (default \fI/usr/local/lib\fR)
X.IP
XNot used. Set for convenience.
X.PP
XLINK (default \fIcc\fR)
X.IP
XThe linker.
X.PP
XLINKFLAGS (default $(CCFLAGS))
X.IP
XFlags handed to the linker.
X.PP
XLINKLIBS (no default)
X.IP
XLibraries to hand to the linker. The target image does not depend on
Xthese libraries.
X.PP
XLOCATE_TARGET (no default) \(bu
X.IP
XThe directory for object modules and other intermediate files generated
Xby \fBObject\fR. This works by setting the \fBjam\fR-special variable
X\fBLOCATE\fR to the value of $(LOCATE_TARGET) for each of
X\fBObject\fR's targets.
X.PP
XLN (default \fIln\fR)
X.IP
XThe hard link command for \fIHardLink\fR.
X.PP
XMANDIR (default \fI/usr/local/man\fR)
X.IP
XNot used. Set for convenience.
X.PP
XMKDIR (default \fImkdir\fR)
X.IP
XThe program to create directories for the \fIMkDir\fR rule.
X.PP
XMODE (default varies)
X.IP
XThe file mode for files installed with \fIInstall\fR. Is set to
X$(EXEMODE), $(FILEMODE), or $(SHELLMODE) depending which rule invoked
X\fIInstall\fR.
X.PP
XMV (default \fImv -f\fR)
X.IP
XThe file rename command and options.
X.PP
XOPTIM (default \fI-O\fR)
X.IP
XMore flags handed to the C compiler.
X.PP
XOWNER (no default)
X.IP
XThe owner of installed filed. Used by \fIInstall\fR.
X.PP
XRANLIB (default \fIranlib\fR) \(bu
X.IP
XIf set, the command string to be invoked on each library after
Xarchiving.
X.PP
XRELOCATE (default unset)
X.IP
XIf set, tells the \fICc\fR rule to move the output object file to
Xits target directory because the cc command has a broken -o option.
X.PP
XRM (default \fIrm -f\fR)
X.IP
XThe command and options to remove a file.
X.PP
XSEARCH_SOURCE (no default) \(bu
X.IP
XThe directory to find sources listed with \fBMain\fR, \fBLibrary\fR,
X\fBObject\fR, \fBBulk\fR, \fBFile\fR, \fBShell\fR, \fBInstallBin\fR,
X\fBInstallLib\fR, and \fBInstallMan\fR rules. This works by setting
Xthe \fBjam\fR-special variable \fBSEARCH\fR to the value of
X$(SEARCH_SOURCE) for each of the rules' sources.
X.PP
XSHELLHEADER (default \fI#!/bin/sh\fR)
X.IP
XA string inserted to the first line of every file created by the
X\fBShell\fR rule.
X.PP
XSHELLMODE (default \fI755\fR) \(bu
X.IP
XPermissions for files installed by \fBShell\fR.
X.PP
XSLASH (default \fI/\fR) \(bu
X.IP
XThe directory separator. Used by \fISubDir\fR and \fISubInclude\fR
Xto build up a directory path.
X.PP
XSOURCE_GRIST (no default) \(bu
X.IP
XSet by the \fISubDir\fR to a value derived from the directory name, and
Xused by \fIObjects\fR and related rules as 'grist' to perturb file names.
X.PP
XSTDHDRS (default \fI/usr/include\fR) \(bu
X.IP
XDirectories where headers can be found without resorting to using the
X\fIflag\fR to the C compiler.
X.PP
XSUBDIR (no default)
X.IP
XSet by \fISubDir\fR to be the named directory.
X.PP
XSUFEXE (default "") \(bu
X.IP
XThe suffix for executable files, if none provided. Used by the
X\fIMain\fR rule.
X.PP
XSUFLIB (default \fI.a\fR) \(bu
X.IP
XThe suffix for libraries. Used by the \fILibrary\fR and related rules.
X.PP
XSUFOBJ (default \fI.o\fR) \(bu
X.IP
XThe suffix for object files. Used by the \fIObjects\fR and related rules.
X.PP
XUNDEFFLAG (default \fI-u _\fR)
X.IP
XThe flag prefixed to each symbol for the \fBUndefines\fR rule.
X.PP
XYACC (default \fIyacc -d\fR)
X.IP
XThe \fByacc\fR(1) command and flags.
X
X.SH SEE ALSO
X\fBjam\fR(1), \fBJamfile\fR(5)
END_OF_FILE
if test 11960 -ne `wc -c <'Jambase.5'`; then
echo shar: \"'Jambase.5'\" unpacked with wrong size!
fi
# end of 'Jambase.5'
fi
if test -f 'Jambase.ps' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Jambase.ps'\"
else
echo shar: Extracting \"'Jambase.ps'\" \(28776 characters\)
sed "s/^X//" >'Jambase.ps' <<'END_OF_FILE'
X%!PS-Adobe-3.0
X%%Creator: groff version 1.08
X%%DocumentNeededResources: font Times-Roman
X%%+ font Times-Bold
X%%+ font Times-Italic
X%%DocumentSuppliedResources: procset grops 1.08 0
X%%Pages: 6
X%%IncludeResource: font Times-Roman
X%%IncludeResource: font Times-Bold
X%%IncludeResource: font Times-Italic
X/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE
X/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE
X%%EndProlog
X%%Page: 1 1
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF -.6(JA)72 48 S(MB).6 E 352.96(ASE\(5\) J)-.35 F(AMB)-.6
XE(ASE\(5\))-.35 E/F1 9/Times-Bold@0 SF -.18(NA)72 84 S(ME).18 E/F2 10
X/Times-Bold@0 SF -.15(Ja)108 96 S(mbase).15 E F0<ad>2.5 E F2(jam)2.5 E F0
X(\(1\) boilerplate)A F1(FILES)72 112.8 Q F2(/usr/local/lib/J)108 124.8 Q
X(ambase)-.15 E -.15(Ja)108 136.8 S(m\214le).15 E F1(DESCRIPTION)72 165.6 Q F2
X-.15(Ja)108 177.6 S(mbase).15 E F0 .28(contains a set of)2.78 F F2(jam)2.779 E
XF0 .279(rule de\214nitions that pro)2.779 F .279(vide roughly)-.15 F F2(mak)
X2.779 E(e)-.1 E F0(\(1\)-lik)A 2.779(ef)-.1 G(unctionality)443.032 177.6 Q(.)
X-.65 E F2 -.15(Ja)5.279 G(m).15 E F0(reads)2.779 E F2 -.15(Ja)108 189.6 S
X(mbase).15 E F0 2.5(,w)C(hich in turn includes the)157.29 189.6 Q F2 -.15(Ja)
X2.5 G(m\214le).15 E F0(from the current directory)2.5 E(.)-.65 E .422
X(This manual page lists the rules and v)108 206.4 R .423(ariables de\214ned in)
X-.25 F F2 -.15(Ja)2.923 G(mbase).15 E F0 5.423(.F)C .423
X(or a more readable guide to writing a)389.019 206.4 R F2 -.15(Ja)108 218.4 S
X(m\214le).15 E F0 2.5(,s)C(ee)147.85 218.4 Q F2 -.15(Ja)2.5 G(m\214le).15 E F0
X(\(5\).)A F2(Rules)87 235.2 Q/F3 10/Times-Italic@0 SF(As)108 247.2 Q F0
X(obj.o : source.s ;)2.5 E(Assemble the \214le)144 264 Q F3(sour)2.5 E(ce)-.37 E
X(.s)-.15 E F0 5(.C)C(alled by the)262.64 264 Q F3(Object)2.5 E F0(rule.)2.5 E
XF3(Bulk)108 280.8 Q F0(directory : sources ;)2.5 E(Copies)144 297.6 Q F3(sour)
X2.5 E(ces)-.37 E F0(into)2.5 E F3(dir)2.5 E(ectory)-.37 E F0 2.5(.D)C
X(ependencies of)273.53 297.6 Q F3(\214les)2.5 E F0(.)A F3(Cc)108 314.4 Q F0
X(object : source ;)2.5 E 2.15(Compile the \214le)144 331.2 R F3(sour)4.65 E(ce)
X-.37 E F0(into)4.65 E F3(object)4.65 E F0 4.65(,u)C 2.15
X(sing the C compiler $\(CC\), its \215ags $\(CCFLA)305.14 331.2 R 2.15
X(GS\) and)-.4 F($\(OPTIM\), and the header \214le directories $\(HDRS\).)144
X343.2 Q(Called by the)5 E F3(Object)2.5 E F0(rule.)2.5 E F3(C++)108 360 Q F0
X(obj.o : source.cc ;)2.5 E(Compile the C++ source \214le)144 376.8 Q F3(sour)
X2.5 E(ce)-.37 E(.cc)-.15 E F0 5(.C)C(alled by the)311.69 376.8 Q F3(Object)2.5
XE F0(rule.)2.5 E F3(Clean)108 393.6 Q F0(clean : tar)2.5 E(gets ;)-.18 E(Remo)
X144 410.4 Q -.15(ve)-.15 G 3.005(se).15 G(xisting)188.215 410.4 Q F3(tar)3.005
XE -.1(ge)-.37 G(ts).1 E F0(when)3.006 E F3(clean)3.006 E F0 .506(is b)3.006 F
X(uilt.)-.2 E F3(clean)5.506 E F0 .506(is not a dependenc)3.006 F 3.006(yo)-.15
XG(f)447.11 410.4 Q F3(all)3.006 E F0 3.006(,a)C .506(nd must be b)473.952 410.4
XR(uilt)-.2 E -.15(ex)144 422.4 S(plicitly for).15 E F3(tar)2.5 E -.1(ge)-.37 G
X(ts).1 E F0(to be remo)2.5 E -.15(ve)-.15 G(d.).15 E F3 -.45(Fi)108 439.2 S(le)
X.45 E F0(tar)2.5 E(get : source ;)-.18 E(Copies)144 456 Q F3(sour)2.5 E(ce)-.37
XE F0(into)2.5 E F3(tar)2.5 E -.1(ge)-.37 G(t).1 E F0 5(.D)C(ependenc)259.27 456
XQ 2.5(yo)-.15 G(f)309.38 456 Q F3(\214les)2.5 E F0(.)A F3 -1.05(Fo)108 472.8 S
X(rtr)1.05 E(an)-.15 E F0(obj.o : source.f ;)2.5 E(Compile the F)144 489.6 Q
X(ortran source \214le)-.15 E F3(sour)2.5 E(ce)-.37 E(.f)-.15 E F0 5(.C)C
X(alled by the)316.93 489.6 Q F3(Object)2.5 E F0(rule.)2.5 E F3(Har)108 506.4 Q
X(dLink)-.37 E F0(tar)2.5 E(get : source ;)-.18 E(Mak)144 523.2 Q(es)-.1 E F3
X(tar)2.5 E -.1(ge)-.37 G(t).1 E F0 2.5(ah)2.5 G(ard link to)210.92 523.2 Q F3
X(sour)2.5 E(ce)-.37 E F0 2.5(,i)C 2.5(fi)288.6 523.2 S 2.5(ti)297.21 523.2 S
X(sn')305.27 523.2 Q 2.5(to)-.18 G(ne already)327.59 523.2 Q(.)-.65 E F3
X(HdrRule)108 540 Q F0(source : headers ;)2.5 E 1.893
X(Arranges the proper dependencies when the \214le)144 556.8 R F3(sour)4.392 E
X(ce)-.37 E F0 1.892(includes the \214les)4.392 F F3(header)4.392 E(s)-.1 E F0
X1.892(through the)4.392 F .389("#include" C preprocessor directi)144 568.8 R
X-.15(ve)-.25 G 5.389(.T).15 G(he)301.616 568.8 Q F3(Object)2.889 E F0 .389
X(rule arranges for this rule to be called when)2.889 F F2(jam)2.89 E F0
X(does its header \214le scan of)144 580.8 Q F3(sour)2.5 E(ce)-.37 E F0(.)A F3
X(Install)108 597.6 Q F0(tar)2.5 E(get : source ;)-.18 E(Copies)144 614.4 Q F3
X(sour)2.5 E(ce)-.37 E F0(into)2.5 E F3(tar)2.5 E -.1(ge)-.37 G(t).1 E F0 2.5
X(,u)C(sing)254.55 614.4 Q F3(install)2.5 E F0 2.5(\(1\). Used)B(by the other)
X2.5 E F3(Install)2.5 E F0 2.5(*r)C(ules.)427.6 614.4 Q F3(InstallBin)108 631.2
XQ F0(dir : sources ;)2.5 E(Cop)144 648 Q(y)-.1 E F3(sour)2.5 E(ces)-.37 E F0
X(into)2.5 E F3(dir)2.5 E F0(with mode $\(EXEMODE\).)2.5 E(Dependencies of)5 E
XF3(install)2.5 E F0(.)A F3(InstallLib)108 664.8 Q F0(dir : sources ;)2.5 E(Cop)
X144 681.6 Q(y)-.1 E F3(sour)2.5 E(ces)-.37 E F0(into)2.5 E F3(dir)2.5 E F0
X(with mode $\(FILEMODE\).)2.5 E(Dependencies of)5 E F3(install)2.5 E F0(.)A F3
X(InstallMan)108 698.4 Q F0(dir : sources ;)2.5 E(Cop)144 715.2 Q(y)-.1 E F3
X(sour)3.415 E(ces)-.37 E F0 .914(into the appropriate subdirectory of)3.415 F
XF3(dir)3.414 E F0 .914(with mode $\(FILEMODE\).)3.414 F .914(The subdirec-)
X5.914 F(tory is)144 727.2 Q F2(man)2.5 E F3(s)A F0 2.5(,w)C(here)206.78 727.2 Q
XF3(s)2.5 E F0(is the suf)2.5 E(\214x of each of)-.25 E F3(sour)2.5 E(ces)-.37 E
XF0 5(.D)C(ependencies of)369.18 727.2 Q F3(install)2.5 E F0(.)A(10 March 1995)
X275.45 768 Q(1)535 768 Q EP
X%%Page: 2 2
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF -.6(JA)72 48 S(MB).6 E 352.96(ASE\(5\) J)-.35 F(AMB)-.6
XE(ASE\(5\))-.35 E/F1 10/Times-Italic@0 SF(InstallShell)108 84 Q F0
X(dir : sources ;)2.5 E(Cop)144 100.8 Q(y)-.1 E F1(sour)2.5 E(ces)-.37 E F0
X(into)2.5 E F1(dir)2.5 E F0(with mode $\(SHELLMODE\).)2.5 E(Dependencies of)5 E
XF1(install)2.5 E F0(.)A F1(Le)108 117.6 Q(x)-.2 E F0(source.c : source.l ;)2.5
XE .916(Process the)144 134.4 R/F2 10/Times-Bold@0 SF(lex)3.416 E F0 .916
X(\(1\) source \214le)B F1(sour)3.416 E(ce)-.37 E(.l)-.15 E F0 .917
X(and rename the le)3.417 F(x.yy)-.15 E .917(.c to)-.65 F F1(sour)3.417 E(ce)
X-.37 E(.c)-.15 E F0 5.917(.C)C .917(alled by the)461.429 134.4 R F1(Object)
X3.417 E F0(rule.)144 146.4 Q F1(Libr)108 163.2 Q(ary)-.15 E F0
X(library : sources ;)2.5 E(Compiles)144 180 Q F1(sour)4.285 E(ces)-.37 E F0
X1.784(and archi)4.285 F -.15(ve)-.25 G 4.284(st).15 G 1.784(hem into)279.798
X180 R F1(libr)4.284 E(ary)-.15 E F0 6.784(.T)C 1.784
X(he intermediate objects are deleted.)364.17 180 R(Calls)6.784 E F1(Objects)144
X192 Q F0(and)2.5 E F1(Libr)2.5 E(aryF)-.15 E -.45(ro)-.55 G(mObjects).45 E F0 5
X(.D)C(ependenc)290.89 192 Q 2.5(yo)-.15 G(f)341 192 Q F1(lib)2.5 E F0(.)A F1
X(Libr)108 208.8 Q(aryF)-.15 E -.45(ro)-.55 G(mObjects).45 E F0
X(library : objects ;)2.5 E(Archi)144 225.6 Q -.15(ve)-.25 G(s).15 E F1(objects)
X2.5 E F0(into)2.5 E F1(libr)2.5 E(ary)-.15 E F0 5(.T)C(he)272.33 225.6 Q F1
X(objects)2.5 E F0(are then deleted.)2.5 E(Dependenc)5 E 2.5(yo)-.15 G(f)443.24
X225.6 Q F1(lib)2.5 E F0(.)A F1(LinkLibr)108 242.4 Q(aries)-.15 E F0
X(image : libraries ;)2.5 E(Mak)144 259.2 Q(es)-.1 E F1(ima)2.5 E -.1(ge)-.1 G
XF0(depend on)2.6 E F1(libr)2.5 E(aries)-.15 E F0
X(and includes them during the linking.)2.5 E F1(Main)108 276 Q F0
X(image : sources ;)2.5 E(Compiles)144 292.8 Q F1(sour)3.23 E(ces)-.37 E F0 .73
X(and links them into)3.23 F F1(ima)3.23 E -.1(ge)-.1 G F0 5.73(.C).1 G(alls)
X340.49 292.8 Q F1(Objects)3.23 E F0(and)3.23 E F1(MainF)3.23 E -.45(ro)-.55 G
X(mObjects).45 E F0 5.73(.D)C(ependenc)497.39 292.8 Q(y)-.15 E(of)144 304.8 Q F1
X-.2(ex)2.5 G(e).2 E F0(.)A F1(MainF)108 321.6 Q -.45(ro)-.55 G(mObjects).45 E
XF0(image : objects ;)2.5 E(Links)144 338.4 Q F1(objects)2.5 E F0(into)2.5 E F1
X(ima)2.5 E -.1(ge)-.1 G F0 5(.D).1 G(ependenc)257.13 338.4 Q 2.5(yo)-.15 G(f)
X307.24 338.4 Q F1 -.2(ex)2.5 G(e).2 E F0(.)A F1(Object)108 355.2 Q F0
X(object : source ;)2.5 E .268(Compiles a single source \214le)144 372 R F1
X(sour)2.768 E(ce)-.37 E F0(into)2.768 E F1(object)2.768 E F0 5.268(.M)C(ak)
X351.874 372 Q(es)-.1 E F1(object)2.768 E F0 .268
X(depend on all header \214les included)2.768 F(by)144 384 Q F1(sour)2.5 E(ce)
X-.37 E F0 5(.S)C(uch dependencies are "soft": missing headers are not an error)
X195.85 384 Q(.)-.55 E(Calls one of the rules listed to do the actual compiling\
X, depending on the suf)144 400.8 Q(\214x of)-.25 E F1(sour)2.5 E(ce)-.37 E F0
X(:)A(source.c:)180 417.6 Q F1(Cc)2.5 E F0(source.cc:)180 429.6 Q F1(C++)2.5 E
XF0(source.cpp:)180 441.6 Q F1(C++)2.5 E F0(source.C:)180 453.6 Q F1(C++)2.5 E
XF0(source.l:)180 465.6 Q F1(Le)2.5 E(x)-.2 E F0(source.y:)180 477.6 Q F1 -.92
X(Ya)2.5 G(cc).92 E F0(source.*:)180 489.6 Q F1(UserObject)2.5 E F0
X(This rule is used by)144 506.4 Q F2(Objects)2.5 E F0(.)A F1(ObjectCcFla)108
X523.2 Q(gs)-.1 E F0(source : \215ags ;)2.5 E(Add)144 540 Q F1<8d61>2.708 E(gs)
X-.1 E F0 .208(to the)2.708 F F1(sour)2.708 E(ce)-.37 E F0 .208(-speci\214c v)B
X.208(alue of $\(CCFLA)-.25 F .209(GS\) when compiling)-.4 F F1(sour)2.709 E(ce)
X-.37 E F0 5.209(.A)C .509 -.15(ny \214)476.713 540 T .209(le suf).15 F .209
X(\214x on)-.25 F F1(sour)144 552 Q(ce)-.37 E F0(is ignored.)2.5 E F1(ObjectHdr)
X108 568.8 Q(s)-.1 E F0(source : dirs ;)2.5 E(Add)144 585.6 Q F1(dir)2.981 E(s)
X-.1 E F0 .481(to the)2.981 F F1(sour)2.981 E(ce)-.37 E F0 .481(-speci\214c v)B
X.481(alue of $\(HDRS\) when scanning and compiling)-.25 F F1(sour)2.98 E(ce)
X-.37 E F0 5.48(.A)C .78 -.15(ny \214)514.39 585.6 T(le).15 E(suf)144 597.6 Q
X(\214x on)-.25 E F1(sour)2.5 E(ce)-.37 E F0(is ignored.)2.5 E F1(Objects)108
X614.4 Q F0(sources ;)2.5 E -.15(Fo)144 631.2 S 4.143(re).15 G 1.643
X(ach source \214le in)166.323 631.2 R F1(sour)4.143 E(ces)-.37 E F0 4.143(,c)C
X(alls)284.698 631.2 Q F1(Object)4.143 E F0 1.643
X(to compile the source \214le into a similarly named)4.143 F(object \214le.)144
X643.2 Q F1(RmT)108 660 Q(emps)-.92 E F0(tar)2.5 E(gets : sources ;)-.18 E
X(Marks)144 676.8 Q F1(sour)3.6 E(ces)-.37 E F0 1.1(as temporary with the)3.6 F
XF2(TEMPORAR)3.6 E(Y)-.35 E F0 1.1(rule, and deletes)3.6 F F1(sour)3.6 E(ces)
X-.37 E F0(once)3.6 E F1(tar)3.6 E -.1(ge)-.37 G(ts).1 E F0(are)3.6 E -.2(bu)144
X688.8 S 2.5(ilt. Must).2 F(be the last rule in)2.5 E -.2(vo)-.4 G -.1(ke).2 G
X2.5(do).1 G(n)292.82 688.8 Q F1(tar)2.5 E -.1(ge)-.37 G(ts).1 E F0 5(.U)C
X(sed internally by)342.35 688.8 Q F2(Object)2.5 E F0(.)A F1(Setuid)108 705.6 Q
XF0(images ;)2.5 E(10 March 1995)275.45 768 Q(2)535 768 Q EP
X%%Page: 3 3
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF -.6(JA)72 48 S(MB).6 E 352.96(ASE\(5\) J)-.35 F(AMB)-.6
XE(ASE\(5\))-.35 E(Sets the setuid bit on each of)144 84 Q/F1 10/Times-Italic@0
XSF(ima)2.5 E -.1(ge)-.1 G(s).1 E F0(after linking.)2.5 E F1(Shell)108 100.8 Q
XF0(image : source ;)2.5 E(Copies)144 117.6 Q F1(sour)3.765 E(ce)-.37 E F0 1.265
X(into the e)3.765 F -.15(xe)-.15 G(cutable).15 E/F2 10/Times-Bold@0 SF(sh)3.765
XE F0 1.265(\(1\) script)B F1(ima)3.765 E -.1(ge)-.1 G F0 6.265(.E).1 G 1.265
X(nsures that the \214rst line of the script is)377.11 117.6 R
X($\(SHELLHEADER\) \(def)144 129.6 Q(ault)-.1 E F1(#!/bin/sh)2.5 E F0 2.5
X(\). Dependenc)B 2.5(yo)-.15 G(f)367.04 129.6 Q F1(shell)2.5 E F0(.)A F1
X(Unde\214nes)108 146.4 Q F0(images : symbols ;)2.5 E -.35(Tr)144 163.2 S
X(ies to con).35 E(vince the link)-.4 E
X(er that symbols need to be "unde\214ned" for the linking of)-.1 E F1(ima)2.5 E
X-.1(ge)-.1 G(s).1 E F0(.)A F1(UserObject)108 180 Q F0(object : source ;)2.5 E
X.161(Complains that the suf)144 196.8 R .161(\214x on)-.25 F F1(sour)2.661 E
X(ce)-.37 E F0 .161(is unkno)2.661 F 2.661(wn. This)-.25 F .16
X(rule is called by)2.661 F F1(Object)2.66 E F0 .16(for source \214les with)2.66
XF(unkno)144 208.8 Q .119(wn suf)-.25 F<8c78>-.25 E .119
X(es, and should be replaced with a user)-.15 F(-pro)-.2 E .12
X(vided rule to handle the source \214le types.)-.15 F F1 -.92(Ya)108 225.6 S
X(cc).92 E F0(source.c : source.y ;)2.5 E 1.175(Process the)144 242.4 R F2(yacc)
X3.675 E F0 1.175(\(1\) \214le)B F1(sour)3.675 E(ce)-.37 E(.y)-.15 E F0 1.174
X(and renamed the resulting y)3.674 F(.tab)-.65 E 1.174(.c and y)-.4 F(.tab)-.65
XE 1.174(.h to)-.4 F F1(sour)3.674 E(ce)-.37 E(.c)-.15 E F0 6.174(.P)C(ro-)
X528.34 242.4 Q(duces a y)144 254.4 Q(.tab)-.65 E(.h and renames it to)-.4 E F1
X(sour)2.5 E(ce)-.37 E F0 2.5(.h. Called)B(by the)2.5 E F1(Object)2.5 E F0
X(rule.)2.5 E F2 -.92(Va)87 271.2 S(riables).92 E F0 .125(These v)108 283.2 R
X.125(ariables are set in)-.25 F F2 -.15(Ja)2.625 G(mbase).15 E F0 .125
X(only if the)2.625 F 2.625(ya)-.15 G .125(re not set in the user')304.925 283.2
XR 2.625(se)-.55 G -.4(nv)400.105 283.2 S .125(ironment, and so can be o).4 F
X-.15(ve)-.15 G(rrid-).15 E .42(den with en)108 295.2 R .42(vironment settings.)
X-.4 F .42(Most v)5.42 F .42
X(ariables are used by the actions of the related rules.)-.25 F .42(When the v)
X5.42 F(ari-)-.25 E .138(able is used by a rule')108 307.2 R 2.638(sp)-.55 G
X.138(rocedure \(and therefore must be set before in)207.148 307.2 R -.2(vo)-.4
XG .138(king the rule\), it is mark).2 F .139(ed with a \203.)-.1 F(AR \(def)108
X324 Q(ault)-.1 E F1("ar ru")2.5 E F0(\))A(The archi)144 340.8 Q -.15(ve)-.25 G
X2.5(ru).15 G(sed for)201.91 340.8 Q F2(Library)2.5 E F0(.)A(AS \(def)108 357.6
XQ(ault)-.1 E F1(as)2.5 E F0(\))A(The assembler for)144 374.4 Q F2(As)2.5 E F0
X(.)A(ASFLA)108 391.2 Q(GS \(no def)-.4 E(ault\))-.1 E
X(Flags handed to the assembler for)144 408 Q F2(As)2.5 E F0(.)A -.9(AW)108
X424.8 S 2.5(K\().9 G F1(awk)136.81 424.8 Q F0(\))A(The name of a)144 441.6 Q
X(wk interpreter)-.15 E 2.5(,u)-.4 G(sed when cop)267.3 441.6 Q
X(ying a shell script for the)-.1 E F1(Shell)2.5 E F0(rule.)2.5 E(BINDIR \(def)
X108 458.4 Q(ault)-.1 E F1(/usr/local/bin)2.5 E F0(\))A(Not used.)144 475.2 Q
X(Set for con)5 E -.15(ve)-.4 G(nience.).15 E(CC \(def)108 492 Q(ault)-.1 E F1
X(cc)2.5 E F0(\))A 2.5(Cc)144 508.8 S(ompiler used for)157.61 508.8 Q F2(Cc)2.5
XE F0(.)A(CCFLA)108 525.6 Q(GS \(no def)-.4 E(ault\) \203)-.1 E
X(Flags handed to the C compiler for)144 542.4 Q F2(Object)2.5 E F0(.)A F2
X(OPTIM)5 E F0(is also handed to the C compiler)2.5 E(.)-.55 E(C++ \(def)108
X559.2 Q(ault)-.1 E F1(gcc)2.5 E F0(\))A(C++ compiler used for)144 576 Q F2(C++)
X2.5 E F0(.)A(C++FLA)108 592.8 Q(GS \(no def)-.4 E(ault\) \203)-.1 E
X(Flags handed to the C++ compiler for)144 609.6 Q F2(C++)2.5 E F0(.)A F2(OPTIM)
X5 E F0(is also handed to the C++ compiler)2.5 E(.)-.55 E(CP \(def)108 626.4 Q
X(ault)-.1 E F1(cp)2.5 E F0(\))A(The \214le cop)144 643.2 Q 2.5(yp)-.1 G
X(rogram, used by)204.17 643.2 Q F1 -.45(Fi)2.5 G(le).45 E F0(and)2.5 E F1
X(Install)2.5 E F0(.)A(EXEMODE \(def)108 660 Q(ault)-.1 E F1(711)2.5 E F0(\))A
X(Permissions for e)144 676.8 Q -.15(xe)-.15 G(cutables link).15 E(ed with)-.1 E
XF2(Main)2.5 E F0(.)A(FILEMODE \(def)108 693.6 Q(ault)-.1 E F1(644)2.5 E F0 2.5
X<2983>C(Permissions for \214les copied by)144 710.4 Q F2(File)2.5 E F0(or)2.5 E
XF2(Bulk)2.5 E F0(.)A(FOR)108 727.2 Q(TRAN \(def)-.6 E(ault)-.1 E F1(f77)2.5 E
XF0(\))A(10 March 1995)275.45 768 Q(3)535 768 Q EP
X%%Page: 4 4
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF -.6(JA)72 48 S(MB).6 E 352.96(ASE\(5\) J)-.35 F(AMB)-.6
XE(ASE\(5\))-.35 E(The F)144 84 Q(ortran compiler used by)-.15 E/F1 10
X/Times-Bold@0 SF -.25(Fo)2.5 G(rtran).25 E F0(.)A(FOR)108 100.8 Q(TRANFLA)-.6 E
X(GS \(no def)-.4 E(ault\))-.1 E(Flags handed to the F)144 117.6 Q
X(ortran compiler for)-.15 E F1 -.25(Fo)2.5 G(rtran).25 E F0(.)A(GR)108 134.4 Q
X(OUP \(no def)-.4 E(ault\))-.1 E(The group o)144 151.2 Q
X(wner of installed \214led.)-.25 E(Used by)5 E/F2 10/Times-Italic@0 SF(Install)
X2.5 E F0(.)A(HDRP)108 168 Q -1.11(AT)-.92 G(TERN \(def)1.11 E
X(ault ^#[\\t ]*include[\\t ]*[<"]\(.*\)[">].*$\) \203)-.1 E(The)144 184.8 Q F1
X-.18(re)3.788 G(gexp).18 E F0 1.287
X(\(3\) pattern for \214nding header \214le includes in source \214les.)B(The)
X6.287 E F1(Object)3.787 E F0 1.287(rule sets the)3.787 F F1(jam)144 196.8 Q F0
X.784(-special v)B(ariable)-.25 E F1(HDRSCAN)3.284 E F0 .784(to $\(HDRP)3.284 F
X-1.11(AT)-.92 G .785(TERN\) for all of its sources.)1.11 F .785
X(The corresponding)5.785 F(tar)144 208.8 Q(get of the)-.18 E F1(Object)2.5 E F0
X(rule in)2.5 E -.2(vo)-.4 G(cation depends on all header \214les found.).2 E
X(HDRR)108 225.6 Q(ULE \(def)-.4 E(ault HdrRule\))-.1 E(The rule to in)144 242.4
XQ -.2(vo)-.4 G .2 -.1(ke w).2 H(ith the results of header \214le scanning.).1 E
X(This is a)5 E F1(jam)2.5 E F0(-special v)A(ariable.)-.25 E(HDRSCAN \(def)108
X259.2 Q(ault $\(HDRP)-.1 E -1.11(AT)-.92 G(TERN\)\))1.11 E(The)144 276 Q F1
X-.18(re)2.927 G(gexp).18 E F0 .426(\(3\) pattern for header \214le scanning.)B
X.426(This v)5.426 F .426(ariable and $\(HDRR)-.25 F .426
X(ULE\) trigger the scan-)-.4 F 2.5(ning. This)144 288 R(is a)2.5 E F1(jam)2.5 E
XF0(-special v)A(ariable.)-.25 E(HDRS \(no def)108 304.8 Q(ault\) \203)-.1 E .57
X(Directories to be scanned for header \214les and handed to the C compiler wit\
Xh -I.)144 321.6 R(The)5.571 E F1(Object)3.071 E F0(rule)3.071 E(sets)144 333.6
XQ F1(HDRS)2.5 E F0(to $\(HDRS\) for each of its sources.)2.5 E(INST)108 350.4 Q
X(ALL \(def)-.93 E(ault)-.1 E F2(install)2.5 E F0(\))A(The \214le cop)144 367.2
XQ(ying program for the)-.1 E F2(Install)2.5 E F0 2.5(rule. If)2.5 F(not set)2.5
XE F2(Install)2.5 E F0(uses $\(CP\).)2.5 E -.6(JA)108 384 S(MFILE \(def).6 E
X(ault)-.1 E F2 -.35(Ja)2.5 G(m\214le).35 E F0(\))A(The user)144 400.8 Q(-pro)
X-.2 E(vided \214le listing the sources to be b)-.15 E(uilt.)-.2 E -.6(JA)108
X417.6 S(MR).6 E(ULES \(def)-.4 E(ault)-.1 E F2 -.35(Ja)2.5 G(mrules).35 E F0
X(\))A(The name of the \214le included by the)144 434.4 Q F2(SubDir)2.5 E F0
X(rule.)2.5 E(LEX \(def)108 451.2 Q(ault)-.1 E F2(le)2.5 E(x)-.2 E F0(\))2.5 E
X(The)144 468 Q F1(lex)2.5 E F0(\(1\) command and \215ags.)A(LIBDIR \(def)108
X484.8 Q(ault)-.1 E F2(/usr/local/lib)2.5 E F0(\))A(Not used.)144 501.6 Q
X(Set for con)5 E -.15(ve)-.4 G(nience.).15 E(LINK \(def)108 518.4 Q(ault)-.1 E
XF2(cc)2.5 E F0(\))A(The link)144 535.2 Q(er)-.1 E(.)-.55 E(LINKFLA)108 552 Q
X(GS \(def)-.4 E(ault $\(CCFLA)-.1 E(GS\)\))-.4 E(Flags handed to the link)144
X568.8 Q(er)-.1 E(.)-.55 E(LINKLIBS \(no def)108 585.6 Q(ault\))-.1 E
X(Libraries to hand to the link)144 602.4 Q(er)-.1 E 5(.T)-.55 G(he tar)276.11
X602.4 Q(get image does not depend on these libraries.)-.18 E(LOCA)108 619.2 Q
X(TE_T)-1.11 E(ARGET \(no def)-.93 E(ault\) \203)-.1 E .203
X(The directory for object modules and other intermediate \214les generated by)
X144 636 R F1(Object)2.703 E F0 5.203(.T)C .202(his w)488.586 636 R .202
X(orks by)-.1 F 2.046(setting the)144 648 R F1(jam)4.546 E F0 2.046(-special v)B
X(ariable)-.25 E F1(LOCA)4.546 E(TE)-.95 E F0 2.047(to the v)4.547 F 2.047
X(alue of $\(LOCA)-.25 F(TE_T)-1.11 E 2.047(ARGET\) for each of)-.93 F F1
X(Object)144 660 Q F0 1.1 -.55('s t)D(ar).55 E(gets.)-.18 E(LN \(def)108 676.8 Q
X(ault)-.1 E F2(ln)2.5 E F0(\))A(The hard link command for)144 693.6 Q F2(Har)
X2.5 E(dLink)-.37 E F0(.)A(MANDIR \(def)108 710.4 Q(ault)-.1 E F2
X(/usr/local/man)2.5 E F0(\))A(10 March 1995)275.45 768 Q(4)535 768 Q EP
X%%Page: 5 5
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF -.6(JA)72 48 S(MB).6 E 352.96(ASE\(5\) J)-.35 F(AMB)-.6
XE(ASE\(5\))-.35 E(Not used.)144 84 Q(Set for con)5 E -.15(ve)-.4 G(nience.).15
XE(MKDIR \(def)108 100.8 Q(ault)-.1 E/F1 10/Times-Italic@0 SF(mkdir)2.5 E F0(\))
XA(The program to create directories for the)144 117.6 Q F1(MkDir)2.5 E F0
X(rule.)2.5 E(MODE \(def)108 134.4 Q(ault v)-.1 E(aries\))-.25 E 3.093
X(The \214le mode for \214les installed with)144 151.2 R F1(Install)5.592 E F0
X8.092(.I)C 5.592(ss)353.18 151.2 S 3.092(et to $\(EXEMODE\), $\(FILEMODE\), or)
X366.552 151.2 R($\(SHELLMODE\) depending which rule in)144 163.2 Q -.2(vo)-.4 G
X-.1(ke).2 G(d).1 E F1(Install)2.5 E F0(.)A(MV \(def)108 180 Q(ault)-.1 E F1
X(mv -f)2.5 E F0(\))A(The \214le rename command and options.)144 196.8 Q
X(OPTIM \(def)108 213.6 Q(ault)-.1 E F1(-O)2.5 E F0(\))A
X(More \215ags handed to the C compiler)144 230.4 Q(.)-.55 E -.35(OW)108 247.2 S
X(NER \(no def).35 E(ault\))-.1 E(The o)144 264 Q(wner of installed \214led.)
X-.25 E(Used by)5 E F1(Install)2.5 E F0(.)A(RANLIB \(def)108 280.8 Q(ault)-.1 E
XF1 -.15(ra)2.5 G(nlib).15 E F0 2.5<2983>C(If set, the command string to be in)
X144 297.6 Q -.2(vo)-.4 G -.1(ke).2 G 2.5(do).1 G 2.5(ne)312.45 297.6 S
X(ach library after archi)324.39 297.6 Q(ving.)-.25 E(RELOCA)108 314.4 Q
X(TE \(def)-1.11 E(ault unset\))-.1 E .987(If set, tells the)144 331.2 R F1(Cc)
X3.487 E F0 .987(rule to mo)3.487 F 1.287 -.15(ve t)-.15 H .987
X(he output object \214le to its tar).15 F .988
X(get directory because the cc com-)-.18 F(mand has a brok)144 343.2 Q
X(en -o option.)-.1 E(RM \(def)108 360 Q(ault)-.1 E F1(rm -f)2.5 E F0(\))A
X(The command and options to remo)144 376.8 Q .3 -.15(ve a \214)-.15 H(le.).15 E
X(SEARCH_SOURCE \(no def)108 393.6 Q(ault\) \203)-.1 E 1.23
X(The directory to \214nd sources listed with)144 410.4 R/F2 10/Times-Bold@0 SF
X(Main)3.729 E F0(,)A F2(Library)3.729 E F0(,)A F2(Object)3.729 E F0(,)A F2
X(Bulk)3.729 E F0(,)A F2(File)3.729 E F0(,)A F2(Shell)3.729 E F0(,)A F2
X(InstallBin)3.729 E F0(,)A F2(InstallLib)144 422.4 Q F0 2.519(,a)C(nd)195.699
X422.4 Q F2(InstallMan)2.519 E F0 2.519(rules. This)2.519 F -.1(wo)2.519 G .019
X(rks by setting the).1 F F2(jam)2.519 E F0 .019(-special v)B(ariable)-.25 E F2
X(SEARCH)2.52 E F0 .02(to the)2.52 F -.25(va)144 434.4 S
X(lue of $\(SEARCH_SOURCE\) for each of the rules' sources.).25 E
X(SHELLHEADER \(def)108 451.2 Q(ault)-.1 E F1(#!/bin/sh)2.5 E F0(\))A 2.5(As)144
X468 S(tring inserted to the \214rst line of e)157.61 468 Q -.15(ve)-.25 G
X(ry \214le created by the).15 E F2(Shell)2.5 E F0(rule.)2.5 E(SHELLMODE \(def)
X108 484.8 Q(ault)-.1 E F1(755)2.5 E F0 2.5<2983>C
X(Permissions for \214les installed by)144 501.6 Q F2(Shell)2.5 E F0(.)A
X(SLASH \(def)108 518.4 Q(ault)-.1 E F1(/)2.5 E F0 2.5<2983>C
X(The directory separator)144 535.2 Q 5(.U)-.55 G(sed by)251.47 535.2 Q F1
X(SubDir)2.5 E F0(and)2.5 E F1(SubInclude)2.5 E F0(to b)2.5 E
X(uild up a directory path.)-.2 E(SOURCE_GRIST \(no def)108 552 Q(ault\) \203)
X-.1 E 1.148(Set by the)144 568.8 R F1(SubDir)3.647 E F0 1.147(to a v)3.647 F
X1.147(alue deri)-.25 F -.15(ve)-.25 G 3.647(df).15 G 1.147
X(rom the directory name, and used by)303.617 568.8 R F1(Objects)3.647 E F0
X1.147(and related)3.647 F(rules as 'grist' to perturb \214le names.)144 580.8 Q
X(STDHDRS \(def)108 597.6 Q(ault)-.1 E F1(/usr/include)2.5 E F0 2.5<2983>C
X(Directories where headers can be found without resorting to using the)144
X614.4 Q F1<8d61>2.5 E(g)-.1 E F0(to the C compiler)2.5 E(.)-.55 E
X(SUBDIR \(no def)108 631.2 Q(ault\))-.1 E(Set by)144 648 Q F1(SubDir)2.5 E F0
X(to be the named directory)2.5 E(.)-.65 E(SUFEXE \(def)108 664.8 Q
X(ault ""\) \203)-.1 E(The suf)144 681.6 Q(\214x for e)-.25 E -.15(xe)-.15 G
X(cutable \214les, if none pro).15 E 2.5(vided. Used)-.15 F(by the)2.5 E F1
X(Main)2.5 E F0(rule.)2.5 E(SUFLIB \(def)108 698.4 Q(ault)-.1 E F1(.a)2.5 E F0
X2.5<2983>C(The suf)144 715.2 Q(\214x for libraries.)-.25 E(Used by the)5 E F1
X(Libr)2.5 E(ary)-.15 E F0(and related rules.)2.5 E(10 March 1995)275.45 768 Q
X(5)535 768 Q EP
X%%Page: 6 6
X%%BeginPageSetup
XBP
X%%EndPageSetup
X/F0 10/Times-Roman@0 SF -.6(JA)72 48 S(MB).6 E 352.96(ASE\(5\) J)-.35 F(AMB)-.6
XE(ASE\(5\))-.35 E(SUFOBJ \(def)108 84 Q(ault)-.1 E/F1 10/Times-Italic@0 SF(.o)
X2.5 E F0 2.5<2983>C(The suf)144 100.8 Q(\214x for object \214les.)-.25 E
X(Used by the)5 E F1(Objects)2.5 E F0(and related rules.)2.5 E(UNDEFFLA)108
X117.6 Q 2.5(G\()-.4 G(def)172.87 117.6 Q(ault)-.1 E F1(-u _)2.5 E F0(\))A
X(The \215ag pre\214x)144 134.4 Q(ed to each symbol for the)-.15 E/F2 10
X/Times-Bold@0 SF(Unde\214nes)2.5 E F0(rule.)2.5 E -.5 -1.2(YA C)108 151.2 T 2.5
X(C\()1.2 G(def)140.01 151.2 Q(ault)-.1 E F1(yacc -d)2.5 E F0(\))A(The)144 168 Q
XF2(yacc)2.5 E F0(\(1\) command and \215ags.)A/F3 9/Times-Bold@0 SF(SEE ALSO)72
X196.8 Q F2(jam)108 208.8 Q F0(\(1\),)A F2 -.15(Ja)2.5 G(m\214le).15 E F0(\(5\))
XA(10 March 1995)275.45 768 Q(6)535 768 Q EP
X%%Trailer
Xend
X%%EOF
END_OF_FILE
if test 28776 -ne `wc -c <'Jambase.ps'`; then
echo shar: \"'Jambase.ps'\" unpacked with wrong size!
fi
# end of 'Jambase.ps'
fi
if test -f 'Jamfile.5' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Jamfile.5'\"
else
echo shar: Extracting \"'Jamfile.5'\" \(40692 characters\)
sed "s/^X//" >'Jamfile.5' <<'END_OF_FILE'
X.TH JAMFILE 5 "10 March 1995"
X.de BB
X.RS
X.PP
X.ft CW
X.na
X.nf
X..
X.de BE
X.RE
X.ft R
X.fi
X.ad
X..
X.de XB
XFor example:
X.BB
X..
X.de XE
X.BE
X..
X.SH NAME
X\fBJamfile\fR \- per-directory \fBjam\fR(1) instructions
X.SH DESCRIPTION
X.PP
XThis manual page gives instructions and examples for writing a
X\fBJamfile\fR, a file that tells the build tool \fBjam\fR what to
Xbuild. It consists of invocations of rules defined by the \fBjam\fR
Xboilerplate, \fBJambase\fR. \fBJambase\fR itself defines rules that
Xprovide roughly \fBmake\fR(1)-like functionality.
X.PP
XThe first section is a one-page overview of \fBjam\fR, to introduce the
Xsyntax. The remaining sections are examples and discussion.
X.PP
XThis description goes with \fBJam\fR Release 2.0.
X.SH JAM OVERVIEW
X.SS Invocation
X.PP
XThe examples in the following sections are parts of a \fBJamfile\fR.
XOnce you have written a \fBJamfile\fR, you can invoke \fBjam\fR to
Xbuild things. The simplest syntax is:
X.BB
Xjam [-n]
X.BE
X.PP
XThe \fB-n\fR tells \fBjam\fR to do a verbose dry-run.
X.SS Rules
X.PP
XThe \fBjam\fR language consists mostly of rule invocations. A rule is
Xinvoked with \fItargets\fR and \fIsources\fR. That is,
X.BB
XRule targets : sources ;
X.BE
X.PP
XEach rule definition has potentially two parts: the rule procedure
Xand the rule's actions. The procedure is just more \fBjam\fR
Xstatements to interpret when the rule is invoked. The actions are
Xthe shell commands to execute when the targets are to be updated.
X.PP
XThe \fBJambase\fR consists mostly of rule definitions, and your
X\fBJamfile\fR will contain mostly rule invocations.
X.SS Variables
X.PP
X\fBJam\fR has two types of variables: global ones and target-specific
Xones. The latter take effect only when the named target is being
Xbound, scanned for header files, or updated. Target-specific variables
Xenable generic actions (like the \fICc\fR rule's call to the C
Xcompiler) to be used for different targets. Only the target-specific
Xvariables (HDRS, CCFLAGS, etc.) vary.
X.PP
XThe \fBJambase\fR rules use variables in three ways:
X.IP "Procedure Input"
XIf a variable is procedure input, it must be set before invoking the
Xrule. This is sometimes used to pass additional parameters to the rule
X(beyond the targets and sources), and is sometimes used for conditional
Xdefinitions (e.g., if the RANLIB variable is set, invoke the
X\fIRanlib\fR rule). When we describe the variables in each section, we
Xmark procedure input variables with a *.
X.IP "Procedure Output"
XA rule procedure may set variables for later use. Except where noted,
Xall rules set these variables specific to the rule's targets.
XSometimes the variable are later used during the binding and header
Xfile scanning phase, and sometimes they are used by the actions.
X.IP "Actions Input"
XThe shell commands to update a target often contain variable references.
XThese variables may be set globally or target-specific. The latter take
Xprecedence.
X.PP
XOften, a variable will be used in more than just way: a variable set by
Xa rule procedure may quite likely be used by the actions. In some
Xcases, a variable that is input to a rule procedure may be output
X(target-specific) as well. This has the effect of freezing the
Xvariable's value for the target.
X.SS Whitespace Note
X.PP
X\fBJam\fR requires whitespace (blanks, tabs, or newlines) to surround
Xall tokens, including the colon (:) and semicolon (;)
Xtokens. This is because \fBjam\fR runs on many platforms and no
Xcharacters, save whitespace, are uncommon in the file names on all of
Xthose platforms.
X.SH BUILDING EXECUTABLES AND LIBRARIES
X.PP
XThe following rules compile source files and build executables and
Xlibraries.
X.SS Main Rule
X.PP
XThe \fIMain\fR rule compiles source files and links the resulting
Xobjects into an executable.
X.XB
XMain myprog : main.c util.c ;
X.XE
X.PP
XThis compiles main.c and util.c and links main.o and util.o into myprog.
XAs with all rules that compile source files, \fIMain\fR handles header file
Xdependencies automatically.
X.SS Library Rule
X.PP
XThe \fILibrary\fR rule compiles source files, archives the
Xresulting object files into a library, and then deletes the object
Xfiles.
X.XB
XLibrary libstring.a : strcmp.c strcpy.c strlen.c ;
XLibrary libtree.a : treemake.c treetrav.c ;
X.XE
X.PP
XThis compiles five source files, archives three of the object files
Xinto libstring.a and the other two into libtree.a. Once the
Xobjects are safely in the libraries, the objects are deleted.
X.SS LinkLibraries Rule
X.PP
XTo tell \fBjam\fR to link executables against libraries, you use the
X\fILinkLibraries\fR rule.
X.XB
XMain myprog : main.c util.c ;
XLinkLibraries myprog : libstring.a libtree.a ;
X
XLibrary libstring.a : strcmp.c strcpy.c strlen.c ;
XLibrary libtree.a : treemake.c treetrav.c ;
X.XE
X.PP
XThe \fILinkLibraries\fR rule does two things: it makes the libraries
Xdependencies of the executable, so that they get built first; and it
Xmakes the libraries show up on the command line that links the
Xexecutable. The ordering of the lines above is not important, because
X\fBjam\fR builds targets in the order that they are needed.
X.PP
XYou can put multiple libraries on a single invocation of the
X\fILinkLibraries\fR rule, or you can provide them in multiple
Xinvocations. In both cases, the libraries appear on the link command
Xline in the order in which they were encountered. You can also provide
Xmultiple executables to the \fILinkLibraries\fR rule, if they
Xneed the same libraries.
X.SS Variables
X.PP
XThe following variables control the linking of executables and the
Xarchiving of libraries.
X.BB
X$(AR) archive command (ar ru)
X$(EXEMODE) * default value for MODE (711)
X$(LINK) linker command (cc)
X$(LINKFLAGS) linker flags ()
X$(LINKLIBS) additional libraries that aren't dependencies ()
X$(MODE) permission on target
X$(RANLIB) name of ranlib program, if any (ranlib)
X.BE
X.PP
X\fIMain\fR sets a target-specific MODE to the current value of $(EXEMODE).
X.PP
XThe difference between and the arguments to \fILinkLibraries\fR
Xand the value of $(LINKLIBS) is that the former are expected to be
Xreal, buildable libraries, while the latter are just handed without
Xinspection to the $(LINK) command. The ordering on the link
Xcommand line is first \fILinkLibraries\fR and then $(LINKLIBS).
X.XB
XMain xprog : xprog.c ;
XLinkLibraries xprog : libxutil.a ;
XLINKFLAGS on xprog = -Bstatic ;
XLINKLIBS on xprog = -lXext -lX11 ;
X
XLibrary libxutil.a : xtop.c xbottom.c xutil.c ;
X.XE
X.PP
XThis example uses the \fBjam\fR syntax "variable \fIon\fR target" to
Xset a target-specific variable. In this way, only xprog will be linked
Xwith these special $(LINKFLAGS) and $(LINKLIBS), even if other
Xexecutables were going to be built by the same \fBJamfile\fR. The
Xactual link command line would look like this:
X.BB
Xcc -Bstatic -o xprog xprog.o libuxtil.a -lXext -lX11
X.BE
X.PP
XNote that the default link command is cc.
X.SH COMPILING
X.PP
XCompiling of source files occurs normally as a byproduct of the
X\fIMain\fR or \fILibrary\fR rules. If you want to control the
Xcompiling process with finer granularity, you can use the rules
Xdescribed here. \fIMain\fR and \fILibrary\fR use these rules.
X.SS Objects Rule
X.PP
XThe \fIMain\fR or \fILibrary\fR rules call the \fIObjects\fR rule on each of
Xtheir source files. You can also call \fIObjects\fR directly.
X.XB
XObjects a.c b.c c.c ;
X.XE
X.PP
XThis compiles a.c into a.o, b.c into b.o, etc.
X.SS Object Rule
X.PP
X\fIObjects\fR gets its work done by calling the \fIObject\fR rule on
Xeach of the source files, making the assumption that the object name
Xitself will be the source file name, with the suffix replaced
Xappropriately. To compile a single source file directly, use the
X\fIObject\fR rule.
X.XB
XObject foo.o : foo.c ;
X.XE
X.PP
XThe \fIObject\fR rule doesn't require that the object name bear any
Xrelationship to the source. It is thus possible to compile the same
Xfile into different objects.
X.XB
XObject a.o : foo.c ;
XObject b.o : foo.c ;
XObject c.o : foo.c ;
X.XE
X.PP
XThis compiles foo.c (three times) into a.o, b.o, and c.o. Later examples
Xshow how this is useful.
X.PP
XThe \fIObject\fR rule looks at the suffix of the source file and calls
Xthe appropriate rules to do the actual compiling. This invariably
Xinvolves a call to the \fICc\fR to turn the .c into a .o, but may also
Xrequire a call to other rules to turn the source file into a .c.
XThus the \fIObject\fR rule is responsible for the generation of an
Xobject file from any type of source.
X.XB
XObject grammar.o : grammar.y ;
XObject scanner.o : scanner.l ;
XObject fastf.o : fastf.f ;
XObject util.o : util.c ;
X.XE
X.PP
XIn addition to calling the compiling rule, \fIObject\fR sets up a bunch
Xof variables specific to the source and target files. These are discussed
Xbelow.
X.SS Cc, C++, Yacc, Lex, Fortran, As, etc. Rules
X.PP
XThe \fIObject\fR calls compiling rules specific to the suffix of the
Xsource file. Because the extra work done by the \fIObject\fR rule, it
Xis not always useful to call the compiling rules directly. But the
Xadventurous user might attempt it.
X.XB
XYacc grammar.c : grammar.y ;
XLex scan.c : scan.l ;
XCc prog.o : prog.c ;
X.XE
X.PP
XThese examples individually run \fByacc\fR(1), \fBlex\fR(1), and the
XC compiler on their sources.
X.SS UserObject Rule
XAny files with suffixes not understood by the \fIObject\fR rule are
Xpassed to the \fIUserObject\fR rule. The default definition of
X\fIUserObject\fR simply emits a warning that the suffix is not understood.
XThis rule definition is intended to be replaced with one that
Xrecognizes the suffix.
X.XB
Xrule UserObject
X{
X switch $(>)
X {
X case *.s : As $(<) : $(>) ;
X case * : ECHO "unknown suffix on" $(>) ;
X }
X}
X
Xrule As
X{
X DEPENDS $(<) : $(>) ;
X}
X
Xactions As
X{
X as -o $(<) $(>)
X}
X
XLibrary libsys.a : alloca.s memcpy.s ;
X.XE
X.PP
XIt should be mentioned that this example is contrived, in that the \fB.s\fR
Xsuffix is already handled by \fIObject\fR.
X.SS LibraryFromObjects Rule
X.PP
XSometimes the \fILibrary\fR rule's straightforward compiling of source
Xinto object modules to be archived isn't flexible enough. The
X\fILibraryFromObjects\fR rule does the archiving (and deleting) job
Xof the \fILibrary\fR rule, but not the compiling. The user can make
Xuse of the \fIObjects\fR or \fIObject\fR rule for that.
X.XB
XLibraryFromObjects libfoo.a : max.o min.o ;
XObject max.o : maxmin.c ;
XObject min.o : maxmin.c ;
XObjectCcFlags max.o : -DUSEMAX ;
XObjectCcFlags min.o : -DUSEMIN ;
X.XE
X.PP
XThis compiles the same source file into two different objects, with
Xdifferent compile flags, and archives them. The
X\fIObjectCcFlags\fR rule is described shortly.
X.SS MainFromObjects Rule
X.PP
XSimilar to \fILibraryFromObjects\fR, \fIMainFromObjects\fR does the linking
Xpart of the \fIMain\fR rule, but not the compiling.
X.XB
XMainFromObjects w : w.o ;
XMainFromObjects uptime : uptime.o ;
XObject w.o : uptime.c ;
XObject uptime.o : uptime.c ;
XObjectCcFlags w.c : -DW_CODE ;
X.XE
X.PP
XThis compiles two different programs, w and uptime, from the same
Xsource file with different C compiler flags. Another use of
X\fIMainFromObjects\fR is when there are no objects at all, and
Xeverything is to be loaded from libraries.
X.XB
XMainFromObjects testprog ;
XLinkLibraries testprog : libprog.a ;
XLibrary libprog.a : main.c util.c ;
X.XE
XThis generates a link command that looks like this:
X.BB
Xcc -o testprog libprog.a
X.BE
X.PP
XLinking purely from libraries is something that doesn't work everywhere:
Xit depends on the symbol "main" being undefined when the linker encounters
Xthe library that contains the definition of "main".
X.SS Variables
X.PP
XThe following variables control the compiling of source files.
X.BB
X$(C++) The C++ Compiler (gcc)
X$(C++FLAGS) * C++ compiler flags()
X$(CC) The C Compiler (cc)
X$(CCFLAGS) * C compiler flags()
X$(HDRS) * non-standard header directories ()
X$(LEX) The Lex program (lex)
X$(OPTIM) optimization flag, if desired (-O)
X$(STDHDRS) * standard header directories (/usr/include)
X$(SUBDIRC++FLAGS) * Per-directory C++FLAGS
X$(SUBDIRCCFLAGS) * Per-directory CCFLAGS
X$(SUBDIRHDRS) * Per-directory HDRS
X$(YACC) The Yacc program (yacc -d)
X.BE
X.PP
XThe \fICc\fR rule sets a target-specific $(CCFLAGS) to the current
Xvalue of $(CCFLAGS) and $(SUBDIRCCFLAGS). Similarly for the \fIC++\fR
Xrule. The \fIObject\fR rule sets a target-specific $(HDRS) to the
Xcurrent value of $(HDRS) and $(SUBDDIRHDRS).
X.PP
X$(CC), $(C++), $(CCFLAGS), $(C++FLAGS), $(OPTIM), and $(HDRS) all affect
Xthe compiling of C and C++ files. $(OPTIM) is separate from $(CCFLAGS)
Xand $(C++FLAGS) so they can be set independently.
X.PP
X$(HDRS) lists the directories to search for header files, and it is
Xused in two ways: first, it is passed to the C compiler (with the flag
X\fB-I\fR prepended); second, it is used by \fIHdrRule\fR to locate the
Xheader files whose names were found when scanning source files.
X$(STDHDRS) lists the header directories that the C compiler already
Xknows about. It does not need passing to the C compiler, but is used
Xby \fIHdrRule\fR.
X.PP
XNote that these variables, if set as target-specific variables, must be
Xset on the target, not the source file. The target file in this case
Xis the object file to be generated.
X.XB
XLibrary libximage.a : xtiff.c xjpeg.c xgif.c ;
X
XHDRS on xjpeg.o = /usr/local/src/jpeg ;
XCCFLAGS on xtiff.o = -DHAVE_TIFF ;
X.XE
X.PP
XThis can be done more easily with the rules that follow.
X.SS ObjectCcFlags, ObjectC++Flags, ObjectHdrs Rules
X.PP
X$(CCFLAGS), $(C++FLAGS) and $(HDRS) can be manipulated directly, but there are
Xrules that allow these variables to be set by referring to the original
Xsource file name, rather than to the derived object file name.
X\fIObjectCcFlags\fR adds object-specific flags to the $(CCFLAGS) variable,
X\fIObjectC++Flags\fR adds object-specific flags to the $(C++FLAGS) variable,
Xand \fIObjectHdrs\fR add object-specific directories to the $(HDRS)
Xvariable.
X.XB
XMain xviewer : viewer.c ;
XObjectCcFlags viewer.c : -DXVERSION ;
XObjectHdrs viewer.c : /usr/include/X11 ;
X.XE
X.PP
XActually, the file suffix (\fB.c\fR in this case) is ignored: the
Xrules know to refer to the object.
X.SS SubDirCcFlags, SubDirC++Flags, SubDirHdrs Rules
X.PP
XThese rules set the values of $(SUBDIRCCFLAGS), $(SUBDIRC++FLAGS) and
X$(SUBDIRHDRS), which are used by the \fICc\fR, \fIC++\fR, and
X\fIObject\fR rules when setting the target-specific values for
X$(CCFLAGS), $(C++FLAGS) and $(HDRS). The \fISubDir\fR rule clears
Xthese variables out, and thus they provide directory-specific values of
X$(CCFLAGS), $(C++FLAGS) and $(HDRS).
X.XB
XSubDir TOP src util ;
X
XSubDirHdrs $(TOP)/src/hdr ;
XSubDirCcFlags -DUSE_FAST_CODE ;
X.XE
X.SH HEADER FILE PROCESSING
X.PP
XOne of the functions of the \fIObject\fR rule is to scan source files
Xfor (C style) header file inclusions. To do so, it sets the
X\fBjam\fR-special variables $(HDRSCAN) and $(HDRRULE) as
Xtarget-specific variables for the source file. The presence of these
Xvariables triggers a special mechanism in \fBjam\fR for scanning a file
Xfor header file inclusions and invoking a rule with the results of the
Xscan. The $(HDRSCAN) variable is set to an \fBegrep\fR(1) pattern that
Xmatches "#include" statements in C source files, and the $(HDRRULE)
Xvariable is set to the name of the rule that gets invoked as such:
X.BB
X$(HDRRULE) source-file : included-files ;
X.BE
X.PP
XThis rule is supposed to set up the dependencies between the source
Xfile and the included files. The \fIObject\fR rule uses
X\fIHdrRule\fR to do the job. \fIHdrRule\fR itself expects another
Xvariable, $(HDRSEARCH), to be set to the list of directories where the
Xincluded files can be found. \fIObject\fR does this as well, setting
X$(HDRSEARCH) to $(HDRS) and $(STDHDRS).
X.PP
XThe header file scanning occurs during the "file binding" phase of
X\fBjam\fR, which means that the target-specific variables (for the
Xsource file) are in effect. To accomodate nested includes, one of the
X\fIHdrRule\fR's jobs is to pass the target-specific values of
X$(HDRRULE), $(HDRSCAN), and $(HDRSEARCH) onto the included files, so
Xthat they will be scanned as well.
X.SS HdrRule Rule
X.PP
X\fIHdrRule\fR can be invoked directly, but it is most usable as the
Xboilerplate in a user-defined $(HDRRULE).
X.XB
XMain mkhdr : mkhdr.c ;
XMain ugly : ugly.c ;
X
XHDRRULE on ugly.c = BuiltHeaders ;
X
Xrule BuiltHeaders
X{
X DEPENDS $(>) : mkhdr ;
X HdrRule $(<) : $(>) ;
X}
X.XE
X.PP
XThis example just says that the files included by "ugly.c" are generated
Xby the program "mkhdr", which can be built from "mkhdr.c". By calling
X\fIHdrRule\fR at the end of \fIBuiltHeaders\fR, all the gadgetry of
X\fIHdrRule\fR takes effect and it doesn't need to be duplicated.
X.SS Variables
X.PP
XThe complete list of variables used by the \fIHdrRule\fR coterie are:
X.BB
X$(HDRPATTERN) * scan pattern for $(HDRSCAN) (ugly egrep expression)
X$(HDRRULE) scan rule, when set activates scanning (HdrRule)
X$(HDRS) * non-standard directories for headers ()
X$(HDRSCAN) scan pattern when actually scanning ($(HDRPATTERN))
X$(HDRSEARCH) search list for HdrRule ($(HDRS) $(STDHDRS))
X$(STDHDRS) * standard directories for headers (/usr/include)
X.BE
X.PP
XThe \fIObject\fR rule sets HDRRULE and HDRSCAN specifically for the
Xsource files to be scanned, rather than globally. If they were set
Xglobally, \fBjam\fR would attempt to scan all files, even library
Xarchives and executables, for header file inclusions. That would
Xbe slow and probably not yield desirable results.
X.SH COPYING FILES
X.SS File Rule
XThe \fIFile\fR rule copies one file to another.
XThe target name needn't bear any relationship to the source name.
X.XB
XFile $(DESTDIR)/foo : bar ;
X.XE
X.SS Bulk Rule
XThe \fIBulk\fR rule is a shorthand for many invocations of the \fIFile\fR
Xrule when all files are going to the same directory.
X.XB
XBulk /usr/local/lib/grob : grobvals.txt grobvars.txt ;
X.XE
X.SS HardLink Rule
XThe \fIHardLink\fR rule makes a hard link (using \fBln\fR(1)) from the
Xsource to the target, if there isn't one already.
X.XB
XHardLink config.h : config.h.dist ;
X.XE
X.SS Shell Rule
XThe \fIShell\fR rule is like the \fIFile\fR rule, except that it makes
Xsure the first line of the target is "#!/bin/sh" and sets the permission
Xto make the file executable.
X.XB
XShell /usr/local/bin/add : add.sh ;
X.XE
X.SS Variables
XThe following variables are used when copying files:
X.BB
X$(FILEMODE) * default value for MODE for files (644)
X$(SHELLHEADER) first line of shell scripts (#!/bin/sh)
X$(SHELLMODE) * default value for MODE for shell scripts (755)
X$(MODE) permission on target
X.BE
X.PP
X\fIFile\fR and \fRShell\fR sets a target-specific MODE to the current value
Xof $(FILEMODE) or $(SHELLMODE), respectively.
X.XB
XShell /usr/local/bin/add : add.awk ;
XSHELLHEADER on /usr/local/bin/add = "#!/bin/awk -f" ;
X.XE
X.PP
XThis installs an \fBawk\fR(1) script.
X.SH INSTALLING FILES
X.SS InstallBin Rule
X.PP
X\fIInstallBin\fR calls \fBinstall\fR(1) to install executables in
Xthe target directory. $(BINDIR) is set to /usr/local/bin for convenience.
X.XB
XMain add : add.c ;
XMain sub : sub.c ;
XInstallBin $(BINDIR) : add sub ;
X.XE
X.SS InstallLib Rule
X\fIInstallLib\fR calls \fBinstall\fR(1) to install files in the target
Xdirectory. $(LIBDIR) is set to /usr/local/lib for convenience.
X.XB
XInstallLib $(LIBDIR) : bighelp.txt ;
X.XE
X.SS InstallMan Rule
X.PP
X\fIInstallMan\fR calls \fBinstall\fR(1) to install manual pages in
Xthe appropriate subdirectories of the target directory. $(MANDIR)
Xis set to /usr/local/man for convenience.
X.XB
XInstallMan $(MANDIR) : add.1 sub.1 bigfile.8 ;
X.XE
X.SS InstallShell Rule
X.PP
X\fIInstallShell\fR calls \fBinstall\fR(1) to install shell scripts in
Xthe target directory.
X.XB
XShell bugs : bugs.sh ;
XInstallShell $(BINDIR) : bugs ;
X.XE
X.PP
XThe difference between \fIShell\fR and \fIInstallShell\fR is not much: they
Xboth copy the source to the target. The former also makes
Xsure the script begins with the magic string "#!/bin/sh"; the latter uses
X\fBinstall\fR(1) for the copy.
X.SS MkDir Rule
X.PP
XAll the \fIInstall\fR rules invoke the \fIMkDir\fR rule to create the
Xdirectory for the target file. \fIMkDir\fR recursively invokes itself
Xon its parent directory, to make sure the whole path gets created.
X\fIMkDir\fR marks directories with the built-in rule \fINOUPDATE\fR,
Xwhich tells \fBjam\fR not to update a target once it exists. In that
Xway, the contents of the install directory can depend on the existence
Xof the install directory itself, and thus the directory will be made
Xbefore its contents are installed. You can call \fIMkDir\fR directly.
X.XB
XFile /usr/local/bin/junky : junky ;
XDEPENDS /usr/local/bin/junky : /usr/local/bin ;
XMkDir /usr/local/bin ;
X.XE
X.PP
XThis says that /usr/local/bin must be created before /usr/local/bin/junky
Xcan be built. Needless to say, \fBjam\fR can't do much if you don't have
Xpermissions to create directories along the path.
X.SS Variables
X.PP
XThe following variables control the installation rules:
X.BB
X$(BINDIR) InstallBin directory (/usr/local/bin)
X$(LIBDIR) InstallLib directory (/usr/local/lib)
X$(MANDIR) InstallMan directory (/usr/local/man)
X$(INSTALL) The install program; uses cp if not set (install)
X$(FILEMODE) * default MODE for InstallLib, InstallMan (644)
X$(EXEMODE) * default MODE for InstallBin (711)
X$(SHELLMODE) * default MODE for InstallShell (755)
X$(MODE) permission on target
X$(MKDIR) Program for creating a directory (mkdir)
X.BE
X.PP
XThe \fIInstall\fR rules set a target-specific MODE to the current value
Xof $(FILEMODE), $(EXEMODE), or $(SHELLMODE), depending on which \fIInstall\fR
Xrule was invoked.
X.PP
XThe directory variables are just defined for convenience: they must
Xbe passed as the target to the appropriate \fIInstall\fR rule.
XThe $(INSTALL) and mode variables must be set (globally) before
Xcalling the \fIInstall\fR rules in order to take effect.
X.SH HANDLING DIRECTORY TREES
X.PP
X\fBJam\fR can build large projects spread across many directories in
Xone pass, tracking the relationships among all files. It doesn't
Xrequire the user to change the invocations of normal rules like
X\fIMain\fR, \fILibrary\fR, etc. to use non-local pathnames: these
Xrules continue to refer to files in the directory of the
X\fBJamfile\fR. This section describes the rules and
Xvariables which support this.
X.PP
XTo build a whole directory tree at a time, the user must do three
Xthings:
X.IP 1.
XSet an environment variable pointing to the root directory of the
Xsource tree. The root variable's name is left up to the user, but in these
Xexamples we use TOP.
X.IP 2.
XPlace at the root of the tree a file named \fBJamrules\fR. (This file
Xcan alternately be named by the variable $(xxxRULES), where xxx is the
Xname of the root variable). This file could be empty, but in practice
Xit contains user-provided rules and variable definitions that are
Xshared throughout the tree. Examples of such definitions are library
Xnames, header directories, install directories, compiler flags, etc.
XThis file is good candidate for automatic customizing with
X\fBautoconf\fR(GNU).
X.IP 3.
XPreface the \fBJamfile\fR in each directory with an invocation of
Xthe \fISubDir\fR rule.
X.SS SubDir Rule
X.PP
XThe \fISubDir\fR rule does two things:
X.IP 1.
XIt reads in the \fBJamrules\fR at the root of the tree, if that file
Xhasn't already been read in by a previous invocation of \fISubDir\fR.
X.IP 2.
XIt sets a few variables that tell \fBjam\fR the name of the
X\fBJamfile\fR's directory, so that \fBjam\fR may find source files that
Xare named local to the \fBJamfile\fR's directory.
X.PP
XThe \fISubDir\fR rule takes as its first argument the root variable's
Xname and takes as subsequent arguments the directory names leading from
Xthe root to the directory of the current \fBJamfile\fR. Note that the
Xname of the subdirectory is given as individual elements: the
X\fISubDir\fR rule does not use system-specific directory name syntax.
X.PP
XThe \fISubDir\fR rule must be invoked before any rules that refer to
Xthe contents of the directory - it is best to put it at the top of each
X\fBJamfile\fR.
X.XB
X# Mondo src/util directory.
X
XSubDir TOP src util ;
X
XMain $(TOP)/bin/testutil : test.c ;
X
XLinkLibraries $(TOP)/bin/testutil : $(TOP)/lib/libutil.a ;
X
XLibrary $(TOP)/lib/libutil.a : gadgets.c gizmos.c widgets.c ;
X.XE
X.PP
XThis compiles four files in $(TOP)/src/util, archives three of the
Xobjects into libutil.a, and links the whole thing into $(TOP)/bin/testutil.
X.SS SubInclude Rule
X.PP
XThe \fISubInclude\fR rule sources the \fBJamfile\fR from the named
Xsubdirectory. Its arguments are in the same format as \fISubDir\fR's, and
Xits only reason for being is to allow including a subdirectory
X\fBJamfile\fR without having to use system-specific directory name
Xsyntax.
X.PP
XThe recommended practice is only to include one level of subdirectories
Xat a time, and let the \fBJamfile\fR in each subdirectory include its
Xown subdirectories. This allows a user to sit in any arbitrary directory
Xof the source tree and build that subtree.
X.XB
X# Top level Jamfile for mondo project.
X#
X# $(TOP) points to root of mondo tree (set in environment).
X
XSubInclude TOP src ;
XSubInclude TOP man ;
XSubInclude TOP misc ;
XSubInclude TOP util ;
X.XE
X.PP
XIf a directory has both subdirectories of its own as well as files that
Xneed building, the \fISubIncludes\fR should be either before the
X\fISubDir\fR rule or be at the end of the \fBJamfile\fR - \fInot\fR
Xbetween the \fISubDir\fR and other rule invocations.
X.XB
X# Mondo src code.
X
XSubDir TOP src ;
X
XMain mondo : mondo.c ;
XLinkLibraries mondo : $(TOP)/lib/libmisc.a $(TOP)/lib/libutil.a ;
X
XSubInclude TOP src misc ;
XSubInclude TOP src util ;
X.XE
X.SS Variables
XThe following variables are used when \fBjam\fR spans multiple directories:
X.BB
X$(LOCATE_TARGET) Directory to place targets.
X$(SEARCH_SOURCE) Directory to find sources.
X$(SOURCE_GRIST) Something to perturb source file names.
X.BE
X.PP
X\fISubDir\fR sets $(LOCATE_TARGET) and $(SEARCH_SOURCE) to be the
Xdirectory given to \fISubDir\fR. These variables are used extensively
Xby rules in \fBJambase\fR: most rules that generate targets (like
X\fIMain\fR, \fIObject\fR, etc.) set $(LOCATE) to be $(LOCATE_TARGET)
Xfor the targets they generate, and rules that use sources (most all of
Xthem) set $(SEARCH) to be $(SEARCH_SOURCE) for the sources they use.
X.PP
X$(LOCATE) and $(SEARCH) are better explained in \fBjam\fR(1), but in
Xbrief they tell \fBjam\fR where to create new targets and where to find
Xexisting ones, respectively.
X.PP
X\fISubDir\fR sets $(SOURCE_GRIST) to be a value derived from the
Xdirectory name. $(SOURCE_GRIST) is used by the rules that take
Xsource files to perturb file names in different directories that
Xwould otherwise be the same.
X.PP
XIt should be noted that the user can set these variables independently
Xof \fISubDir\fR, or after it. The most profitable example is setting
X$(LOCATE_TARGET) to be a directory outside the source tree: in this
Xcase, \fBjam\fR can build into a target directory (tree) without ever
Xmodifying the source tree.
X.SS VMS Notes
X.PP
XOn VMS, the logical name table is not imported as is the environment
Xon UNIX. To use the \fISubDir\fR and related rules, you must
Xset the value of the variable that names the root directory.
X.XB
XTOP = USR_DISK:[JONES.SRC] ;
X
XSubInclude TOP util ;
X.XE
X.PP
XThe variable must have a value that looks like a directory or device.
XIf you choose, you can use a concealed logical.
X.XB
XTOP = TOP: ;
X
XSubInclude TOP util ;
X.XE
X.PP
XThe \fB:\fR at the end of TOP makes the value of $(TOP) look like a
Xdevice name, which \fBjam\fR respects as a directory name and will use
Xwhen trying to access files. TOP must then be defined from DCL:
X.BB
X$ define/job/translation=concealed TOP DK100:[USERS.JONES.SRC.]
X.BE
X.PP
XNote three things: the concealed translation allows the logical to be
Xused as a device name; the device name in the logical (here DK100)
Xcannot itself be concealed logical (VMS rules, man); and the directory
Xcomponent of the definition must end in a period (more VMS rules).
X.SH MISCELLANEOUS RULES
X.SS Clean Rule
X.PP
XThe \fIClean\fR rule has only a simple action: to delete all of its
Xsources. It is normally invoked with generated files as sources, so
Xthat they can be cleaned out. \fIClean\fR must invoked with a target
Xas well, as different sets of files might be cleaned on with different
Xtargets. To actually remove the files to be cleaned, you invoke
X\fBjam\fR with the target name on the command line.
X.XB
XClean zap : junk1 junk2 junk3 ;
X.XE
X.PP
XSaying "\f(CWjam zap\fP" would cause it to delete junk1, junk2, and junk3.
X.PP
XAll rules listed in this manual page that generate targets, except the
X\fIInstall\fR rules, invoke the following \fIClean\fR rule:
X.BB
XClean clean : $(<) ;
X.BE
X.PP
XThe \fIInstall\fR rules invoke the following:
X.BB
XClean uninstall : $(<) ;
X.BE
X.PP
XThus a "\f(CWjam uninstall\fP" removes anything created with the \fIInstall\fR
Xrules, and a "\f(CWjam clean\fP" removes anything created by the other rules
Xlisted in this manual page. It should be noted that \fBjam\fR's cleaning
Xmechanism gets rid of exactly the files it created, not miscellaneous junk
Xleft around by the user.
X.PP
XGiven user-defined targets, the \fIClean\fR rule can selectively
Xremove other generated files.
X.XB
Xrule M4
X{
X # File depends on it's m4 source
X
X DEPENDS $(<) : $(>) ;
X
X Clean m4clean : $(<) ;
X}
X
Xactions M4
X{
X m4 < $(>) > $(<)
X}
X.XE
X.PP
XHere a "\f(CWjam m4clean\fR" would remove all files created by \fBm4\fR.
X.SS RmTemps Rule
X.PP
XSome intermediate files are meant to be temporary. The \fIRmTemps\fR
Xrule marks such files with the \fITEMPORARY\fR rule, and then deletes
Xthem after they are used. To delete them only when they are finished
Xbeing used, \fIRmTemps\fR must be the last rule (with actions) invoked on
Xthe target that uses the temporary files, and the sources to
X\fIRmTempts\fR must be the temporary files themselves.
X.XB
XSpecialUserRuleA foo : bar ;
XSpecialUserRuleB ola : foo ;
XRmTemps ola : foo ;
X.XE
X.PP
XThis says: build "foo" using \fISpecialUserRuleA\fR and "ola"
Xusing \fISpecialUserRuleB\fR. Once that is done, remove "foo".
X.SH SPECIAL TARGETS
X.PP
X\fBJam\fR has only one special target: \fIall\fR, which it tries
Xto build if no targets are on the command line. \fBJambase\fR defines
Xseveral special targets which are dependencies of \fIall\fR:
X.BB
Xall - parent of first, shell, files, lib, exe
Xfirst - first dependency of 'all', for potential initialization
Xshell - parent of all Shell targets
Xfiles - parent of all File targets
Xlib - parent of all Library targets
Xexe - parent of all Main target
Xdirs - parent of all MkDir targets
Xclean - removes all Shell, File, Library, and Main targets
Xuninstall - removes all Install targets
X.BE
X.PP
X\fBJambase\fR marks all of these targets with \fBjam\fR's \fINOTFILE\fR
Xattribute, meaning that they aren't to be found in the filesystem. You
Xcan build selected components by giving \fIshell\fR, \fIfiles\fR,
X\fIlib\fR, \fIexe\fR, or \fIdirs\fR as targets on the command line.
XYou can remove the files that \fBjam\fR built giving \fIclean\fR and
X\fIuninstall\fR as targets. And you can arrange for \fBjam\fR to run
Xinitialization commands by putting actions on the target \fIfirst\fR.
X.XB
Xactions Initialize
X{
X ECHO "This is a test of the jam initialization system."
X}
X
XInitialize first ;
X.XE
X.PP
XThis only gets run if \fBjam\fR is invoked with the \fIall\fR or \fIfirst\fR
Xtargets, or no target at all.
X.SH JAM BUILT-IN RULES AND VARIABLES
X.PP
XThis section discusses \fBjam\fR's built-in rules and variables. They
Xare described in \fBjam\fR(1) more precisely. Built-in rules are
Xuppercase, as opposed to the mixed-case rules defined by
X\fBJambase\fR. These built-in rules, along with the other \fBjam\fR
Xsyntax for manipulating variables, provide the foundation upon which
Xthe \fBJambase\fR is built. A \fBJamfile\fR, or (more likely) a
X\fBJamrules\fR (q.v.), can make use of these built-in rules and
Xvariables as well.
X.SS DEPENDS, INCLUDES Rules
X.PP
XTwo rules build the dependency graph. \fIDEPENDS\fR simply makes
Xits sources dependencies of its targets. \fIINCLUDES\fR makes its
Xsources dependencies of anything of which its targets are
Xdependencies. This reflects the dependencies that arise when one
Xsource file includes another: the object built from the source file
Xdepends both on the original and included source file, but the two
Xsources files don't depend on each other.
X.XB
XDEPENDS foo.o : foo.c ;
XINCLUDES foo.c : foo.h ;
X.XE
X.PP
XBoth "foo.c" and "foo.h" become dependencies of "foo.o" in this example.
X.SS ALWAYS, LEAVES, NOCARE, NOTFILE, NOUPDATE, TEMPORARY Rules
X.PP
XSix rules mark targets so that \fBjam\fR treats them differently
Xduring its target binding and updating phase. Normally, \fBjam\fR
Xupdates a target if it is missing, if its filesystem modification time
Xis older than any of its dependencies (recursively), or if any of its
Xdependencies are being updated. This basic behavior can be changed by
Xinvoking the following rules with the target name as the rule's
Xtarget:
X.PP
XThe \fIALWAYS\fR rule causes its targets to be always updated. This is
Xused for the \fIclean\fR and \fIuninstall\fR targets, as they have no
Xdependencies and would otherwise appear never to need building. It is
Xbest applied to targets that are also \fINOTFILE\fR targets, but it
Xcan also be used to force a real file to be updated as well.
X.PP
XThe \fINOCARE\fR rule causes \fBjam\fR to ignore its targets if they
Xcan't be found and have no updating actions. Normally, \fBjam\fR
Xissues a warning about a target that can't be built and then refuses to
Xbuild anything that depends on that target. The \fIHdrRule\fR uses
X\fINOCARE\fR on the header file names found during header file
Xscanning, to let \fBjam\fR know that the included files may not exist.
XFor example, if a #include is within an #ifdef, the included file may
Xnot actually be around.
X.PP
XThe \fINOTFILE\fR rule marks its targets as being pseudo targets, that
Xis, targets that aren't really files. The actions on such a target are
Xonly executed if the target's dependencies are updated, or if the target
Xis also marked with \fIALWAYS\fR. The \fIall\fR and \fIclean\fR
Xtargets are examples of such targets.
X.PP
XThe \fINOUPDATE\fR rule causes \fBjam\fR to ignore the modification
Xtime of the target. This has two effects: first, once the target has
Xbeen created it will never be updated; second, manually updating target
Xwill not cause other targets to be updated. This rule is applied to
Xdirectories by the \fIMkDir\fR rule, because \fIMkDir\fR only cares
Xthat the target directory exists, not when it has last been updated.
X.PP
XThe \fITEMPORARY\fR rule allows for targets to be deleted after they
Xare generated. If \fBjam\fR sees that a temporary target is missing,
Xit will use the target's parent's time when determining if the target
Xneeds updating. Object files that are also archived in a library are
Xmarked as such, so that they can be deleted after they are archived.
X.PP
XThe \fILEAVES\fR rule makes each of the targets depend only on its
X"leaf" dependencies. This makes it immune to its dependencies being
Xupdated, as the "leaf" dependencies are those without their own
Xdependencies and without updating actions. This allows a target to be
Xupdated only if original source files change.
X.SS ECHO, EXIT Rules
X.PP
XThese two rules help during the \fBJamfile\fR compiling phase.
XThe \fIECHO\fR rule just echoes its targets to the standard output.
XThe \fIEXIT\fR rule does the same and then does a brutal, fatal exit of
X\fBjam\fR.
X.SS SEARCH, LOCATE Variables
X.PP
XThese two variables control the binding of target names to real files:
Xthey indicate what path name is to be prepended to the target name to
Xget to the real file. $(SEARCH) provides a list of directories along
Xwhich \fBjam\fR scans looking for a target. $(LOCATE) overrides
X$(SEARCH), indicating the directory where the target must be.
XNormally, $(SEARCH) is set for existing targets while $(LOCATE) is set
Xfor the targets which \fBjam\fR must build. If neither $(SEARCH) nor
X$(LOCATE) are set, or if the name of the target is a rooted file name
X(i.e. on UNIX beginning with "/"), then the file name is assumed to be
Xthe target name.
X.PP
XBoth $(SEARCH) and $(LOCATE) should be set target-specific and not
Xglobally. If they were set globally, \fBjam\fR would use them for all
Xfile binding - including looking for the \fIJamfile\fR, and this is not
Xlikely to produce sane results. All of the rules defined in
X\fBJambase\fR (and described in this document) set $(SEARCH) and
X$(LOCATE) to sensible values for sources they are looking for and
Xtargets they create, respectively. These values are usually
X$(SEARCH_SOURCE) and $(LOCATE_TARGET), described above in the section
Xdescribing variables use when building whole directory trees. The header
Xfile processing rule \fIHdrRule\fR sets $(SEARCH) for header files
Xto be $(HDRS).
X.PP
XWhen writing your own rules, especially ones not built upon those in
X\fBJambase\fR, you may need to set $(SEARCH) or $(LOCATE) directly.
XMost often you'll set them to the prevailing value of $(SEARCH_SOURCE)
Xor $(LOCATE_TARGET). The best examples are those in \fBJambase\fR.
X.SS HDRSCAN, HDRRULE Variables
X.PP
XThese two variable control header file scanning. The first is an
X\fBegrep\fR(1) pattern, with ()'s surrounding the file name, used to
Xfind file inclusion statements in source files. The second is the
Xname of a rule to invoke with the results of the scan: the scanned
Xfile is the target, the found files are the sources. This is the only
Xplace where \fBjam\fR invokes a rule through a variable setting.
X.PP
XBoth $(HDRSCAN) and $(HDRRULE) must be set for header file scanning to
Xtake place, and they should be set target-specific and not globally.
XIf they were set globally, all files, including executables and libraries,
Xwould be scanned for header file include statements.
X.PP
XThe scanning for header file inclusions is not exact, but it is at
Xleast dynamic. That is, there is no need to run something like
X\fBmakedepend\fR(GNU) to create a static dependency file. Because
X\fBjam\fR uses regular expressions to find include files, it can't
Xknow when an include is within #ifdefs or other conditional logic. To
Xmake up for this, \fIHdrRule\fR applies the \fINOCARE\fR rule to each
Xheader file, just in case it is bogus. Also, regular expressions only
Xwork where the included file name is literally in the source file.
XThey can't handle languages that allow including files using variable
Xnames (as \fBjam\fR's own langauge does).
X.SS JAMSHELL Variable (Unix Only)
X.PP
XWhen \fBjam\fR executes a rule's action block, it forks and
Xexecs a shell, passing the action block as an argument to the shell.
XThe invocation of the shell is controlled by $(JAMSHELL), whose default
Xvalue is:
X.BB
XJAMSHELL = /bin/sh -c % ;
X.BE
X.PP
XThe \fB%\fR is replaced with the text of the action block.
X.PP
XOn UNIX \fBjam\fR can build targets in parallel, as long as the
Xdependencies among files are properly spelled out and actions don't
Xcreate fixed named files in the current directory. (If either of those
Xtwo provisions are violated, \fBjam\fR can trip over itself when
Xbuilding in parallel things which just happen to build OK sequentially.)
XWhen building in parallel, \fBjam\fR simply forks off more than
Xone shell at a time.
X.PP
X\fBJam\fR does not directly support building in parallel across
Xmultiple hosts, since that is heavily dependent on the local
Xenvironment. To build in parallel across multiple hosts, you need to
Xwrite your own shell that provides access to the multiple hosts.
XYou then reset $(JAMSHELL) to reference it.
X.PP
XJust as \fBjam\fR expands a \fB%\fR to be the text of the rule's action
Xblock, it expands a \fB!\fR to be the multi-process slot number. The slot
Xnumber varies between 1 and the number of concurrent jobs permitted by
Xthe \fB-j\fR flag given on the command line. Armed with this, it is
Xpossible to write a multiple host shell.
X.XB
X#!/bin/sh
X
X# This sample JAMSHELL uses the SunOS on(1) command to execute
X# a command string with an identical environment on another host.
X#
X# Set JAMSHELL = jamshell ! %
X#
X# where jamshell is the name of this shell file.
X#
X# This version handles up to -j6; after that they get executed
X# locally.
X
Xcase $1 in
X1|4) on winken sh -c "$2";;
X2|5) on blinken sh -c "$2";;
X3|6) on nod sh -c "$2";;
X*) eval "$2";;
Xesac
X.XE
X.SH SEE ALSO
X\fBjam\fR(1), \fBJambase\fR(5)
X.SH BUGS
XThis document shouldn't be a manual page.
END_OF_FILE
if test 40692 -ne `wc -c <'Jamfile.5'`; then
echo shar: \"'Jamfile.5'\" unpacked with wrong size!
fi
# end of 'Jamfile.5'
fi
if test -f 'variable.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'variable.h'\"
else
echo shar: Extracting \"'variable.h'\" \(551 characters\)
sed "s/^X//" >'variable.h' <<'END_OF_FILE'
X/*
X * Copyright 1993, 1995 Christopher Seiwald.
X *
X * This file is part of Jam - see jam.c for Copyright information.
X */
X
X/*
X * variable.h - handle jam multi-element variables
X *
X * 08/23/94 (seiwald) - Support for '+=' (append to variable)
X */
X
XLIST *var_get();
Xvoid var_defines();
Xvoid var_set();
XLIST *var_swap();
XLIST *var_list();
Xint var_string();
X
X/*
X * Defines for var_set().
X */
X
X# define VAR_SET 0 /* override previous value */
X# define VAR_APPEND 1 /* append to previous value */
X# define VAR_DEFAULT 2 /* set only if no previous value */
X
END_OF_FILE
if test 551 -ne `wc -c <'variable.h'`; then
echo shar: \"'variable.h'\" unpacked with wrong size!
fi
# end of 'variable.h'
fi
echo shar: End of archive 4 \(of 7\).
cp /dev/null ark4isdone
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# Contents: Jambase filesys.h jam.1 jamgram.c make1.c
# Wrapped by kent@ftp on Sat Mar 25 12:04:11 1995
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 5 (of 7)."'
if test -f 'Jambase' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Jambase'\"
else
echo shar: Extracting \"'Jambase'\" \(23751 characters\)
sed "s/^X//" >'Jambase' <<'END_OF_FILE'
X#
X# /+\
X# +\ Copyright 1993, 1995 Christopher Seiwald.
X# \+/
X#
X# This file is part of Jam - see jam.c for Copyright information.
X#
X
X#
X# JAMBASE - jam 2.0 ruleset providing make(1)-like functionality
X#
X# Supports UNIX, NT, and VMS.
X#
X# 12/27/93 (seiwald) - purturb library sources with SOURCE_GRIST
X# 04/18/94 (seiwald) - use 'default =' when setting OS specific vars
X# 04/21/94 (seiwald) - do RmTemps together
X# 05/05/94 (seiwald) - all supported C compilers support -o: relegate
X# RELOCATE as an option; set Ranlib to "" to disable it
X# 06/01/94 (seiwald) - new 'actions existing' to do existing sources
X# 08/25/94 (seiwald) - new ObjectCcFlags rule to append to per-target CCFLAGS
X# 08/29/94 (seiwald) - new ObjectHdrs rule to append to per-target HDRS
X# 09/19/94 (seiwald) - LinkLibraries and Undefs now append
X# - Rule names downshifted.
X# 10/06/94 (seiwald) - Dumb yyacc stuff moved into Jamfile.
X# 10/14/94 (seiwald) - (Crude) support for .s, .C, .cc, .cpp, and .f files.
X# 01/08/95 (seiwald) - Shell now handled with awk, not sed
X# 01/09/95 (seiwald) - Install* now take dest directory as target
X# 01/10/95 (seiwald) - All entries sorted.
X# 01/10/95 (seiwald) - NT support moved in, with LauraW's help.
X# 01/10/95 (seiwald) - VMS support moved in.
X# 02/06/95 (seiwald) - ObjectC++Flags and SubDirC++Flags added.
X# 02/07/95 (seiwald) - Iron out when HDRSEARCH uses "" or SEARCH_SOURCE.
X# 02/08/95 (seiwald) - SubDir works on VMS.
X# 02/14/95 (seiwald) - MkDir and entourage.
X
X# Special targets defined in this file:
X#
X# all - parent of first, shell, files, lib, exe
X# first - first dependent of 'all', for potential initialization
X# shell - parent of all Shell targets
X# files - parent of all File targets
X# lib - parent of all Library targets
X# exe - parent of all Main targets
X# dirs - parent of all MkDir targets
X# clean - removes all Shell, File, Library, and Main targets
X# uninstall - removes all Install targets
X#
X
X# Rules defined by this file:
X#
X# as obj.o : source.s ; .s -> .o
X# Bulk dir : files ; populate directory with many files
X# Cc obj.o : source.c ; .c -> .o
X# C++ obj.o : source.cc ; .cc -> .o
X# Clean clean : sources ; remove sources with 'jam clean'
X# File dest : source ; copy file
X# Fortran obj.o : source.f ; .f -> .o
X# Hardlink target : source ; make link from source to target
X# HdrRule source : headers ; handle #includes
X# Install target : source ; install any single file
X# InstallBin dir : sources ; install binaries
X# InstallLib dir : sources ; install files
X# InstallMan dir : sources ; install man pages
X# InstallShell dir : sources ; install shell scripts
X# Lex source.c : source.l ; .l -> .c
X# Library lib : source ; archive library from compiled sources
X# LibraryFromObjects lib : objects ; archive library from objects
X# LinkLibraries images : libraries ; bag libraries onto Mains
X# Main image : source ; link executable from compiled sources
X# MainFromObjects image : objects ; link executable from objects
X# MkDir dir ; make a directory, if not there
X# Object object : source ; compile object from source
X# ObjectCcFlags source : flags ; add compiler flags for object
X# ObjectC++Flags source : flags ; add compiler flags for object
X# ObjectHdrs source : dirs ; add include directories for object
X# Objects sources ; compile sources
X# RmTemps target : sources ; remove temp sources after target made
X# Setuid images ; mark executables Setuid
X# SubDir TOP d1 d2 ... ; start a subdirectory Jamfile
X# SubDirCcFlags flags ; add compiler flags until next SubDir
X# SubDirC++Flags flags ; add compiler flags until next SubDir
X# SubDirHdrs dirs ; add include dirs until next SubDir
X# SubInclude TOP d1 d2 ... ; include a subdirectory Jamfile
X# Shell exe : source ; make a shell executable
X# Undefines images : symbols ; save undef's for linking
X# UserObject object : source ; handle unknown suffixes for Object
X# Yacc source.c : source.y ; .y -> .c
X#
X
X# Brief review of the jam language:
X#
X# Statements:
X# rule RULE - statements to process a rule
X# actions RULE - system commands to carry out target update
X#
X# Modifiers on actions:
X# together - multiple instances of same rule on target get executed
X# once with their sources ($(>)) concatenated
X# updated - refers to updated sources ($(>)) only
X# ignore - ignore return status of command
X# quietly - don't trace its execution unless verbose
X# piecemeal - iterate command each time with a small subset of $(>)
X# existing - refers to currently existing sources ($(>)) only
X#
X# Special rules:
X# ALWAYS - always build a target
X# DEPENDS - builds the dependency graph
X# ECHO - blurt out targets on stdout
X# EXIT - blurt out targets and exit
X# INCLUDES - marks sources as headers for target (a codependency)
X# NOCARE - don't panic if the target can't be built
X# NOUPDATE - create the target if needed but never update it
X# NOTFILE - ignore the timestamp of the target (it's not a file)
X# TEMPORARY - target need not be present if sources haven't changed
X#
X# Special variables set by jam:
X# $(<) - targets of a rule (to the left of the :)
X# $(>) - sources of a rule (to the right of the :)
X# $(UNIX) - true on UNIX
X# $(VMS) - true on VMS
X# $(NT) - true on NT
X# $(OS) - name of OS - varies wildly
X#
X# Special variables used by jam:
X# SEARCH - where to find something (used during binding and actions)
X# LOCATE - where to plop something not found with SEARCH
X# HDRRULE - rule to call to handle include files
X# HDRSCAN - egrep regex to extract include files
X#
X# Special targets:
X# all - default if none given on command line
X#
X
X# Initialize variables
X#
X# "default =" - set only if unset
X
X#
X# OS specific variable settings
X#
X
Xswitch $(OS)
X{
Xcase AIX : LINKLIBS default = -lbsd ;
Xcase DGUX : RANLIB default = "" ;
Xcase IRIX : RANLIB default = "" ;
Xcase HPUX : RANLIB default = "" ;
X INSTALL default = "" ;
Xcase PTX : RANLIB default = "" ;
Xcase SOLARIS : RANLIB default = "" ;
X}
X
Xif $(UNIX)
X{
X AR default = ar ru ;
X AS default = as ;
X AWK default = awk ;
X ASFLAGS default = ;
X BINDIR default = /usr/local/bin ;
X C++ default = gcc ;
X C++FLAGS default = ;
X CC default = cc ;
X CCFLAGS default = ;
X CP default = cp ;
X CHMOD default = chmod ;
X EXEMODE default = 711 ;
X FILEMODE default = 644 ;
X FORTRAN default = f77 ;
X FORTRANFLAGS default = ;
X HDRS default = ;
X INSTALL default = install ;
X LEX default = lex ;
X LIBDIR default = /usr/local/lib ;
X LINK default = $(CC) ;
X LINKFLAGS default = $(CCFLAGS) ;
X LINKLIBS default = ;
X LN default = ln ;
X MANDIR default = /usr/local/man ;
X MKDIR default = mkdir ;
X MV default = mv -f ;
X OPTIM default = -O ;
X RANLIB default = ranlib ;
X RM default = rm -f ;
X SHELLHEADER default = "#!/bin/sh" ;
X SHELLMODE default = 755 ;
X SLASH default = / ;
X STDHDRS default = /usr/include ;
X SUFLIB default = .a ;
X SUFOBJ default = .o ;
X SUFEXE default = "" ;
X UNDEFFLAG default = "-u _" ;
X YACC default = yacc -d ;
X}
Xelse if $(NT)
X{
X if $(BCCROOT)
X {
X ECHO "Compiler is Borland C++" ;
X
X AR default = tlib ;
X ARFLAGS default = /C /P64 ;
X CC default = bcc32 ;
X CCFLAGS default = -v -w- ;
X MV default = rename ;
X RM default = del ;
X RW default = $(BCCROOT)\\lib\\rw ;
X RWLIBPATH default = $(RW)\\lib ;
X LINK default = $(CC) ;
X LINKFLAGS default = $(CCFLAGS) ;
X SLASH default = \\ ;
X STDLIBPATH default = $(BCCROOT)\\lib ;
X STDHDRS default = $(BCCROOT)\\include ;
X SUFLIB default = .lib ;
X SUFOBJ default = .obj ;
X SUFEXE default = .exe ;
X }
X else if $(MSVCNT)
X {
X ECHO "Compiler is Microsoft Visual C++" ;
X
X AR default = lib ;
X CC default = cl ;
X CCFLAGS default = /D \"NT\" ;
X MV default = rename ;
X RM default = del ;
X RW default = $(MSVCNT)\\lib\\rw ;
X RWLIBPATH default = $(RW)\\lib ;
X LINK default = $(CC) ;
X LINKFLAGS default = $(CCFLAGS) ;
X LINKLIBS default = $(MSVCNT)\\lib\\advapi32.lib
X $(MSVCNT)\\lib\\libcmt.lib
X $(MSVCNT)\\lib\\libc.lib
X $(MSVCNT)\\lib\\oldnames.lib
X $(MSVCNT)\\lib\\kernel32.lib ;
X OPTIM default = ;
X SLASH default = \\ ;
X STDHDRS default = $(MSVCNT)\\include ;
X SUFLIB default = .lib ;
X SUFOBJ default = .obj ;
X SUFEXE default = .exe ;
X UNDEFFLAG default = "/u _" ;
X }
X}
Xelse if $(VMS)
X{
X AS default = as ;
X CC default = cc ;
X CCFLAGS default = ;
X CRELIB default = true ;
X EXEMODE default = (w:e) ;
X FILEMODE default = (w:r) ;
X HDRS default = ;
X LEX default = lex ;
X LINK default = link ;
X LINKFLAGS default = ;
X LINKLIBS default = ;
X MV default = rename ;
X OPTIM default = ;
X RM default = delete ;
X SHELLMODE default = (w:er) ;
X SLASH default = . ;
X STDHDRS default = decc$library_include ;
X SUFLIB default = .olb ;
X SUFOBJ default = .obj ;
X SUFEXE default = .exe ;
X
X switch $(OS)
X {
X case OPENVMS : CCFLAGS default = /stand=vaxc ;
X case VMS : LINKLIBS default = sys$library:vaxcrtl.olb/lib ;
X }
X}
X
XJAMFILE default = Jamfile ;
XJAMRULES default = Jamrules ;
X
XHDRPATTERN = "^#[ ]*include[ ]*[<\"](.*)[\">].*$" ;
X
X#
X# Base dependencies - first for "bootstrap" kinds of rules
X#
X
XDEPENDS all : first shell files lib exe ;
XNOTFILE all first shell files lib exe dirs clean uninstall ;
XALWAYS clean uninstall ;
X
X#
X# Rules
X#
X
Xrule As
X{
X DEPENDS $(<) : $(>) ;
X}
X
Xrule Bulk
X{
X for i in $(>)
X {
X File $(i:D=$(<)) : $(i) ;
X }
X}
X
Xrule Cc
X{
X DEPENDS $(<) : $(>) ;
X
X # Just to clarify here: this sets the per-target CCFLAGS to
X # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
X
X CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ;
X
X # If the compiler's -o flag doesn't work, relocate the .o
X
X if $(RELOCATE)
X {
X CcMv $(<) : $(>) ;
X }
X
X if $(VMS) && $(HDRS[1])
X {
X SLASHINC on $(<) = "/inc=(" $(HDRS[1]) ,$(HDRS[2-]) ")" ;
X }
X}
X
Xrule C++
X{
X DEPENDS $(<) : $(>) ;
X C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) ;
X
X if $(VMS) && $(HDRS[1])
X {
X SLASHINC on $(<) = "/inc=(" $(HDRS[1]) ,$(HDRS[2-]) ")" ;
X }
X}
X
Xrule File
X{
X DEPENDS files : $(<) ;
X DEPENDS $(<) : $(>) ;
X SEARCH on $(>) = $(SEARCH_SOURCE) ;
X MODE on $(<) = $(FILEMODE) ;
X Chmod $(<) ;
X}
X
Xrule Fortran
X{
X DEPENDS $(<) : $(>) ;
X}
X
Xrule HardLink
X{
X DEPENDS files : $(<) ;
X DEPENDS $(<) : $(>) ;
X SEARCH on $(>) = $(SEARCH_SOURCE) ;
X}
X
Xrule HdrRule
X{
X # HdrRule source : headers ;
X
X # N.B. This rule is called during binding, potentially after
X # the fate of many targets has been determined, and must be
X # used with caution: don't add dependencies to unrelated
X # targets, and don't set variables on $(<).
X
X # Tell Jam that anything depending on $(<) also depends on $(>),
X # set SEARCH so Jam can find the headers, but then say we don't
X # care if we can't actually find the headers (they may have been
X # within ifdefs),
X
X INCLUDES $(<) : $(>) ;
X SEARCH on $(>) = $(HDRSEARCH) ;
X NOCARE $(>) ;
X
X # Propagate on $(<) to $(>)
X
X HDRSEARCH on $(>) = $(HDRSEARCH) ;
X HDRSCAN on $(>) = $(HDRSCAN) ;
X HDRRULE on $(>) = $(HDRRULE) ;
X}
X
Xrule Install
X{
X DEPENDS install : $(<) ;
X DEPENDS $(<) : $(>) ;
X SEARCH on $(>) = $(SEARCH_SOURCE) ;
X
X # depend upon and create the directory
X
X DEPENDS $(<) : $(<:D) ;
X MkDir $(<:D) ;
X
X # Arrange for jam uninstall
X
X Clean uninstall : $(<) ;
X
X if ! $(INSTALL)
X {
X Chmod $(<) ;
X
X if $(OWNER) { Chown $(<) ; OWNER on $(<) = $(OWNER) ; }
X if $(GROUP) { Chgrp $(<) ; GROUP on $(<) = $(GROUP) ; }
X }
X}
X
Xrule InstallBin
X{
X for i in $(>)
X {
X Install $(i:D=$(<)) : $(i) ;
X MODE on $(i:D=$(<)) = $(EXEMODE) ;
X }
X}
X
Xrule InstallLib
X{
X for i in $(>)
X {
X Install $(i:D=$(<)) : $(i) ;
X MODE on $(i:D=$(<)) = $(FILEMODE) ;
X }
X}
X
Xrule InstallMan
X{
X # Really this just strips the . from the suffix
X
X for i in $(>)
X {
X switch $(i:S)
X {
X case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;
X case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;
X case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;
X case .n : s = n ; case .man : s = 1 ;
X }
X
X d = $(i:D=man$(s):S=.$(s)) ;
X
X Install $(d:R=$(<)) : $(i) ;
X MODE on $(d:R=$(<)) = $(FILEMODE) ;
X }
X}
X
Xrule InstallShell
X{
X for i in $(>)
X {
X Install $(i:D=$(<)) : $(i) ;
X MODE on $(i:D=$(<)) = $(SHELLMODE) ;
X }
X}
X
Xrule Lex
X{
X DEPENDS $(<) : $(>) ;
X LOCATE on $(<) = $(LOCATE_TARGET) ;
X Clean clean : $(<) ;
X}
X
Xrule Library
X{
X LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
X Objects $(>) ;
X}
X
Xrule LibraryFromObjects
X{
X # library depends on its member objects
X
X l = $(<:S=$(SUFLIB)) ;
X s = $(>) ;
X
X if $(SOURCE_GRIST)
X {
X s = $(>:G=$(SOURCE_GRIST)) ;
X }
X
X DEPENDS lib : $(l) ;
X DEPENDS $(l) : $(l)($(s:BS)) ;
X
X Clean clean : $(l) ;
X
X # We wish we could locate the library and it's contents,
X # but the reference to $(NEEDLIBS) in Main's actions
X # get the unbound names. Only $(<) and $(>) refer to
X # bound file name in rule actions. Sigh.
X #
X # LOCATE on $(<) $(<)($(s:BS)) = $(LOCATE_TARGET) ;
X
X # each archive member object depends on real object
X # each real object gets compiled from sources
X
X for i in $(s)
X {
X DEPENDS $(l)($(i:BS)) : $(i) ;
X }
X
X # must call separate Archive rule so that 'updated' modifier
X # on 'actions' refers to updated .o's.
X # delete objects after archive is made
X
X if $(CRELIB) { CreLib $(l) ; }
X
X Archive $(l) : $(s) ;
X RmTemps $(l) : $(s) ;
X
X if $(RANLIB) { Ranlib $(l) ; }
X}
X
Xrule Link
X{
X MODE on $(<) = $(EXEMODE) ;
X Chmod $(<) ;
X}
X
Xrule LinkLibraries
X{
X # make library dependencies of target
X # set NEEDLIBS variable used by 'actions Main'
X
X if $(<:S)
X {
X t = $(<) ;
X } else {
X t = $(<:S=$(SUFEXE)) ;
X }
X
X DEPENDS $(t) : $(>:S=$(SUFLIB)) ;
X NEEDLIBS on $(t) += $(>:S=$(SUFLIB)) ;
X}
X
Xrule Main
X{
X MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
X Objects $(>) ;
X}
X
Xrule MainFromObjects
X{
X # make compiled sources a dependency of target
X
X s = $(>) ;
X
X if $(SOURCE_GRIST)
X {
X s = $(>:G=$(SOURCE_GRIST)) ;
X }
X
X if $(<:S)
X {
X t = $(<) ;
X } else {
X t = $(<:S=$(SUFEXE)) ;
X }
X
X DEPENDS exe : $(t) ;
X DEPENDS $(t) : $(s) ;
X LOCATE on $(t) = $(LOCATE_TARGET) ;
X
X Clean clean : $(t) ;
X
X Link $(t) : $(s) ;
X}
X
Xrule MkDir
X{
X if ! $($(<)-mkdir)
X {
X # Cheesy gate to prevent multiple invocations on same dir
X # MkDir1 has the actions
X # If dir exists, don't update it
X # Arrange for jam dirs
X
X $(<)-mkdir = true ;
X MkDir1 $(<) ;
X NOUPDATE $(<) ;
X Depends dirs : $(<) ;
X
X # Recursively make parent directories.
X # On UNIX, $(<:D) = $(<)'s parent, & we recurse until root
X # On VMS, $(<:D) = $(<), no recursing, but you don't need to
X # create parent directories explicitly there.
X
X s = $(<:D) ;
X
X if $(s) && $(s) != $(<)
X {
X Depends $(<) : $(s) ;
X MkDir $(s) ;
X }
X }
X}
X
Xrule Object
X{
X # locate object and search for source, if wanted
X
X Clean clean : $(<) ;
X
X LOCATE on $(<) = $(LOCATE_TARGET) ;
X SEARCH on $(>) = $(SEARCH_SOURCE) ;
X
X # Save HDRS for -I$(HDRS) on compile.
X # We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers
X # in the .c file's directory, but generated .c files (from
X # yacc, lex, etc) are located in $(LOCATE_TARGET), possibly
X # different from $(SEARCH_SOURCE).
X
X HDRS on $(<) = $(HDRS) $(SUBDIRHDRS) $(SEARCH_SOURCE) ;
X
X # handle #includes for source: Jam scans for headers with
X # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
X # with the scanned file as the target and the found headers
X # as the sources. HDRSEARCH is just grist for HdrRule.
X
X # $(h) is where cc first looks for #include "foo.h" files.
X # If the source file is in a distant directory, look there.
X # Else, look in "" (the current directory).
X
X if $(SEARCH_SOURCE)
X {
X h = $(SEARCH_SOURCE) ;
X }
X else
X {
X h = "" ;
X }
X
X HDRRULE on $(>) = HdrRule ;
X HDRSCAN on $(>) = $(HDRPATTERN) ;
X HDRSEARCH on $(>) = $(HDRS) $(SUBDIRHDRS) $(h) $(STDHDRS) ;
X
X # if source is not .c, generate .c with specific rule
X
X switch $(>:S)
X {
X case .c : Cc $(<) : $(>) ;
X case .C : C++ $(<) : $(>) ;
X case .cc : C++ $(<) : $(>) ;
X case .cpp : C++ $(<) : $(>) ;
X case .f : Fortran $(<) : $(>) ;
X case .l : Cc $(<) : $(<:S=.c) ;
X Lex $(<:S=.c) : $(>) ;
X case .s : As $(<) : $(>) ;
X case .y : Cc $(<) : $(<:S=.c) ;
X Yacc $(<:S=.c) : $(>) ;
X case * : UserObject $(<) : $(>) ;
X }
X}
X
Xrule ObjectCcFlags
X{
X s = $(<:S=$(SUFOBJ)) ;
X
X if $(SOURCE_GRIST)
X {
X s = $(s:G=$(SOURCE_GRIST)) ;
X }
X
X CCFLAGS on $(s) += $(>) ;
X}
X
Xrule ObjectC++Flags
X{
X s = $(<:S=$(SUFOBJ)) ;
X
X if $(SOURCE_GRIST)
X {
X s = $(s:G=$(SOURCE_GRIST)) ;
X }
X
X C++FLAGS on $(s) += $(>) ;
X}
X
Xrule ObjectHdrs
X{
X s = $(<:S=$(SUFOBJ)) ;
X
X if $(SOURCE_GRIST)
X {
X s = $(s:G=$(SOURCE_GRIST)) ;
X }
X
X HDRS on $(s) += $(>) ;
X}
X
Xrule Objects
X{
X s = $(<) ;
X
X if $(SOURCE_GRIST)
X {
X s = $(<:G=$(SOURCE_GRIST)) ;
X }
X
X for i in $(s)
X {
X Object $(i:S=$(SUFOBJ)) : $(i) ;
X }
X}
X
Xrule RmTemps
X{
X TEMPORARY $(>) ;
X}
X
Xrule Setuid
X{
X if $(<:S)
X {
X t = $(<) ;
X } else {
X t = $(<:S=$(SUFEXE)) ;
X }
X
X MODE on $(t) = 4711 ;
X}
X
Xrule Shell
X{
X DEPENDS shell : $(<) ;
X DEPENDS $(<) : $(>) ;
X SEARCH on $(>) = $(SEARCH_SOURCE) ;
X MODE on $(<) = $(SHELLMODE) ;
X Chmod $(<) ;
X}
X
Xrule SubDir
X{
X #
X # SubDir TOP d1 [ ... ]
X #
X # This introduces a Jamfile that is part of a project tree
X # rooted at $(TOP). It (only once) includes the project-specific
X # rules file $(TOP)/Jamrules and then sets search & locate stuff.
X #
X # If the variable $(TOPRULES) is set (where TOP is the first arg
X # to SubDir), that file is included instead of $(TOP)/Jamrules.
X #
X # d1 ... are the directory elements that lead to this directory
X # from $(TOP). We construct the system dependent path from these
X # directory elements in order to set search&locate stuff.
X #
X
X if ! $($(<[1]))
X {
X EXIT Top level of source tree has not been set with $(<[1]) ;
X }
X
X #
X # If $(TOP)/Jamrules hasn't been included, do so.
X #
X
X if ! $($(<[1])-included)
X {
X # Gated entry.
X
X $(<[1])-included = TRUE ;
X
X # File is $(TOPRULES) or $(TOP)/Jamrules.
X
X r = $($(<[1])RULES) ;
X
X if ! $(r)
X {
X r = $(JAMRULES:R=$($(<[1]))) ;
X }
X
X # Include it.
X
X include $(r) ;
X }
X
X # Get the grist $(g), search $(s), by concatenating the
X # directory elements using the OS specific path separator.
X
X g = $(<[2]) ;
X s = $(<[2]) ;
X
X for i in $(<[3-])
X {
X g = $(g)!$(i) ;
X s = $(s)$(SLASH)$(i) ;
X }
X
X if $(VMS)
X {
X s = [$(s)] ;
X }
X
X # Now set up SEARCH_SOURCE, LOCATE_TARGET, SOURCE_GRIST
X # These can be reset if needed. For example, if the source
X # directory should not hold object files, LOCATE_TARGET can
X # subsequently be redefined.
X
X SUBDIR = $(s:R=$($(<[1]))) ;
X SEARCH_SOURCE = $(SUBDIR) ;
X LOCATE_TARGET = $(SUBDIR) ;
X SOURCE_GRIST = $(g) ;
X
X # Reset per-directory ccflags, hdrs
X
X SUBDIRCCFLAGS = ;
X SUBDIRC++FLAGS = ;
X SUBDIRHDRS = ;
X}
X
Xrule SubDirCcFlags
X{
X SUBDIRCCFLAGS += $(<) ;
X}
X
Xrule SubDirC++Flags
X{
X SUBDIRC++FLAGS += $(<) ;
X}
X
Xrule SubDirHdrs
X{
X SUBDIRHDRS += $(<) ;
X}
X
Xrule SubInclude
X{
X # That's
X # SubInclude TOP d1 [ d2 [ d3 [ d4 ] ] ]
X #
X # to include a subdirectory's Jamfile.
X
X if ! $($(<[1]))
X {
X EXIT Top level of source tree has not been set with $(<[1]) ;
X }
X
X s = $(<[2]) ;
X
X for i in $(<[3-])
X {
X s = $(s)$(SLASH)$(i) ;
X }
X
X if $(VMS)
X {
X s = [$(s)] ;
X }
X
X include $(JAMFILE:D=$(s):R=$($(<[1]))) ;
X}
X
Xrule Undefines
X{
X if $(<:S)
X {
X t = $(<) ;
X } else {
X t = $(<:S=$(SUFEXE)) ;
X }
X
X UNDEFS on $(t) += $(UNDEFFLAG)$(>) ;
X}
X
Xrule UserObject
X{
X EXIT "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ;
X}
X
Xrule Yacc
X{
X h = $(<:BS=.h) ;
X
X # Some places don't have a yacc.
X
X if $(YACC)
X {
X DEPENDS $(<) $(h) : $(>) ;
X Yacc1 $(<) $(h) : $(>) ;
X Clean clean : $(<) $(h) ;
X }
X
X # make sure someone includes $(h) else it will be
X # a deadly independent target
X
X INCLUDES $(<) : $(h) ;
X LOCATE on $(<) $(h) = $(LOCATE_TARGET) ;
X}
X
X#
X# Actions
X#
X
Xif $(UNIX)
X{
X
X actions updated together piecemeal Archive
X {
X $(AR) $(<) $(>)
X }
X
X actions As
X {
X $(AS) $(ASFLAGS) -o $(<) $(>) ;
X }
X
X actions C++
X {
X $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>)
X }
X
X actions Cc
X {
X $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>)
X }
X
X actions CcMv
X {
X [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)
X }
X
X actions Chgrp
X {
X chgrp $(GROUP) $(<)
X }
X
X actions Chmod
X {
X chmod $(MODE) $(<)
X }
X
X actions Chown
X {
X chown $(OWNER) $(<)
X }
X
X actions piecemeal together existing Clean
X {
X $(RM) $(>)
X }
X
X actions File
X {
X $(RM) $(<)
X $(CP) $(>) $(<) &&
X }
X
X actions Fortran
X {
X $(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>)
X }
X
X actions HardLink
X {
X $(RM) $(<) && $(LN) $(>) $(<)
X }
X
X if $(INSTALL)
X {
X actions Install
X {
X $(INSTALL) -m$(MODE) -o$(OWNER) -g$(GROUP) $(>) $(<)
X }
X }
X else
X {
X actions Install
X {
X $(CP) $(>) $(<)
X }
X }
X
X actions Lex
X {
X $(LEX) $(>) && $(MV) lex.yy.c $(<)
X }
X
X actions Link
X {
X if $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
X then :
X else $(RM) $(<) && exit 1
X fi
X }
X
X actions MkDir1
X {
X $(MKDIR) $(<)
X }
X
X actions together Ranlib
X {
X $(RANLIB) $(<)
X }
X
X actions quietly updated piecemeal together RmTemps
X {
X $(RM) $(>)
X }
X
X actions Shell
X {
X $(AWK) '
X NR == 1 { print "$(SHELLHEADER)" }
X NR == 1 && /^[#:]/ { next }
X /^##/ { next }
X { print }
X ' < $(>) > $(<)
X }
X
X actions Yacc1
X {
X $(YACC) $(>) &&
X {
X $(MV) y.tab.c $(<[1])
X $(MV) y.tab.h $(<[2])
X }
X }
X}
Xelse if $(NT)
X{
X if $(BCCROOT)
X {
X actions Link
X {
X $(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>) || del $(<) /f
X }
X
X actions together piecemeal Archive
X {
X $(AR) $(ARFLAGS) $(<) -+$(>)
X }
X }
X else if $(MSVCNT)
X {
X actions Link
X {
X $(LINK) $(LINKFLAGS) /o$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
X }
X
X actions together piecemeal Archive
X {
X $(AR) /out:$(<) $(>)
X }
X }
X
X actions Cc
X {
X $(CC) /c $(CCFLAGS) $(OPTIM) /out:$(<) /I$(HDRS) $(>)
X }
X
X actions Chmod
X {
X }
X
X actions piecemeal together existing Clean
X {
X $(RM) $(>) /f /q
X }
X
X actions File
X {
X copy $(>) $(<)
X }
X
X actions quietly updated piecemeal together RmTemps
X {
X $(RM) $(>)
X }
X}
Xelse if $(VMS)
X{
X
X actions updated together piecemeal Archive
X {
X lib/replace $(<) $(>[1]) ,$(>[2-])
X }
X
X actions Cc
X {
X cc/obj=$(<) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>)
X }
X
X actions Chmod
X {
X set file/prot=$(MODE) $(<)
X }
X
X actions piecemeal together existing Clean
X {
X $(RM) $(>[1]);* ,$(>[2-]);*
X }
X
X actions together quietly CreLib
X {
X if f$search("$(<)") .eqs. "" then lib/create $(<)
X }
X
X actions File
X {
X copy $(>) $(<)
X }
X
X actions Install
X {
X copy $(>) $(<)
X }
X
X actions Lex
X {
X $(LEX) $(>)
X $(MV) lex.yy.c $(<)
X }
X
X actions Link
X {
X $(LINK)/exe=$(<) $(LINKFLAGS) $(>[1]) ,$(>[2-]) ,$(NEEDLIBS)/lib ,$(LINKLIBS)
X }
X
X actions MkDir1
X {
X create/dir $(<)
X }
X
X actions quietly updated piecemeal together RmTemps
X {
X $(RM) $(>[1]);* ,$(>[2-]);*
X }
X
X actions Shell
X {
X copy $(>) $(<)
X }
X
X actions Yacc1
X {
X $(YACC) $(>)
X $(MV) y.tab.c $(<[1])
X $(MV) y.tab.h $(<[2])
X }
X}
X
X
X#
X# Backwards compatibility with jam 1, where rules were uppercased.
X#
X
Xrule BULK { Bulk $(<) : $(>) ; }
Xrule FILE { File $(<) : $(>) ; }
Xrule HDRRULE { HdrRule $(<) : $(>) ; }
Xrule INSTALL { Install $(<) : $(>) ; }
Xrule LIBRARY { Library $(<) : $(>) ; }
Xrule LIBS { LinkLibraries $(<) : $(>) ; }
Xrule LINK { Link $(<) : $(>) ; }
Xrule MAIN { Main $(<) : $(>) ; }
Xrule SETUID { Setuid $(<) ; }
Xrule SHELL { Shell $(<) : $(>) ; }
Xrule UNDEFINES { Undefines $(<) : $(>) ; }
X
X# Old INSTALL* didn't take dest directory.
X
Xrule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; }
Xrule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; }
Xrule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; }
X
X#
X# Now include the user's Jamfile.
X#
X
Xinclude $(JAMFILE) ;
X
END_OF_FILE
if test 23751 -ne `wc -c <'Jambase'`; then
echo shar: \"'Jambase'\" unpacked with wrong size!
fi
# end of 'Jambase'
fi
if test -f 'filesys.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'filesys.h'\"
else
echo shar: Extracting \"'filesys.h'\" \(918 characters\)
sed "s/^X//" >'filesys.h' <<'END_OF_FILE'
X/*
X * Copyright 1993, 1995 Christopher Seiwald.
X *
X * This file is part of Jam - see jam.c for Copyright information.
X */
X
X/*
X * filesys.h - FILENAME struct and OS specific file routines
X */
X
X/*
X * FILENAME - a name of a file, broken into <grist>dir/base/suffix(member)
X *
X * <grist> is salt to distinguish between targets that otherwise would
X * have the same name: it never appears in the bound name of a target.
X * (member) is an archive member name: the syntax is arbitrary, but must
X * agree in file_parse(), file_build() and the Jambase.
X */
X
Xtypedef struct _filename FILENAME;
X
Xstruct _filename {
X struct filepart {
X char *ptr;
X int len;
X } part[6];
X# define f_grist part[0]
X# define f_root part[1]
X# define f_dir part[2]
X# define f_base part[3]
X# define f_suffix part[4]
X# define f_member part[5]
X} ;
X
Xvoid file_parse();
Xvoid file_build();
X
Xvoid file_archscan();
Xvoid file_dirscan();
X
Xint file_time();
END_OF_FILE
if test 918 -ne `wc -c <'filesys.h'`; then
echo shar: \"'filesys.h'\" unpacked with wrong size!
fi
# end of 'filesys.h'
fi
if test -f 'jam.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jam.1'\"
else
echo shar: Extracting \"'jam.1'\" \(19224 characters\)
sed "s/^X//" >'jam.1' <<'END_OF_FILE'
X.TH JAM 1 "10 March 1995"
X.SH NAME
X\fBjam\fR
X\-
X\fBmake\fR(1)
Xredux
X
X.SH SYNOPSIS
X\fBjam\fR
X[ \fB-a\fR ]
X[ \fB-n\fR ]
X[ \fB-v\fR ]
X[ \fB-d \fIdebug\fR ]
X[ \fB-f \fIJambase\fR ... ]
X[ \fB-j \fIjobs\fR ]
X[ \fB-t \fItarget\fR ... ]
X[ \fItarget\fR ... ]
X
X.SH DESCRIPTION
X.PP
X\fBJam\fR recursively builds target files from their source files,
Xusing two files to define the dependency graph and the updating actions
Xfor all targets. The file \fBJambase\fR (usually located in
X/usr/local/lib) defines rules, and the file \fBJamfile\fR (located in
Xthe current directory) lists the targets and sources in terms of those
Xrules. \fBJam\fR does not need to rely on suffix-driven implicit rules
Xor directory contents. A \fBJambase\fR is provided with \fBjam\fR; the
Xuser supplies the \fBJamfile\fR.
X.PP
XSee \fBJamfile\fR(5) for information on writing Jamfiles. This manual
Xpage describes the program that interprets \fBJambase\fR and
X\fBJamfile\fR.
X
X.SH OPTIONS
X.PP
XIf \fItarget\fR is provided on the command line, \fBjam\fR attempts to
Xbuild that target; otherwise \fBjam\fR attempts to build the target
X\fIall\fR.
X.PP
X\fBJam\fR supports the following options:
X.IP "-a"
XBuild all targets, even if they are up-to-date.
X.IP "-d\fI<n>\fR"
XSet the debug level to \fI<n>\fR. Interesting values are:
X.PP
X.RS
X0 Emit only errors
X.br
X1 Emit update action tracing (default)
X.br
X2 Emit update commands
X.br
X3 Produce dependency information
X.br
X4 Show modification times of bound files
X.br
X5 Show rule invocation
X.br
X6-9 debugging
X.RE
X.IP "-f\fI<file>\fR"
XRead \fI<file>\fR instead of \fBJambase\fR.
X.IP "-j\fI<jobs>\fR"
XRun up to \fI<jobs>\fR shell commands concurrently (UNIX only).
XThe default is 1.
X.IP "-n"
XDon't actually execute the updating actions, but do everything else.
XThis implies \fB-d\fI2\fR.
X.IP "-t\fI<target>\fR"
XRebuild \fI<target>\fR, even if it is up-to-date.
X.IP "-v"
XPrint the version of \fBjam\fR and exit.
X
X.SH "THE JAM LANGUAGE"
X.PP
XThe \fBjam\fR language supports defining rules, invoking rules, and
Xsetting variables. It also has a few flow-of-control statements.
X\fBJambase\fR and \fBJamfile\fR share this language.
X.SS "Lexical Features"
X\fBJam\fR treats its input files as whitespace-separated tokens, with
Xtwo exceptions: double quotes (") can enclose whitespace to embed it
Xinto a token, and everything between the matching curly braces ({}) in
Xthe definition of a rule action is treated as a single string. A
Xbackslash (\\) can escape a double quote.
X.PP
X\fBJam\fR requires whitespace (blanks, tabs, or newlines) to surround
Xall tokens, including the colon (:) and semicolon (;) tokens. This is
Xbecause \fBjam\fR runs on many platforms and no characters, save
Xwhitespace, are uncommon in the file names on all of those platforms.
X.SS Targets
XTargets are files to be updated and sources are the files used in
Xupdating those targets. Collectively, they are just referred to as
X"targets". A target is simply a file name, either rooted or relative
Xto the directory of \fBjam\fR's invocation. The special syntax,
X\fIfile(member)\fR, refers to an \fBar\fR(1) library member. The
Xspecial syntax, \fI<grist>file\fR, perturbs a file name to distinguish
Xit from other files with the same name. The \fI<grist>\fR is stripped
Xfrom the name during binding (q.v., below).
X.SS Rules
X\fBJam\fR's basic entity is called a rule, which is used to relate
Xtargets to their sources. A rule is defined in two parts: the
X\fBjam\fR statements to execute when the rule is invoked (essentially a
Xprocedure call), and the actions (shell commands) to execute in order
Xto update the targets of the rule. A rule may have a procedure
Xdefinition, actions, or both.
X.PP
XThe \fBjam\fR statements for defining and invoking rules are as
Xfollows. \fI<targets>\fR and \fI<sources>\fR are lists of file names;
X\fI<statements>\fR are \fBjam\fR statements; and \fI<string>\fR is a
Xshell script:
X.IP
Xrule \fI<rulename>\fR { \fI<statements>\fR }
X.IP
Xactions [ \fImodifiers\fR ] \fI<rulename>\fR { \fI<string>\fR }
X.IP
X\fI<rulename>\fR \fI<targets>\fR [ : \fI<sources>\fR ] ;
X.PP
XThe first form defines a rule's procedure; the second defines the rule's
Xupdating actions; the third invokes the rule. Redefining a rule's
Xprocedure or actions replaces the previous definition.
X.PP
XInvoking a rule executes the procedure for the rule (if any) and
Xassociates any update actions for the targets. More than one update
Xaction may be associated with a target: the actions are executed in the
Xorder in which they are added.
X.PP
XIn both the rule's procedure definition and the rule's actions, the
Xspecial variables $(<) and $(>) refer to the \fI<targets>\fR and
X\fI<sources>\fR given at rule invocation. However, in the rule's
Xactions, $(<) and $(>) refer to the \fI<targets>\fR and \fI<sources>\fR
Xafter they have been bound by the binding phase (q.v., below).
X\fBJam\fR issues a warning if $(<) or $(>) have elements not in the
Xdependency graph.
X.PP
XThe following action \fImodifiers\fR are understood:
X.RS
X.IP "\fBactions existing\fR"
X$(>) includes only targets currently existing.
X.IP "\fBactions ignore\fR"
XThe return status of the shell commands is ignored.
X.IP "\fBactions piecemeal\fR"
XThe shell commands are repeatedly invoked with a subset of $(>)
Xsmall enough to fit in a command buffer.
X.IP "\fBactions quietly\fR"
XThe action is not echoed to the standard output.
X.IP "\fBactions together\fR"
XThe $(>) from multiple instances of the same action on the same
Xtarget are glommed together.
X.IP "\fBactions updated\fR"
X$(>) includes only targets marked for updating.
X.RE
X.SS "Built-in Rules"
X.PP
X\fBJam\fR has ten built-in rules, none of which have updating actions:
X.PP
X.RS
X.IP "ALWAYS \fI<targets>\fR ;"
X.br
XRebuilds \fI<targets>\fR, even if they are up-to-date.
X.IP "DEPENDS \fI<targets>\fR : \fI<sources>\fR ;"
X.br
XMakes \fI<sources>\fR dependencies of \fI<targets>\fR.
X.IP "ECHO \fI<args>\fR ;"
X.br
XBlurts out the message \fI<args>\fR to stdout.
X.IP "EXIT \fI<args>\fR ;"
X.br
XBlurts out the message \fI<args>\fR to stdout and then
Xexits with a failure status.
X.IP "INCLUDES \fI<targets>\fR : \fI<sources>\fR ;"
X.br
XMakes \fI<sources>\fR dependencies of anything of which \fI<targets>\fR
Xare dependencies.
X.IP "LEAVES \fI<targets>\fR ;"
X.br
XMakes each of \fI<targets>\fR depend only on its leaf sources, and not
Xon any intermediate targets. Its leaf sources are those dependencies
Xwithout any dependencies themselves.
X.IP "NOCARE \fI<targets>\fR ;"
X.br
XMarks \fI<targets>\fR as possibly being bogus.
X.IP "NOTFILE \fI<targets>\fR ;"
X.br
XMarks \fI<targets>\fR as not being files.
X.IP "NOUPDATE \fI<targets>\fR ;"
X.br
XCauses the timestamps of \fI<targets>\fR to be ignored: either the
Xtarget exists or it doesn't. If it exists, it is considered eternally
Xold.
X.IP "TEMPORARY \fI<targets>\fR ;"
X.br
XMarks \fI<targets>\fR as temporary.
X.RE
X.PP
XThe \fIALWAYS\fR, \fILEAVES\fR, \fINOCARE\fR, \fINOTFILE\fR,
X\fINOUPDATE\fR, and \fITEMPORARY\fR affect only the binding phase
X(q.v.).
X.SS "Flow-of-Control"
X.PP
X\fBJam\fR has several simple flow-of-control statements:
X.IP
Xinclude \fI<a>\fR ;
X.IP
Xfor \fI<a>\fR in \fI<args>\fR { \fI<statements>\fR }
X.IP
Xswitch \fI<a>\fR { case \fI<v1>\fR : \fI<statements>\fR ; case \fI<v2>\fR : \fI<statements>\fR ; ... }
X.IP
Xif \fI<cond>\fR { \fI<statements>\fR } [ else { \fI<statements>\fR } ]
X.PP
XThe \fBinclude\fR statement includes the named file. The file is bound
Xlike regular targets (see \fBBinding\fR, below), but unlike regular
Xtargets the include file cannot be built.
X.PP
XThe \fBfor\fR loop executes \fI<statements>\fR for each value in
X\fI<args>\fR, setting the variable \fI<a>\fR to the value.
X.PP
XThe \fBswitch\fR statement executes zero or one of the enclosed
X\fI<statements>\fR, depending on which value \fI<a>\fR matches. The
X\fI<v>\fR values are not variable-expanded. The \fI<v>\fR values may
Xinclude the following wildcards:
X.PP
X.RS
X? match any single character
X.br
X* match zero or more characters
X.br
X[\fI<chars>\fR] match any single character in \fI<chars>\fR
X.RE
X.PP
XThe \fBif\fR statement does the obvious; the \fBelse\fR clause is
Xoptional. \fI<cond>\fR is built of:
X.PP
X.RS
X\fI<a>\fR true if \fI<a>\fR is a non-zero-length string
X.br
X\fI<a>\fR = \fI<b>\fR strings equal
X.br
X\fI<a>\fR != \fI<b>\fR strings not equal
X.br
X\fI<a>\fR < \fI<b>\fR string less than
X.br
X\fI<a>\fR <= \fI<b>\fR string less than or equal to
X.br
X\fI<a>\fR > \fI<b>\fR string greater than
X.br
X\fI<a>\fR >= \fI<b>\fR string greater than or equal to
X.PP
X! \fI<cond>\fR condition not true
X.br
X\fI<cond>\fR && \fI<cond>\fR conjunction
X.br
X\fI<cond>\fR || \fI<cond>\fR disjunction
X.br
X( \fI<cond>\fR ) grouping
X.RE
X.PP
XIn comparisons, the arguments may (through variable expansion) be more
Xthan one token, but only the first token takes part in the comparison.
XIf, through variable expansion, the argument is zero tokens, a single
Xtoken of a zero-length string is used instead.
X.SS Variables
X.PP
X\fBJam\fR variables are lists of strings, with zero or more elements.
XAn undefined variable is indistinguishable from a variable whose value
Xis an empty list. Variables are either global or target-specific. All
Xvariables are referenced as $(VARIABLE).
X.PP
XA variable is defined with:
X.IP
X\fI<variable>\fR = \fI<values>\fR ;
X.IP
X\fI<variable>\fR += \fI<values>\fR ;
X.IP
X\fI<variable>\fR on \fI<targets>\fR = \fI<values>\fR ;
X.IP
X\fI<variable>\fR on \fI<targets>\fR += \fI<values>\fR ;
X.IP
X\fI<variable>\fR default = \fI<values>\fR ;
X.PP
XThe first two forms set \fI<variable>\fR globally. The third and forth
Xforms set a target-specific variable, where \fI<variable>\fR takes on a
Xvalue only during the binding and updating \fI<targets>\fR. The
X\fB=\fR operator replaces any previous value of \fI<variable>\fR with
X\fI<values>\fR; the \fB+=\fR operation appends \fI<values>\fR to any
Xprevious value. The final form sets \fI<variable>\fR globally, but
Xonly if it was previously unset.
X.PP
XOn program start-up, \fBjam\fR imports the environment variable
Xsettings into \fBjam\fR variables. Environment variables are split at
Xblanks with each word becomming an element in the variable's list
Xvalue. Environment variables whose names end in \fBPATH\fR are split
Xat colons ("\fB:\fR"). \fBJam\fR variables are not re-exported to
Xthe shell that executes the updating actions, but the updating actions
Xcan reference \fBjam\fR variables with $(VARIABLE).
X.SS "Variable Expansion"
X.PP
XBefore executing a statement, \fBjam\fR performs variable expansion on
Xeach token that is not a keyword or rule name. Such tokens with
Xembedded variable references are replaced with zero or more tokens.
XVariable references are of the form $(\fIv\fR) or $(\fIvm\fR), where
X\fIv\fR is the variable name, and \fIm\fR are optional modifiers.
X.PP
XVariable expansion in a rule's actions is similar to variable expansion
Xin statements, except that the action string is tokenized at whitespace
Xregardless of quoting.
X.PP
XThe result of a token after variable expansion is the product of the
Xcomponents of the token, where each component is a literal substring or
Xa list substituting a variable reference. For example:
X.PP
X.RS
X$(X) -> a b c
X.br
Xt$(X) -> ta tb tc
X.br
X$(X)z -> az bz cz
X.br
X$(X)-$(X) -> a-a a-b a-c b-a b-b b-c c-a c-b c-c
X.RE
X.PP
XThe variable name and modifiers can themselves contain a variable
Xreference, and this partakes of the product as well:
X.PP
X.RS
X$(X) -> a b c
X.br
X$(Y) -> 1 2
X.br
X$(Z) -> X Y
X.br
X$($(Z)) -> a b c 1 2
X.RE
X.PP
XBecause of this product expansion, if any variable reference in a token
Xis undefined, the result of the expansion is an empty list.
X.PP
XModifiers to a variable are of two varieties: sub-element selection and
Xfile name editing. They are:
X.PP
X.IP "[\fI<n>\fR]"
XSelect only element number \fI<n>\fR (starting at 1). If the variable contains
Xfewer than \fI<n>\fR elements, the result is a zero-element list.
X.IP "[\fI<n>\fR-\fI<m>\fR]"
XSelect only elements number \fI<n>\fR through \fI<m>\fR.
X.IP "[\fI<n>\fR-]"
XSelect only elements number \fI<n>\fR through the last.
X.IP ":G=\fI<grist>\fR"
XReplace the grist of the file name with \fI<grist>\fR.
X.IP ":D=\fI<path>\fR"
XReplace directory component of file name with \fI<path>\fR.
X.IP ":B=\fI<base>\fR"
XReplace the base part of file name with \fI<base>\fR.
X.IP ":S=\fI<suf>\fR"
XReplace the suffix of file name with \fI<suf>\fR.
X.IP ":M=\fI<mem>\fR"
XReplace the archive member name with \fI<mem>\fR.
X.IP ":R=\fI<root>\fR"
XPrepend \fI<root>\fR to the whole file name, if not already rooted.
X.IP ":\fI<components>\fR"
XRemove components not listed; components is one or more of
X\fBGDBSM\fR.
X
X.SH OPERATION
X\fBJam\fR has three phases of operation: parsing, binding, and
Xupdating.
X.SS Parsing
X.PP
X\fBJam\fR parses the \fBJambase\fR file, which includes \fBJamfile\fR.
XThe results of parsing are: the dependency graph of targets; update
Xactions associated with the targets; and variables set to specific
Xvalues.
X.PP
X.SS Binding
XAfter parsing, \fBjam\fR recursively descends the dependency graph,
Xattempting to locate each target file and determine if it is in need of
Xupdating. If \fBjam\fR detects a cycle in the graph, it issues a
Xwarning.
X.PP
XBy default, a target is located at the actual path of the target,
Xrelative to the directory of \fBjam\fR's invocation. If the special
Xvariable $(LOCATE) is set to a directory name, \fBjam\fR prepends that
Xdirectory name to the target; else if the special variable $(SEARCH) is
Xset to a directory list, \fBjam\fR searches along the directory list
Xfor the target file, and if the file is found prepends the directory
Xname to the target. If the target name has a rooted directory
Xcomponent then $(SEARCH) and $(LOCATE) do not apply: the target is
Xlocated at the actual path of the target. If a target is marked as not
Xbeing a file (using the built-in rule NOTFILE), it is left unbound to a
Xfile name.
X.PP
XAfter binding each target, \fBjam\fR determines whether the target
Xneeds updating, and marks the target if necessary for the updating
Xphase. A target is marked for updating for any of these three reasons:
X.IP
XIt is missing.
X.IP
XIts filesystem modification time is older than any of its sources.
X.IP
XAny of its sources are marked for updating.
X.PP
XThis basic behavior can be modified applying (usually one of) the
Xfollowing six built-in rules to the target:
X.RS
X.IP ALWAYS
XThe target is always updated.
X.IP LEAVES
XThe target is only updated if it is missing or if its leaf sources
Xare newer. Leaf sources are those dependencies of the target that have
Xno dependencies themselves.
X.IP NOCARE
XThe target is ignored if it is missing and has no updating actions.
XNormally, \fBjam\fR issues a warning and skips other targets that
Xdepend on missing targets without updating actions.
X.IP TEMPORARY
XIf the target is missing, then its parent's modification time is used
Xwhen comparing against sources.
X.IP NOTFILE
XThe target is only updated if any of its sources are marked for updating.
X.IP NOUPDATE
XThe target is only updated if it is missing. Also, if it exists, it
Xwill appear eternally old; that is, older than anything that depends on
Xit.
X.RE
X.PP
XIf a target is a source file that includes other files, \fBjam\fR scans
Xthe source file for header file include lines. It scans the file by
Xmatching each line against a \fBregexp\fR(3) pattern that has ()'s
Xsurrounding the included file name. The pattern is provided by the
Xuser through the special variable $(HDRSCAN) (see \fBHDRPATTERN\fR in
X\fBJambase\fR for an example). The result of the scan is formed into a
Xrule invocation, with the scanned file as the target and the found
Xincluded file names as the sources. The rule invoked is named by the
Xspecial variable $(HDRRULE). \fBJam\fR only scans files if $(HDRSCAN)
Xis set, and $(HDRSCAN) is normally set target-specific.
X.PP
XBetween binding and updating, \fBjam\fR announces the number of targets
Xto be updated.
X.SS Updating
XAfter binding, \fBjam\fR again recursively descends the dependency
Xgraph, this time executing the update actions for each target marked
Xfor update during the binding phase. If a target's updating actions
Xfail, then all targets which depend on it are skipped.
X.PP
X(UNIX only). The \fB-j\fR flag instructs \fBjam\fR to build more than
Xone target at a time. If there are multiple actions on a single
Xtarget, they are run sequentially.
X.PP
X(UNIX only). The special variable $(JAMSHELL) gives \fBjam\fR a
Xcommand execution shell to be used instead of /bin/sh. This variable's
Xvalue must be a multi-element list, corresponding to the argument
Xvector for the command shell. An element "\fB%\fR" is replaced with the
Xcommand string to execute. An element "\fB!\fR" is replaced with the
Xmultiprocess slot number, which is (inclusively) between 1 and the
Xmaximum number of concurrent jobs specified with the \fB-j\fR flag
X(default 1). If no element of the list is "\fB%\fR", the command
Xstring is tacked on as the last argument. The default value is:
X"/bin/sh -c %".
X
X.SH DIAGNOSTICS
X.PP
XIn addition to generic error messages,
X\fBjam\fR
Xmay emit one of the following:
X.PP
Xwarning: unknown rule X
X.IP
XA rule was invoked that has not been defined with
Xan "actions" or "rule" statement.
X.PP
Xusing N temp target(s)
X.IP
XTargets marked as being temporary (but nonetheless present)
Xhave been found.
X.PP
Xupdating N target(s)
X.IP
XTargets are out-of-date and will be updated.
X.PP
Xcan't find N target(s)
X.IP
XSource files can't be found and there are no actions to create them.
X.PP
Xcan't make N target(s)
X.IP
XDue to sources not being found, other targets cannot be made.
X.PP
Xwarning: X depends on itself
X.IP
XA target depends on itself either directly or through its sources.
X.PP
Xdon't know how to make X
X.IP
XA target is not present and no actions have been defined to create it.
X.PP
XX skipped for lack of Y
X.IP
XA source failed to build, and thus a target cannot be built.
X.PP
Xwarning: using independent target X
X.IP
XA target that does is not a dependency of any other target is
Xbeing referenced with $(<) or $(>).
X.PP
XX removed
X.IP
X\fBJam\fR
Xremoved a partially built target after being interrupted.
X
X.SH FILES
X/usr/local/lib/Jambase
X.br
XJamfile
X
X.SH BUGS, LIMITATIONS
X.PP
XBecause the \fBinclude\fR statement works by pushing a new file in the
Xinput stream of the scanner rather than recursively invoking the parser
Xon the new file, multiple include statements in a rule's procedure
Xcauses the files to be included in reverse order.
X.PP
XIf the \fBinclude\fR statement appears inside an \fBif\fR block, the
Xparser's attempt to find the \fBelse\fR will cause the text of the
Xincluded file to appear after the first token following the statement
Xblock. This is rarely what is intended.
X.PP
XIn a rule's actions, only $(<) and $(>) refer to the bound file names:
Xall other variable references get the unbound names.
X.PP
XWith the \fB-j\fR flag, errors from failed commands can get
Xstaggeringly mixed up. Also, because targets tend to get built in a
Xquickest-first ordering, dependency information must be quite exact.
XFinally, beware of parallelizing commands that drop fixed-named files
Xinto the current directory, like \fByacc\fR(1) does.
X.PP
XA poorly set $(JAMSHELL) is likely to result in silent failure.
X
X.SH SEE ALSO
X\fBJambase\fR(5), \fBJamfile\fR(5)
END_OF_FILE
if test 19224 -ne `wc -c <'jam.1'`; then
echo shar: \"'jam.1'\" unpacked with wrong size!
fi
# end of 'jam.1'
fi
if test -f 'jamgram.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jamgram.c'\"
else
echo shar: Extracting \"'jamgram.c'\" \(23346 characters\)
sed "s/^X//" >'jamgram.c' <<'END_OF_FILE'
Xextern char *malloc(), *realloc();
X# define _BANG 257
X# define _BANG_EQUALS 258
X# define _AMPERAMPER 259
X# define _LPAREN 260
X# define _RPAREN 261
X# define _PLUS_EQUALS 262
X# define _COLON 263
X# define _SEMIC 264
X# define _LANGLE 265
X# define _LANGLE_EQUALS 266
X# define _EQUALS 267
X# define _RANGLE 268
X# define _RANGLE_EQUALS 269
X# define _QUESTION_EQUALS 270
X# define ACTIONS 271
X# define CASE 272
X# define DEFAULT 273
X# define ELSE 274
X# define EXISTING 275
X# define FOR 276
X# define IF 277
X# define IGNORE 278
X# define IN 279
X# define INCLUDE 280
X# define ON 281
X# define PIECEMEAL 282
X# define QUIETLY 283
X# define RULE 284
X# define SWITCH 285
X# define TOGETHER 286
X# define UPDATED 287
X# define _LBRACE 288
X# define _BARBAR 289
X# define _RBRACE 290
X# define ARG 291
X# define STRING 292
X
X# line 62 "jamgram.y"
X#define yyclearin yychar = -1
X#define yyerrok yyerrflag = 0
Xextern int yychar;
Xextern int yyerrflag;
X#ifndef YYMAXDEPTH
X#define YYMAXDEPTH 150
X#endif
X#ifndef YYSTYPE
X#define YYSTYPE int
X#endif
XYYSTYPE yylval, yyval;
X# define YYERRCODE 256
Xint yyexca[] ={
X-1, 1,
X 0, -1,
X -2, 0,
X-1, 4,
X 263, 37,
X 264, 37,
X 291, 37,
X -2, 39,
X };
X# define YYNPROD 48
X# define YYLAST 173
Xint yyact[]={
X
X 10, 89, 87, 27, 32, 6, 8, 28, 25, 3,
X 21, 26, 85, 9, 7, 84, 10, 11, 39, 94,
X 4, 6, 8, 38, 93, 3, 41, 69, 79, 9,
X 7, 37, 10, 11, 90, 88, 4, 6, 8, 34,
X 33, 3, 27, 41, 83, 9, 7, 81, 10, 11,
X 63, 61, 4, 6, 8, 31, 42, 3, 92, 19,
X 41, 9, 7, 59, 18, 11, 56, 20, 4, 30,
X 58, 57, 40, 42, 55, 54, 19, 67, 60, 52,
X 2, 18, 44, 53, 20, 15, 13, 17, 68, 45,
X 46, 43, 47, 48, 5, 16, 12, 80, 29, 1,
X 0, 14, 23, 24, 22, 0, 0, 51, 0, 0,
X 70, 0, 35, 36, 0, 0, 0, 0, 0, 0,
X 24, 24, 64, 0, 0, 0, 0, 0, 49, 50,
X 0, 62, 0, 0, 65, 66, 24, 24, 73, 74,
X 75, 76, 77, 78, 71, 72, 86, 0, 0, 0,
X 0, 0, 0, 0, 91, 0, 0, 0, 0, 0,
X 0, 82, 95, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 96 };
Xint yypact[]={
X
X -1000, -223, -1000, -1000, -1000, -186, -281, -1000, -249, -284,
X -1000, -1000, -209, -287, -224, -1000, -1000, -236, -1000, -1000,
X -1000, -256, -270, -216, -176, -249, -249, -1000, -223, -212,
X -239, -1000, -1000, -1000, -1000, -214, -203, -1000, -1000, -245,
X -1000, -249, -249, -288, -288, -288, -288, -288, -288, -1000,
X -233, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
X -1000, -1000, -217, -1000, -1000, -220, -273, -278, -245, -289,
X -255, -1000, -199, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
X -291, -1000, -230, -1000, -1000, -1000, -1000, -205, -250, -1000,
X -1000, -271, -1000, -223, -1000, -223, -1000 };
Xint yypgo[]={
X
X 0, 99, 78, 69, 96, 94, 85, 77, 102, 98,
X 97, 88, 86, 83 };
Xint yyr1[]={
X
X 0, 1, 1, 3, 3, 2, 2, 2, 2, 2,
X 2, 2, 2, 2, 2, 2, 10, 2, 2, 6,
X 6, 6, 8, 8, 8, 8, 8, 8, 8, 8,
X 8, 8, 8, 7, 7, 11, 4, 12, 12, 5,
X 9, 9, 13, 13, 13, 13, 13, 13 };
Xint yyr2[]={
X
X 0, 1, 5, 1, 5, 7, 7, 11, 9, 13,
X 11, 15, 11, 11, 15, 7, 1, 11, 7, 3,
X 3, 3, 3, 7, 7, 7, 7, 7, 7, 5,
X 7, 7, 7, 1, 5, 9, 3, 1, 5, 3,
X 1, 5, 3, 3, 3, 3, 3, 3 };
Xint yychk[]={
X
X -1000, -1, -2, 280, 291, -5, 276, 285, 277, 284,
X 271, 288, -4, -12, -4, -6, 281, 273, 267, 262,
X 270, 291, -4, -8, -5, 257, 260, 291, 291, -9,
X -3, 264, 291, 264, 263, -4, -4, 267, 279, 288,
X 288, 259, 289, 267, 258, 265, 266, 268, 269, -8,
X -8, -2, 291, -13, 287, 286, 278, 283, 282, 275,
X -2, 290, -4, 264, -6, -4, -4, -7, -11, 272,
X -3, -8, -8, -5, -5, -5, -5, -5, -5, 261,
X -10, 264, -4, 264, 288, 290, -7, 291, 290, 292,
X 264, -3, 263, 274, 290, -3, -2 };
Xint yydef[]={
X
X 1, -2, 2, 37, -2, 0, 0, 37, 0, 0,
X 40, 3, 0, 36, 0, 37, 37, 0, 19, 20,
X 21, 0, 0, 0, 22, 0, 0, 39, 0, 0,
X 0, 5, 38, 6, 37, 0, 0, 37, 37,