1#
2# /+\
3# +\	Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
4# \+/
5#
6# This file is part of Jam - see jam.c for Copyright information.
7#
8
9#
10# JAMBASE - jam 2.5 ruleset providing make(1)-like functionality
11#
12# Supports UNIX, NT, and VMS.
13#
14# 12/27/93 (seiwald) - purturb library sources with SOURCE_GRIST
15# 04/18/94 (seiwald) - use '?=' when setting OS specific vars
16# 04/21/94 (seiwald) - do RmTemps together
17# 05/05/94 (seiwald) - all supported C compilers support -o: relegate
18#		       RELOCATE as an option; set Ranlib to "" to disable it
19# 06/01/94 (seiwald) - new 'actions existing' to do existing sources
20# 08/25/94 (seiwald) - new ObjectCcFlags rule to append to per-target CCFLAGS
21# 08/29/94 (seiwald) - new ObjectHdrs rule to append to per-target HDRS
22# 09/19/94 (seiwald) - LinkLibraries and Undefs now append
23#		     - Rule names downshifted.
24# 10/06/94 (seiwald) - Dumb yyacc stuff moved into Jamfile.
25# 10/14/94 (seiwald) - (Crude) support for .s, .C, .cc, .cpp, and .f files.
26# 01/08/95 (seiwald) - Shell now handled with awk, not sed
27# 01/09/95 (seiwald) - Install* now take dest directory as target
28# 01/10/95 (seiwald) - All entries sorted.
29# 01/10/95 (seiwald) - NT support moved in, with LauraW's help.  
30# 01/10/95 (seiwald) - VMS support moved in.
31# 02/06/95 (seiwald) - ObjectC++Flags and SubDirC++Flags added.
32# 02/07/95 (seiwald) - Iron out when HDRSEARCH uses "" or SEARCH_SOURCE.
33# 02/08/95 (seiwald) - SubDir works on VMS.
34# 02/14/95 (seiwald) - MkDir and entourage.
35# 04/30/95 (seiwald) - Use install -c flag so that it copies, not moves.
36# 07/10/95 (taylor) - Support for Microsoft C++.
37# 11/21/96 (peterk) - Support for BeOS
38# 07/19/99 (sickel) - Support for Mac OS X Server (and maybe client)
39# 02/18/00 (belmonte)- Support for Cygwin.
40
41# Special targets defined in this file:
42#
43# all		- parent of first, shell, files, lib, exe
44# first		- first dependent of 'all', for potential initialization
45# shell		- parent of all Shell targets 
46# files		- parent of all File targets
47# lib		- parent of all Library targets
48# exe		- parent of all Main targets
49# dirs		- parent of all MkDir targets
50# clean		- removes all Shell, File, Library, and Main targets
51# uninstall	- removes all Install targets
52#	
53
54# Rules defined by this file:
55#
56# as obj.o : source.s ;			.s -> .o
57# Bulk dir : files ;			populate directory with many files
58# Cc obj.o : source.c ;			.c -> .o
59# C++ obj.o : source.cc ;		.cc -> .o
60# Clean clean : sources ;		remove sources with 'jam clean'
61# File dest : source ;			copy file
62# Fortran obj.o : source.f ;		.f -> .o
63# GenFile source.c : program args ;	make custom file
64# HardLink target : source ;		make link from source to target
65# HdrRule source : headers ;		handle #includes
66# InstallInto dir : sources ;		install any files
67# InstallBin dir : sources ;		install binaries
68# InstallLib dir : sources ;		install files
69# InstallFile dir : sources ;		install files
70# InstallMan dir : sources ;		install man pages
71# InstallShell dir : sources ;		install shell scripts
72# Lex source.c : source.l ;		.l -> .c
73# Library lib : source ;		archive library from compiled sources
74# LibraryFromObjects lib : objects ;	archive library from objects
75# LinkLibraries images : libraries ;	bag libraries onto Mains
76# LocalClean target : deps ;	a conditional Clean
77# LocalDepends target : deps ;	a conditional Depends
78# Main image : source ;			link executable from compiled sources
79# MainFromObjects image : objects ;	link executable from objects
80# MkDir dir ;				make a directory, if not there
81# Object object : source ;		compile object from source
82# ObjectCcFlags source : flags ;	add compiler flags for object
83# ObjectC++Flags source : flags ;	add compiler flags for object
84# ObjectHdrs source : dirs ;		add include directories for object
85# Objects sources ;			compile sources
86# RmTemps target : sources ;		remove temp sources after target made
87# Setuid images ;			mark executables Setuid
88# SoftLink target : source ;		make symlink from source to target
89# SubDir TOP d1 d2 ... ;		start a subdirectory Jamfile
90# SubDirCcFlags flags ;			add compiler flags until next SubDir
91# SubDirC++Flags flags ;		add compiler flags until next SubDir
92# SubDirHdrs d1 d2 ... ;		add include dir until next SubDir
93# SubInclude TOP d1 d2 ... ;		include a subdirectory Jamfile
94# Shell exe : source ;			make a shell executable
95# Undefines images : symbols ;		save undef's for linking
96# UserObject object : source ;		handle unknown suffixes for Object
97# Yacc source.c : source.y ;		.y -> .c
98#
99# Utility rules that have no side effects (not supported):
100#
101# FAppendSuffix f1 f2 ... : $(SUF) ; 	return $(<) with suffixes
102# FDirName d1 d2 ... ;			return path from root to dir
103# FGrist d1 d2 ... ;			return d1!d2!...
104# FGristFiles value ;			return $(value:G=$(SOURCE_GRIST))
105# FGristSourceFiles value ;		return $(value:G=$(SOURCE_GRIST))
106# FIsPrefix a : b ;				return whether or not a is a prefix of b
107# FStripCommon v1 : v2 ; 		strip common initial parts of v1 v2
108# FReverse a1 a2 ... ;			return ... a2 a1 
109# FRelPath d1 : d2 ;			return rel path from d1 to d2
110# FSubDir d1 d2 ... ;			return path to root
111#
112
113
114# Brief review of the jam language:
115#
116# Statements:
117#	rule RULE - statements to process a rule
118#	actions RULE - system commands to carry out target update
119#
120# Modifiers on actions:
121#	together - multiple instances of same rule on target get executed
122#		   once with their sources ($(>)) concatenated
123#	updated - refers to updated sources ($(>)) only
124#	ignore - ignore return status of command
125#	quietly - don't trace its execution unless verbose
126#	piecemeal - iterate command each time with a small subset of $(>)
127#	existing - refers to currently existing sources ($(>)) only
128#	bind vars - subject to binding before expanding in actions
129#
130# Special rules:
131#	Always - always build a target
132#	Depends - builds the dependency graph
133#	Echo - blurt out targets on stdout
134#	Exit - blurt out targets and exit
135#	Includes - marks sources as headers for target (a codependency)
136#	NoCare - don't panic if the target can't be built
137#	NoUpdate - create the target if needed but never update it 
138#	NotFile - ignore the timestamp of the target (it's not a file)
139#	Temporary - target need not be present if sources haven't changed
140#
141# Special variables set by jam:
142#	$(<) - targets of a rule (to the left of the :)
143#	$(>) - sources of a rule (to the right of the :)
144#	$(xxx) - true on xxx (UNIX, VMS, NT, OS2, MAC)
145#	$(OS) - name of OS - varies wildly
146#	$(JAMVERSION) - version number (2.5)
147#
148# Special variables used by jam:
149#	SEARCH - where to find something (used during binding and actions)
150#	LOCATE - where to plop something not found with SEARCH
151#	HDRRULE - rule to call to handle include files
152#	HDRSCAN - egrep regex to extract include files
153#
154# Special targets:
155#	all - default if none given on command line
156#
157
158# for perforce use -- jambase version
159
160JAMBASEDATE = 2002.05.09 ;
161
162# Initialize variables
163#
164
165#
166# OS specific variable settings
167#
168
169if $(NT)
170{
171    	MV		?= move /y ;
172    	CP		?= copy ;
173    	RM		?= del /f/q ;
174	RMDIR		?= rmdir /s/q ;
175    	SLASH		?= \\ ;
176    	SUFLIB		?= .lib ;
177    	SUFOBJ		?= .obj ;
178    	SUFEXE		?= .exe ;
179     
180    if $(BCCROOT)
181    {
182	AR		?= tlib /C /P64 ;
183	CC		?= bcc32 ;
184	CCFLAGS		?= -v -w- -q -DWIN -tWR -tWM -tWC ;
185	C++		?= $(CC) ;
186	C++FLAGS	?= $(CCFLAGS) -P ;
187	LINK		?= $(CC) ;
188	LINKFLAGS	?= $(CCFLAGS) ;
189	STDLIBPATH	?= $(BCCROOT)\\lib ;
190	STDHDRS		?= $(BCCROOT)\\include ;
191	NOARSCAN	?= true ;
192    }
193    else if $(MSVC)
194    {
195	AR		?= lib /nologo ;
196	CC		?= cl /nologo ;
197	CCFLAGS		?= /D \"WIN\" ;
198	C++		?= $(CC) ;
199	C++FLAGS	?= $(CCFLAGS) ;
200	LINK		?= $(CC) ;
201	LINKFLAGS	?= $(CCFLAGS) ;
202	LINKLIBS	?= 
203				$(MSVC)\\lib\\mlibce.lib
204				$(MSVC)\\lib\\oldnames.lib
205				;
206	LINKLIBS	?= ;
207	NOARSCAN	?= true ;
208	OPTIM		?=  ;
209	STDHDRS		?= $(MSVC)\\include ;
210	UNDEFFLAG	?= "/u _" ;
211    }
212    else if $(MSVCNT) || $(MSVCDIR)
213    {
214	# Visual C++ 6.0 uses MSVCDIR
215
216	MSVCNT		?= $(MSVCDIR) ;	
217
218	# bury IA64 in the path for the SDK
219
220	local I ; if $(OSPLAT) = IA64 { I = ia64\\ ; } else { I = "" ; }
221
222	AR		?= lib ;
223	AS		?= masm386 ;
224	CC		?= cl /nologo ;
225	CCFLAGS		?= "" ;
226	C++		?= $(CC) ;
227	C++FLAGS	?= $(CCFLAGS) ;
228	LINK		?= link /nologo ;
229	LINKFLAGS	?= "" ;
230	LINKLIBS	?= 
231				$(MSVCNT)\\lib\\$(I)libc.lib
232				$(MSVCNT)\\lib\\$(I)oldnames.lib
233				$(MSVCNT)\\lib\\$(I)kernel32.lib ;
234	OPTIM		?= "" ;
235	STDHDRS		?= $(MSVCNT)\\include ;
236	UNDEFFLAG	?= "/u _" ;
237    }
238    else
239    {
240	EXIT On NT, set BCCROOT, MSVCDIR, MSVCNT, or MSVC to the root
241		of the Borland or Microsoft directories. ;
242    }
243
244}
245else if $(MINGW)
246{
247	Echo		"MingW32" ;
248
249	CC		?= gcc ;
250	C++		?= g++ ;
251	CCFLAGS 	+= -DMINGW ;
252	RANLIB		?= "ranlib" ;
253	SUFEXE		?= .exe ;
254}
255else if $(OS2)
256{
257	WATCOM		?= $(watcom) ;
258	 
259	if ! $(WATCOM)
260	{
261	    Exit On OS2, set WATCOM to the root of the Watcom directory. ;
262	}
263
264	AR		?= wlib ;
265	BINDIR		?= \\os2\\apps ;
266	CC		?= wcc386 ;
267	CCFLAGS		?= /zq /DOS2 /I$(WATCOM)\\h ; # zq=quiet
268	C++		?= wpp386 ;
269	C++FLAGS	?= $(CCFLAGS) ;
270	CP		?= copy ;
271	DOT		?= . ;
272	DOTDOT		?= .. ;
273	LINK		?= wcl386 ;
274	LINKFLAGS	?= /zq ; # zq=quiet
275	LINKLIBS	?= ;
276	MV		?= move ;
277	NOARSCAN	?= true ;
278	OPTIM		?= ;
279	RM		?= del /f ;
280	SLASH		?= \\ ;
281	STDHDRS		?= $(WATCOM)\\h ;
282	SUFEXE		?= .exe ;
283	SUFLIB		?= .lib ;
284	SUFOBJ		?= .obj ;
285	UNDEFFLAG	?= "/u _" ;
286
287}
288else if $(VMS)
289{
290	C++		?= cxx ;
291	C++FLAGS	?= ;
292	CC		?= cc ;
293	CCFLAGS		?= ;
294	CHMOD		?= set file/prot= ;
295	CP		?= copy/replace ;
296	CRELIB		?= true ;
297	DOT		?= [] ;
298	DOTDOT		?= [-] ;
299	EXEMODE		?= (w:e) ;
300	FILEMODE	?= (w:r) ;
301	HDRS		?= ;
302	LINK		?= link ;
303	LINKFLAGS	?= "" ;
304	LINKLIBS	?= ;
305	MKDIR		?= create/dir ;
306	MV		?= rename ;
307	OPTIM		?= "" ;
308	RM		?= delete ;
309	RUNVMS		?= mcr ;
310	SHELLMODE	?= (w:er) ;
311	SLASH		?= . ;
312	STDHDRS		?= decc$library_include ;
313	SUFEXE		?= .exe ;
314	SUFLIB		?= .olb ;
315	SUFOBJ		?= .obj ;
316
317	switch $(OS) 
318	{
319	case OPENVMS : CCFLAGS ?= /stand=vaxc ;
320	case VMS     : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ;
321	}
322}
323else if $(MAC)
324{
325	local OPT ;
326	
327	CW	?= "{CW}" ;
328
329	MACHDRS ?=
330		"$(UMACHDRS):Universal:Interfaces:CIncludes"
331		"$(CW):MSL:MSL_C:MSL_Common:Include"
332		"$(CW):MSL:MSL_C:MSL_MacOS:Include" ;
333
334	MACLIBS ?=
335		"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib"
336		"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib" ;
337
338	MPWLIBS ?= 
339		"$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib"
340		"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW.Lib" ;
341
342	MPWNLLIBS ?= 
343		"$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib"
344		"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW(NL).Lib" ;
345		
346	SIOUXHDRS ?= ;
347	
348	SIOUXLIBS ?= 
349		"$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_Runtime_PPC.lib"
350		"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_SIOUX_PPC.Lib" 
351		"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC.Lib" ;
352
353	C++		?= mwcppc ;
354	C++FLAGS	?= -w off ;
355	CC		?= mwcppc ;
356	CCFLAGS		?= -w off ;
357	CP		?= duplicate -y ;
358	DOT		?= ":" ;
359	DOTDOT		?= "::" ;
360	HDRS 		?= $(MACHDRS) $(MPWHDRS) ;
361	LINK		?= mwlinkppc ;
362	LINKFLAGS	?= -mpwtool -warn ;				
363	LINKLIBS 	?= $(MACLIBS) $(MPWLIBS) ;				
364	MKDIR		?= newfolder ;
365	MV		?= rename -y ;
366	NOARSCAN	?= true ;
367	OPTIM		?= ;
368	RM		?= delete -y ;
369	SLASH		?= ":" ;
370	STDHDRS		?= ; 
371	SUFLIB		?= .lib ;
372	SUFOBJ		?= .o ;
373}
374else if $(OS) = BEOS && $(OSPLAT) = PPC
375{
376	AR		?= mwld -xml -o ;
377	BINDIR		?= /boot/home/config/bin ;
378	CC		?= mwcc ;
379	CCFLAGS		?= -nosyspath ;
380	C++		?= $(CC) ;
381	C++FLAGS	?= -nosyspath ;
382	CHMOD		?= chmod ;
383	CHGRP		?= chgrp ;
384	CHOWN		?= chown ;
385	FORTRAN		?= "" ;
386	LEX		?= flex ;
387	LIBDIR		?= /boot/home/config/lib ;
388	LINK		?= mwld ;
389	LINKFLAGS	?= "" ;
390	MANDIR		?= /boot/home/config/man ;
391	NOARSCAN	?= true ;
392	RANLIB		?= ranlib ;
393	STDHDRS		?= /boot/develop/headers/posix ;
394	YACC		?= bison -y ;
395	YACCGEN		?= .c ;
396	YACCFILES	?= y.tab ;
397	YACCFLAGS	?= -d ;
398}
399else if $(OS) = BEOS
400{
401	BINDIR		?= /boot/home/config/bin ;
402	CC		?= gcc ;
403	C++		?= $(CC) ;
404	CHMOD		?= chmod ;
405	CHGRP		?= chgrp ;
406	CHOWN		?= chown ;
407	FORTRAN		?= "" ;
408	LEX		?= flex ;
409	LIBDIR		?= /boot/home/config/lib ;
410	LINK		?= gcc ;
411	MANDIR		?= /boot/home/config/man ;
412	NOARSCAN	?= true ;
413	RANLIB		?= ranlib ;
414	STDHDRS		?= /boot/develop/headers/posix ;
415	YACC		?= bison -y ;
416	YACCGEN		?= .c ;
417	YACCFILES	?= y.tab ;
418	YACCFLAGS	?= -d ;
419}
420else if $(OS) = HAIKU
421{
422	BINDIR		?= /boot/common/bin ;
423	CC		?= gcc ;
424	C++		?= $(CC) ;
425	CHMOD		?= chmod ;
426	CHGRP		?= chgrp ;
427	CHOWN		?= chown ;
428	FORTRAN		?= "" ;
429	LEX		?= flex ;
430	LIBDIR		?= /boot/common/lib ;
431	LINK		?= gcc ;
432	MANDIR		?= /boot/common/man ;
433	NOARSCAN	?= true ;
434	RANLIB		?= ranlib ;
435	STDHDRS		?= /boot/develop/headers/posix ;
436	YACC		?= bison -y ;
437	YACCGEN		?= .c ;
438	YACCFILES	?= y.tab ;
439	YACCFLAGS	?= -d ;
440}
441else if $(UNIX)
442{
443    switch $(OS)
444    {
445    case AIX :
446	LINKLIBS	?= -lbsd ;
447
448    case AMIGA :
449	CC		?= gcc ;
450	YACC		?= bison -y ;
451
452    case CYGWIN :	
453	CC		?= gcc ;
454	CCFLAGS 	+= -D__cygwin__ ;
455	LEX		?= flex ;
456	JAMSHELL	?= sh -c ;
457	RANLIB		?= "" ;
458	SUFEXE		?= .exe ;
459	YACC		?= bison -y ;
460
461    case DGUX :
462	RANLIB		?= "" ;
463	RELOCATE 	?= true ;
464
465    case HPUX :
466	RANLIB		?= "" ;
467
468    case INTERIX :
469	CC		?= gcc ;
470	JAMSHELL	?= sh -c ;
471	RANLIB		?= "" ;
472
473    case IRIX :
474	RANLIB		?= "" ;
475
476    case MPEIX :
477	CC		?= gcc ;
478	C++		?= gcc ;
479	CCFLAGS		+= -D_POSIX_SOURCE ;
480	HDRS		+= /usr/include ;
481	RANLIB		?= "" ; 
482	NOARSCAN	?= true ;
483	NOARUPDATE	?= true ;
484
485    case MVS :
486	RANLIB		?= "" ; 
487
488    case NEXT :
489	AR		?= libtool -o ;
490	RANLIB		?= "" ;
491
492    case MACOSX :
493	C++		?= c++ ;
494	MANDIR		?= /usr/local/share/man ;
495
496    case NCR :
497	RANLIB		?= "" ;
498
499    case PTX :
500	RANLIB		?= "" ;
501
502    case QNX :
503	AR		?= wlib ;
504	CC		?= cc ;
505	CCFLAGS		?= -Q ;	# quiet
506	C++		?= $(CC) ;
507	C++FLAGS	?= -Q ;	# quiet
508	LINK		?= $(CC) ;
509	LINKFLAGS	?= -Q ;	# quiet
510	NOARSCAN	?= true ;
511	RANLIB		?= "" ;
512
513    case SCO :
514	RANLIB		?= "" ;
515	RELOCATE 	?= true ;
516
517    case SINIX :
518	RANLIB		?= "" ;
519
520    case SOLARIS :
521	RANLIB		?= "" ;
522	AR		?= "/usr/ccs/bin/ar ru" ;
523
524    case UNICOS :
525	NOARSCAN 	?= true ;
526	OPTIM 		?= -O0 ;
527
528    case UNIXWARE :
529	RANLIB		?= "" ;
530	RELOCATE 	?= true ;
531    }
532
533	# UNIX defaults
534
535	CCFLAGS		?= ;
536	C++FLAGS	?= $(CCFLAGS) ;
537	CHMOD		?= chmod ;
538	CHGRP		?= chgrp ;
539	CHOWN		?= chown ;
540	LEX		?= lex ;
541	LINKFLAGS	?= $(CCFLAGS) ;
542	LINKLIBS	?= ;
543	OPTIM		?= ;
544	RANLIB		?= ranlib ;
545	YACC		?= yacc ;
546	YACCGEN		?= .c ;
547	YACCFILES	?= y.tab ;
548	YACCFLAGS	?= -d ;
549}
550
551#
552# General defaults; a lot like UNIX
553#
554
555	AR		?= ar ru ;
556	AS		?= as ;
557	ASFLAGS		?= ;
558	AWK		?= awk ;
559	BINDIR		?= /usr/local/bin ;
560	C++		?= cc ;
561	C++FLAGS	?= ;
562	CC		?= cc ;
563	CCFLAGS		?= ;
564	CP		?= cp -f ;
565	CRELIB		?= ;
566	DOT		?= . ;
567	DOTDOT		?= .. ;
568	EXEMODE		?= 711 ;
569	FILEMODE	?= 644 ;
570	FORTRAN		?= f77 ;
571	FORTRANFLAGS	?= ;
572	HDRS		?= ;
573	INSTALLGRIST	?= installed ;
574	JAMFILE		?= Jamfile ;
575	JAMRULES	?= Jamrules ;
576	LEX		?= ;
577	LIBDIR		?= /usr/local/lib ;
578	LINK		?= $(CC) ;
579	LINKFLAGS	?= ;
580	LINKLIBS	?= ;
581	LN		?= ln ;
582	MANDIR		?= /usr/local/man ;
583	MKDIR		?= mkdir ;
584	MV		?= mv -f ;
585	OPTIM		?= ;
586	RCP		?= rcp ;
587	RM		?= rm -f ;
588	RMDIR		?= $(RM) ;
589	RSH		?= rsh ;
590	SED		?= sed ;
591	SHELLHEADER	?= "#!/bin/sh" ;
592	SHELLMODE	?= 755 ;
593	SLASH		?= / ;
594	STDHDRS		?= /usr/include ;
595	SUBDIRRULES 	?= ;
596	SUBDIRRESET 	?= ASFLAGS HDRS C++FLAGS CCFLAGS ;
597	SUFEXE		?= "" ;
598	SUFLIB		?= .a ;
599	SUFOBJ		?= .o ;
600	UNDEFFLAG	?= "-u _" ;
601	YACC		?= ;
602	YACCGEN		?= ;
603	YACCFILES	?= ;
604	YACCFLAGS	?= ;
605
606	HDRPATTERN = 
607	    	"^[ 	]*#[ 	]*include[ 	]*[<\"]([^\">]*)[\">].*$" ;
608
609	OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;
610
611
612#
613# Base dependencies - first for "bootstrap" kinds of rules
614#
615
616Depends all : shell files lib exe obj ;
617Depends all shell files lib exe obj : first ;
618NotFile all first shell files lib exe obj dirs clean uninstall ;
619Always clean uninstall ;
620
621#
622# Rules
623#
624
625rule As
626{
627	Depends $(<) : $(>) ;
628	ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;
629	ASHDRS on $(<) = [ FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
630}
631
632rule Bulk
633{
634	local i ;
635
636	for i in $(>)
637	{
638	    File $(i:D=$(<)) : $(i) ;
639	}
640}
641
642rule Cc
643{
644	Depends $(<) : $(>) ;
645
646	# If the compiler's -o flag doesn't work, relocate the .o
647
648	if $(RELOCATE)
649	{
650	    CcMv $(<) : $(>) ;
651	}
652
653	# Just to clarify here: this sets the per-target CCFLAGS to
654	# be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
655	# CCHDRS and CCDEFS must be reformatted each time for some
656	# compiles (VMS, NT) that malign multiple -D or -I flags.
657
658	CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) $(OPTIM) ;
659
660	CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
661	CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
662}
663
664rule C++
665{
666	Depends $(<) : $(>) ;
667
668	if $(RELOCATE)
669	{
670	    CcMv $(<) : $(>) ;
671	}
672
673	C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) $(OPTIM) ;
674
675	CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
676	CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
677}
678
679rule Chmod
680{
681	if $(CHMOD) { Chmod1 $(<) ; }
682}
683
684rule File
685{
686	LocalDepends files : $(<) ;
687	Depends $(<) : $(>) ;
688	SEARCH on $(>) = $(SEARCH_SOURCE) ;
689	MODE on $(<) = $(FILEMODE) ;
690	Chmod $(<) ;
691}
692
693rule Fortran
694{
695	Depends $(<) : $(>) ;
696}
697
698rule GenFile 
699{
700	local _t = [ FGristSourceFiles $(<) ] ;
701	local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;
702	Depends $(_t) : $(_s) $(>[2-]) ;
703	GenFile1 $(_t) : $(_s) $(>[2-]) ;
704	LocalClean clean : $(_t) ;
705}
706
707rule GenFile1
708{
709	MakeLocate $(<) : $(LOCATE_SOURCE) ;
710	SEARCH on $(>) = $(SEARCH_SOURCE) ;
711}
712
713rule HardLink
714{
715	LocalDepends files : $(<) ;
716	Depends $(<) : $(>) ;
717	SEARCH on $(>) = $(SEARCH_SOURCE) ;
718}
719
720rule HdrRule
721{
722	# HdrRule source : headers ;
723
724	# N.B.	This rule is called during binding, potentially after
725	# the fate of many targets has been determined, and must be
726	# used with caution: don't add dependencies to unrelated
727	# targets, and don't set variables on $(<).
728
729	# Tell Jam that anything depending on $(<) also depends on $(>),
730	# set SEARCH so Jam can find the headers, but then say we don't
731	# care if we can't actually find the headers (they may have been
732	# within ifdefs),
733
734	local s = $(>:G=$(HDRGRIST:E)) ;
735
736	Includes $(<) : $(s) ;
737	SEARCH on $(s) = $(HDRSEARCH) ;
738	NoCare $(s) ;
739
740	# Propagate on $(<) to $(>)
741
742	HDRSEARCH on $(s) = $(HDRSEARCH) ;
743	HDRSCAN on $(s) = $(HDRSCAN) ;
744	HDRRULE on $(s) = $(HDRRULE) ;
745	HDRGRIST on $(s) = $(HDRGRIST) ;
746}
747
748rule InstallInto
749{
750	# InstallInto dir : sources ;
751
752	local i t ;
753
754	t = $(>:G=$(INSTALLGRIST)) ;
755
756	# Arrange for jam install
757	# Arrange for jam uninstall
758	# sources are in SEARCH_SOURCE
759	# targets are in dir
760
761	LocalDepends install : $(t) ;
762	LocalClean uninstall : $(t) ;
763	SEARCH on $(>) = $(SEARCH_SOURCE) ;
764	MakeLocate $(t) : $(<) ;
765
766	# For each source, make gristed target name
767	# and Install, Chmod, Chown, and Chgrp
768
769	for i in $(>)
770	{
771	    local tt = $(i:G=$(INSTALLGRIST)) ;
772
773	    Depends $(tt) : $(i) ;
774	    Install $(tt) : $(i) ;
775	    Chmod $(tt) ;
776
777	    if $(OWNER) && $(CHOWN) 
778	    { 
779		Chown $(tt) ;
780		OWNER on $(tt) = $(OWNER) ;
781	    }
782
783	    if $(GROUP) && $(CHGRP) 
784	    { 
785		Chgrp $(tt) ;
786		GROUP on $(tt) = $(GROUP) ;
787	    }
788	}
789}
790
791rule InstallBin
792{
793	local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;
794
795	InstallInto $(<) : $(_t) ;
796	MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ;
797}
798
799rule InstallFile
800{
801	InstallInto $(<) : $(>) ;
802	MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
803}
804
805rule InstallLib
806{
807	InstallInto $(<) : $(>) ;
808	MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
809}
810
811rule InstallMan
812{
813	# Really this just strips the . from the suffix
814
815	local i s d ;
816
817	for i in $(>)
818	{
819	    switch $(i:S)
820	    {
821	    case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;
822	    case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;
823	    case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;
824	    case .n : s = n ; case .man : s = 1 ;
825	    }
826
827	    d = man$(s) ;
828
829	    InstallInto $(d:R=$(<)) : $(i) ;
830	}
831
832	MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
833}
834
835rule InstallShell
836{
837	InstallInto $(<) : $(>) ;
838	MODE on $(>:G=$(INSTALLGRIST)) = $(SHELLMODE) ;
839}
840
841rule Lex
842{
843	LexMv $(<) : $(>) ;
844	Depends $(<) : $(>) ;
845	MakeLocate $(<) : $(LOCATE_SOURCE) ;
846	LocalClean clean : $(<) ;
847}
848
849rule Library
850{
851	LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
852	Objects $(>) ;
853}
854
855rule LibraryFromObjects
856{
857	local _i _l _s ;
858
859	# Add grist to file names
860
861	_s = [ FGristFiles $(>) ] ;
862	_l = $(<:S=$(SUFLIB)) ;
863
864	# library depends on its member objects
865
866	if $(KEEPOBJS)
867	{
868	    LocalDepends obj : $(_s) ;
869	}
870	else
871	{
872	    LocalDepends lib : $(_l) ;
873	}
874
875	# Set LOCATE for the library and its contents.  The bound
876	# value shows up as $(NEEDLIBS) on the Link actions.
877	# For compatibility, we only do this if the library doesn't
878	# already have a path.
879
880	if ! $(_l:D)
881	{
882	    MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;
883	}
884
885	if $(NOARSCAN) 
886	{ 
887	    # If we can't scan the library to timestamp its contents,
888	    # we have to just make the library depend directly on the
889	    # on-disk object files.  
890
891	    Depends $(_l) : $(_s) ;
892	}
893	else
894	{
895	    # If we can scan the library, we make the library depend
896	    # on its members and each member depend on the on-disk
897	    # object file.
898
899	    Depends $(_l) : $(_l)($(_s:BS)) ;
900
901	    for _i in $(_s)
902	    {
903		Depends $(_l)($(_i:BS)) : $(_i) ;
904	    }
905	}
906
907	LocalClean clean : $(_l) ;
908
909	if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
910
911	Archive $(_l) : $(_s) ;
912
913	if $(RANLIB) { Ranlib $(_l) ; }
914
915	# If we can't scan the library, we have to leave the .o's around.
916
917	if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; }
918}
919
920rule Link
921{
922	MODE on $(<) = $(EXEMODE) ;
923	Chmod $(<) ;
924}
925
926rule LinkLibraries
927{
928	# make library dependencies of target
929	# set NEEDLIBS variable used by 'actions Main'
930
931	local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
932
933	Depends $(_t) : $(>:S=$(SUFLIB)) ;
934	NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ;
935}
936
937rule LocalClean
938{
939	# LocalClean <targets> : <deps> ;
940	# Like Clean, but has only effect in a Jamfile in the
941	# directory or any of its subdirectories where jam has been invoked.
942
943	if [ FIsPrefix $(SUBDIR_UP) : $(SUBDIR_DOWN) ] {
944		Clean $(1) : $(2) ;
945	}
946}
947
948rule LocalDepends
949{
950	# LocalDepends <targets> : <deps> ;
951	# Like Depends, but has only effect in a Jamfile in the
952	# directory or any of its subdirectories where jam has been invoked.
953
954	if [ FIsPrefix $(SUBDIR_UP) : $(SUBDIR_DOWN) ] {
955		Depends $(1) : $(2) ;
956	}
957}
958
959rule Main
960{
961	MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
962	Objects $(>) ;
963}
964
965rule MainFromObjects
966{
967	local _s _t ;
968
969	# Add grist to file names
970	# Add suffix to exe
971
972	_s = [ FGristFiles $(>) ] ;
973	_t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
974
975	# so 'jam foo' works when it's really foo.exe
976
977	if $(_t) != $(<)
978	{
979	    Depends $(<) : $(_t) ;
980	    NotFile $(<) ;
981	}
982
983	# make compiled sources a dependency of target
984
985	LocalDepends exe : $(_t) ;
986	Depends $(_t) : $(_s) ;
987	MakeLocate $(_t) : $(LOCATE_TARGET) ;
988
989	LocalClean clean : $(_t) ;
990
991	Link $(_t) : $(_s) ;
992}
993
994rule MakeLocate
995{
996	# MakeLocate targets : directory ;
997
998	# Sets special variable LOCATE on targets, and arranges
999	# with MkDir to create target directory.
1000
1001	# Note we grist the directory name with 'dir',
1002	# so that directory path components and other
1003	# targets don't conflict.
1004
1005	if $(>)
1006	{
1007	    LOCATE on $(<) = $(>) ;
1008	    Depends $(<) : $(>[1]:G=dir) ;
1009	    MkDir $(>[1]:G=dir) ;
1010	}
1011}
1012
1013rule MkDir
1014{
1015	# MkDir directory ;
1016
1017	# Make a directory and all its parent directories.
1018
1019	# Ignore timestamps on directories: we only care if they 
1020	# exist.
1021
1022	NoUpdate $(<) ;
1023
1024	# Don't create . or any directory already created.
1025
1026	if $(<:G=) != $(DOT) && ! $($(<)-mkdir) 
1027	{
1028	    # Cheesy gate to prevent multiple invocations on same dir
1029	    # Arrange for jam dirs
1030	    # MkDir1 has the actions 
1031
1032	    $(<)-mkdir = true ;
1033	    LocalDepends dirs : $(<) ;
1034	    MkDir1 $(<) ;
1035
1036	    # Recursively make parent directories.
1037	    # $(<:P) = $(<)'s parent, & we recurse until root
1038
1039	    local s = $(<:P) ;
1040
1041	    # Don't try to create A: or A:\ on windows
1042
1043	    if $(NT)
1044	    {
1045	        switch $(s)
1046		{
1047		case *:   : s = ;
1048		case *:\\ : s = ;
1049		}
1050	    }
1051
1052	    if $(s) = $(<)
1053	    {
1054		# The parent is the same as the dir.
1055		# We're at the root, which some OS's can't stat, so we mark
1056		# it as NotFile.
1057
1058	        NotFile $(s) ;
1059	    }
1060	    else if $(s:G=)
1061	    {
1062		# There's a parent; recurse.
1063
1064		Depends $(<) : $(s) ;
1065		MkDir $(s) ;
1066	    }
1067	}
1068}
1069
1070rule Object
1071{
1072	# locate object and search for source, if wanted
1073
1074	LocalClean clean : $(<) ;
1075
1076	MakeLocate $(<) : $(LOCATE_TARGET) ;
1077	SEARCH on $(>) = $(SEARCH_SOURCE) ;
1078
1079	# Save HDRS for -I$(HDRS) on compile.
1080	# We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers
1081	# in the .c file's directory, but generated .c files (from
1082	# yacc, lex, etc) are located in $(LOCATE_TARGET), possibly
1083	# different from $(SEARCH_SOURCE).
1084
1085	HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;
1086
1087	# handle #includes for source: Jam scans for headers with
1088	# the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
1089	# with the scanned file as the target and the found headers
1090	# as the sources.  HDRSEARCH is the value of SEARCH used for
1091	# the found header files.  Finally, if jam must deal with 
1092	# header files of the same name in different directories,
1093	# they can be distinguished with HDRGRIST.
1094
1095	# $(SEARCH_SOURCE:E) is where cc first looks for #include 
1096	# "foo.h" files.  If the source file is in a distant directory, 
1097	# look there.  Else, look in "" (the current directory).
1098
1099	HDRRULE on $(>) = HdrRule ;
1100	HDRSCAN on $(>) = $(HDRPATTERN) ;
1101	HDRSEARCH on $(>) = 
1102		$(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ;
1103
1104	HDRGRIST on $(>) = $(HDRGRIST) ;
1105
1106	# propagate target specific-defines
1107
1108	DEFINES on $(<) += $(DEFINES) ;
1109
1110	# if source is not .c, generate .c with specific rule
1111
1112	switch $(>:S)
1113	{
1114	    case .asm : As $(<) : $(>) ;
1115	    case .c :	Cc $(<) : $(>) ;
1116	    case .C :	C++ $(<) : $(>) ;
1117	    case .cc :	C++ $(<) : $(>) ;
1118	    case .cpp : C++ $(<) : $(>) ;
1119	    case .f :	Fortran $(<) : $(>) ;
1120	    case .l :	Cc $(<) : $(<:S=.c) ;
1121			Lex $(<:S=.c) : $(>) ;
1122	    case .s :	As $(<) : $(>) ;
1123	    case .y :	Cc $(<) : $(<:S=$(YACCGEN)) ;
1124			Yacc $(<:S=$(YACCGEN)) : $(>) ;
1125	    case * :	UserObject $(<) : $(>) ;
1126	}
1127}
1128
1129rule ObjectCcFlags
1130{
1131	CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1132}
1133
1134rule ObjectC++Flags
1135{
1136	C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1137}
1138
1139rule ObjectDefines
1140{
1141	# must reformat CCDEFS according to current defines
1142
1143	local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;
1144
1145	DEFINES on $(s) += $(>) ;
1146	CCDEFS on $(s) = [ on $(s) FDefines $(DEFINES) ] ;
1147}
1148
1149rule ObjectHdrs
1150{
1151	# Add to HDRS for HdrScan's benefit.
1152	# must reformat CCHDRS according to headers
1153
1154	local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;
1155
1156	HDRS on $(s) += $(>) ;
1157	CCHDRS on $(s) = [ on $(s) FIncludes $(HDRS) ] ;
1158}
1159
1160rule Objects
1161{
1162	local _i ;
1163
1164	for _i in [ FGristFiles $(<) ]
1165	{
1166		Object $(_i:S=$(SUFOBJ)) : $(_i) ;
1167		LocalDepends obj : $(_i:S=$(SUFOBJ)) ;
1168	}
1169}
1170
1171rule RmTemps
1172{
1173	Temporary $(>) ;
1174}
1175
1176rule Setuid
1177{
1178	MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ;
1179}
1180
1181rule Shell
1182{
1183	LocalDepends shell : $(<) ;
1184	Depends $(<) : $(>) ;
1185	SEARCH on $(>) = $(SEARCH_SOURCE) ;
1186	MODE on $(<) = $(SHELLMODE) ;
1187	LocalClean clean : $(<) ;
1188	Chmod $(<) ;
1189}
1190
1191rule SoftLink
1192{
1193	LocalDepends files : $(<) ;
1194	Depends $(<) : $(>) ;
1195	SEARCH on $(>) = $(SEARCH_SOURCE) ;
1196	LocalClean clean : $(<) ;
1197}
1198
1199rule SubDir
1200{
1201	#
1202	# SubDir TOP d1 d2 ... ;
1203	#
1204	# Support for a project tree spanning multiple directories.
1205	#
1206	# SubDir declares a Jamfile's location in a project tree, setting
1207	# Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source
1208	# files can be found.
1209	#
1210	# TOP is a user-select variable name for root of the tree, and
1211	# d1 d2 ...  are the directory elements that lead from the root
1212	# of the tree to the directory of the Jamfile.
1213	#
1214	# TOP can be set externally, but normally the first SubDir call
1215	# computes TOP as the path up from the current directory; the
1216	# path contains one ../ for each of d1 d2 ...
1217	#
1218	# SubDir reads once the project-specific rules file Jamrules 
1219	# in the TOP directory, if present.  This can be overridden
1220	# with the variable TOPRULES.
1221	#
1222	# SubDir supports multiple, overlaid project trees:  SubDir
1223	# invocations with different TOPs can appear in the same Jamfile.
1224	# The location established by the first SubDir call is used set
1225	# the TOPs for the subsequent SubDir calls.
1226	#
1227	# SubDir's public variables:
1228	#
1229	#	$(TOP) = path from CWD to root.
1230	#	$(SUBDIR) = path from CWD to the directory SubDir names.
1231	#	$(SUBDIR_TOKENS) = path from $(TOP) to $(SUBDIR) as dir names
1232	#	$(SEARCH_SOURCE) = $(SUBDIR)
1233	#	$(LOCATE_SOURCE) = $(ALL_LOCATE_TARGET) $(SUBDIR)
1234	#	$(LOCATE_TARGET) = $(ALL_LOCATE_TARGET) $(SUBDIR)
1235	#	$(SOURCE_GRIST) = $(SUBDIR_TOKENS) with !'s 
1236	#
1237
1238	local _top = $(<[1]) ;
1239	local _tokens = $(<[2-]) ;
1240
1241	#
1242	# First time through sets up relative root and includes Jamrules.
1243	#
1244
1245	if ! $(_top)
1246	{
1247	    Exit SubDir syntax error ;
1248	}
1249
1250	if ! $($(_top)-SET)
1251	{
1252	    $(_top)-SET = true ;
1253
1254		## LOCAL CHANGE
1255		#
1256		# Needed below to reset $(_top), so that to the SubDir invoked by the
1257		# top jamfile we will include, it will appear, as if the code has
1258		# never been executed.
1259		#
1260		local _originalTop = $($(_top)) ;
1261		#
1262		## LOCAL CHANGE
1263
1264
1265	    # First time we've seen this TOP.
1266	    # We'll initialize a number of internal variables:
1267	    #
1268	    #	$(TOP-UP) = directories from ROOT to a common point
1269	    #	$(TOP-DOWN) = directories from common point to TOP
1270	    #	$(TOP-ROOT) = root directory for UP/DOWN -- normally CWD
1271	    #	$(SUBDIR_UP) = current value of $(TOP-UP)
1272	    #	$(SUBDIR_DOWN) = current value of $(TOP-DOWN)
1273	    #	$(SUBDIR_ROOT) = current value of $(TOP-ROOT)
1274	    #
1275
1276	    if $($(_top))
1277	    {
1278		# TOP externally set.
1279		# We'll ignore the relative (UP/DOWN) path that
1280		# got us here, and instead remember the hard ROOT.
1281
1282		$(_top)-UP = ;
1283		$(_top)-DOWN = ;
1284		$(_top)-ROOT = $($(_top)) ;
1285	    }
1286	    else
1287	    {
1288		# TOP not preset.
1289
1290		# Establishing a new TOP.  In the simplest case,
1291		# (SUBDIR_UP/SUBDIR_DOWN/SUBDIR_ROOT unset), it's
1292		# merely a certain number of directories down from
1293		# the current directory, and FSubDirPath will set
1294		# TOP to a path consisting of ../ for each of the
1295		# elements of _tokens, because that represents how 
1296		# far below TOP the current directory sits.
1297		#
1298		# In the more complicated case, the starting directory
1299		# isn't the directory of jam's invocation but an 
1300		# location established by previous SubDir call.  The
1301		# starting directory is SUBDIR_UP directories up from
1302		# SUBDIR_ROOT, and then SUBDIR_DOWN directories down
1303		# from that.   If SUBDIR_ROOT is not set, that means
1304		# SUBDIR_DOWN and SUBDIR_UP represent the path from
1305		# the directory of jam's invocation.
1306		#
1307		# In the most complicated case, the _tokens also 
1308		# represents directories down, because TOP is being
1309		# estalished in a directory other than TOP's root.
1310		# Hopefully, _tokens and SUBDIR_DOWN represent the
1311		# same final directory, relative to the new TOP and
1312		# the previous SubDIr's TOP.  To find the new TOP,
1313		# we have to chop off any common directories from
1314		# then ends of _tokens and SUBDIR_DOWN.  To do so,
1315		# we reverse each of them, call FStripCommon to
1316		# remove the initial common elements, and then
1317		# reverse them again.  After this process, if
1318		# both _tokens and SUBDIR_DOWN have elements, it
1319		# means the directory names estalished by the two
1320		# SubDir calls don't match, and a warning is issued.
1321		# All hell will likely break loose at this point,
1322		# since the whole SubDir scheme relies on the SubDir
1323		# calls accurately naming the current directory.
1324
1325		# Strip common trailing elements of _tokens and SUBDIR_DOWN.
1326
1327		_tokens = [ FReverse $(_tokens) ] ;
1328		SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
1329		FStripCommon _tokens : SUBDIR_DOWN ;
1330		SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
1331		_tokens = [ FReverse $(_tokens) ] ;
1332
1333		if $(SUBDIR_DOWN) && $(_tokens) 
1334		{ 
1335		    Echo Warning: SubDir $(<) misplaced! ; 
1336		}
1337
1338		# We'll remember the relative (UP/DOWN) path that
1339		# got us here, plus any hard ROOT starting point
1340		# for the UP/DOWN.  If TOP is never set externally,
1341		# ROOT will always be "" (directory of jam's invocation).
1342
1343		$(_top)-UP = $(SUBDIR_UP) $(_tokens) ;
1344		$(_top)-DOWN = $(SUBDIR_DOWN) ;
1345		$(_top)-ROOT = $(SUBDIR_ROOT:E="") ;
1346		$(_top) = [ FSubDirPath $(_top) ] ;
1347	    }
1348
1349	    # Set subdir vars for the inclusion of the Jamrules,
1350	    # just in case they have SubDir rules of their own.
1351	    # Note that SUBDIR_DOWN is empty: it's all the way
1352	    # up where the Jamrules live.  These gets overrided
1353	    # just after the inclusion.
1354
1355	    SUBDIR_UP = $($(_top)-UP) ;
1356	    SUBDIR_DOWN = ;
1357	    SUBDIR_ROOT = $($(_top)-ROOT) ;
1358
1359		## LOCAL CHANGE
1360		#
1361		# If we are the first Jamfile, we include the top Jamfile of this
1362		# tree and  stop processing.
1363		#
1364		if ! $(INVOCATION_SUBDIR_SET)
1365		{
1366			INVOCATION_SUBDIR_SET = true ;
1367			INVOCATION_SUBDIR_TOP = $($(_top)) ;
1368			INVOCATION_SUBDIR = $(_tokens) ;
1369			if $(INVOCATION_SUBDIR)
1370			{
1371				# Reset $(_top)-SET and $(_top) so that it appears as if the
1372				# code till this point has never been executed (let alone the
1373				# setting of the INVOCATION_SUBDIR_SET and INVOCATION_SUBDIR
1374				# variables).
1375				#
1376				$(_top)-SET = ;
1377				$(_top) = $(_originalTop) ;
1378
1379				include $(JAMFILE:D=$(INVOCATION_SUBDIR_TOP)) ;
1380				jumptoeof ;
1381			}
1382		}
1383		#
1384		## LOCAL CHANGE
1385
1386	    # Include $(TOPRULES) or $(TOP)/Jamrules.
1387	    # Include $(TOPRULES) if set.
1388	    # Otherwise include $(TOP)/Jamrules if present.
1389
1390	    if $($(_top)RULES) { 
1391		include $($(_top)RULES) ;
1392	    } else { 
1393		NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ;
1394		include $(JAMRULES:R=$($(_top)):G=$(_top)) ;
1395	    }
1396	}
1397
1398	# Get path from $(TOP) to named directory.
1399	# Save dir tokens for other potential uses.
1400
1401	SUBDIR_UP = $($(_top)-UP) ;
1402        SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ;
1403	SUBDIR_ROOT = $($(_top)-ROOT) ;
1404        SUBDIR_TOKENS = $(SUBDIR_DOWN) ;
1405
1406	SUBDIR = [ FSubDirPath $(<) ] ;
1407
1408	# Now set up SEARCH_SOURCE, LOCATE_TARGET, SOURCE_GRIST
1409	# These can be reset if needed.	 For example, if the source
1410	# directory should not hold object files, LOCATE_TARGET can
1411	# subsequently be redefined.
1412
1413	SEARCH_SOURCE = $(SUBDIR) ;
1414	LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
1415	LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
1416	SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ;
1417
1418	## LOCAL CHANGE -- OPT_HEADER_CACHE_EXT.  With the header
1419	# cache, we can grist all files found during a header scan
1420	# without incurring a performance penalty.
1421	#
1422	HDRGRIST = $(SOURCE_GRIST) ;
1423	#
1424	## LOCAL CHANGE
1425
1426	# Reset per-directory ccflags, hdrs, etc,
1427	# listed in SUBDIRRESET.
1428	# Note use of variable expanded assignment var
1429
1430	SUBDIR$(SUBDIRRESET) = ;
1431
1432	# Invoke user-specific SubDir extensions,
1433	# rule names listed in SUBDIRRULES.
1434	# Note use of variable expanded rule invocation
1435
1436	$(SUBDIRRULES) $(<) ;
1437}
1438
1439rule FSubDirPath
1440{
1441	# FSubDirPath TOP d1 ... ;
1442
1443	# Returns path to named directory.
1444
1445	# If jam is invoked in a subdirectory of the TOP, then we
1446	# need to prepend a ../ for every level we must climb up
1447	# (TOP-UP), and then append the directory names we must 
1448	# climb down (TOP-DOWN), plus the named directories d1 ...
1449	# If TOP was set externally, or computed from another TOP 
1450	# that was, we'll have to reroot the whole thing at TOP-ROOT.
1451
1452	local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ;
1453
1454	return $(_r:R=$($(<[1])-ROOT)) ;
1455}
1456
1457rule SubDirCcFlags
1458{
1459	SUBDIRCCFLAGS += $(<) ;
1460}
1461
1462rule SubDirC++Flags
1463{
1464	SUBDIRC++FLAGS += $(<) ;
1465}
1466
1467rule SubDirHdrs
1468{
1469	SUBDIRHDRS += [ FDirName $(<) ] ;
1470}
1471
1472rule SubInclude
1473{
1474	# SubInclude TOP d1 ... ;
1475	#
1476	# Include a subdirectory's Jamfile.
1477
1478	# We use SubDir to get there, in case the included Jamfile
1479	# either doesn't have its own SubDir (naughty) or is a subtree
1480	# with its own TOP.
1481
1482	if ! $($(<[1]))
1483	{
1484	    Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ;
1485	}
1486
1487	SubDir $(<) ;
1488
1489	include $(JAMFILE:D=$(SUBDIR)) ;
1490}
1491
1492rule SubRules
1493{
1494	# SubRules TOP d1 ... : Other-TOP ;
1495	#
1496	# Read another tree's Jamrules, by giving it's path according
1497	# to this tree and it's own name.
1498
1499	if ! $($(<[1]))
1500	{
1501	    Exit SubRules $(<[1]) without prior SubDir $(<[1]) ;
1502	}
1503
1504	SubDir $(<) ;
1505	SubDir $(>) ;
1506}
1507
1508rule Undefines
1509{
1510	UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ;
1511}
1512
1513rule UserObject
1514{
1515	Exit "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ;
1516}
1517
1518rule Yacc
1519{
1520	local _h ;
1521
1522	_h = $(<:S=.h) ;
1523
1524	# Some places don't have a yacc.
1525
1526	MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;
1527
1528	if $(YACC)
1529	{
1530	    Depends $(<) $(_h) : $(>) ;
1531	    Yacc1 $(<) $(_h) : $(>) ;
1532	    YaccMv $(<) $(_h) : $(>) ;
1533	    LocalClean clean : $(<) $(_h) ;
1534	}
1535
1536	# make sure someone includes $(_h) else it will be
1537	# a deadly independent target
1538
1539	Includes $(<) : $(_h) ;
1540}
1541
1542#
1543# Utility rules; no side effects on these
1544#
1545
1546rule FGrist
1547{
1548	return $(<:J=!) ;
1549
1550}
1551
1552rule FGristFiles 
1553{
1554	return $(<:G=$(SOURCE_GRIST:E)) ;
1555}
1556
1557rule FGristSourceFiles
1558{
1559	## LOCAL CHANGE: OPT_HEADER_CACHE_EXT
1560	# With header caching, there is no performance penalty to gristing
1561	# header files.	 It is also not correct to assume that header
1562	# files have global visibility.
1563	#
1564	# Here we comment out the old version and replace it with the new.
1565#	# Produce source file name name with grist in it, 
1566#	# if SOURCE_GRIST is set.
1567#
1568#	# Leave header files alone, because they have a global
1569#	# visibility.
1570#
1571#	if ! $(SOURCE_GRIST)
1572#	{
1573#	    return $(<) ;
1574#	}
1575#	else 
1576#	{
1577#	    local _i _o ;
1578#
1579#	    for _i in $(<)
1580#	    {
1581#		switch $(_i)
1582#		{
1583#		case *.h :	_o += $(_i) ;
1584#		case * : 	_o += $(_i:G=$(SOURCE_GRIST)) ;
1585#		}
1586#	    }
1587#
1588#	    return $(_o) ;
1589#	}
1590	return [ FGristFiles $(<) ] ;
1591	#
1592	## LOCAL CHANGE: end
1593}
1594
1595rule FIsPrefix
1596{
1597	# FIsPrefix <a> : <b> ;
1598	# Returns true, if list <a> is a prefix (a proper one or equal) of
1599	# list <b>, an empty list otherwise.
1600	local a = $(1) ;
1601	local b = $(2) ;
1602	while $(a) && $(a[1]) = $(b[1]) {
1603		a = $(a[2-]) ;
1604		b = $(b[2-]) ;
1605	}
1606
1607	if $(a) {
1608		return ;
1609	} else {
1610		return true ;
1611	}
1612}
1613
1614rule FReverse 
1615{
1616	# FReverse a1 a2 a3 ... ;
1617	# return ... a3 a2 a1 ;
1618
1619	if $(1) { return [ FReverse $(1[2-]) ] $(1[1]) ; }
1620}
1621
1622rule FSubDir
1623{
1624	# If $(>) is the path to the current directory, compute the
1625	# path (using ../../ etc) back to that root directory.
1626	# Sets result in $(<)
1627
1628	if ! $(<[1]) 
1629	{
1630	    return $(DOT) ;
1631	} 
1632	else
1633	{
1634	    local _i _d ;
1635
1636	    _d = $(DOTDOT) ;
1637
1638	    for _i in $(<[2-])
1639	    {
1640		_d = $(_d:R=$(DOTDOT)) ;
1641	    }
1642
1643	    return $(_d) ;
1644	}
1645}
1646
1647rule FStripCommon
1648{
1649	# FStripCommon v1 : v2 ;
1650
1651	# Strip common initial elements of variables v1 and v2.
1652	# Modifies the variable values themselves.
1653
1654	if $($(<)[1]) && $($(<)[1]) = $($(>)[1])
1655	{
1656	    $(<) = $($(<)[2-]) ;
1657	    $(>) = $($(>)[2-]) ;
1658	    FStripCommon $(<) : $(>) ;
1659	}
1660}
1661
1662rule FRelPath
1663{
1664	local _l _r ;
1665
1666	# first strip off common parts
1667
1668	_l = $(<) ;
1669	_r = $(>) ;
1670
1671	FStripCommon _l : _r ;
1672
1673	# now make path to root and path down
1674
1675	_l = [ FSubDir $(_l) ] ;
1676	_r = [ FDirName $(_r) ] ;
1677
1678	# Concatenate and save
1679
1680	# XXX This should be better
1681
1682	if $(_r) = $(DOT) {
1683	    return $(_l) ;
1684	} else {
1685	    return $(_r:R=$(_l)) ;
1686	}
1687}
1688
1689rule FAppendSuffix
1690{
1691       # E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;"
1692       # returns (yacc,lex,foo.bat) on Unix and 
1693       # (yacc.exe,lex.exe,foo.bat) on NT.
1694
1695	if $(>)
1696	{
1697	    local _i _o ;
1698
1699	    for _i in $(<)
1700	    {
1701		if $(_i:S)
1702		{
1703		    _o += $(_i) ;
1704		}
1705		else
1706		{
1707		    _o += $(_i:S=$(>)) ;
1708		}
1709	    }
1710	    return $(_o) ;
1711	}
1712	else
1713	{
1714	    return $(<) ;
1715	}
1716}
1717
1718#
1719# Operating system specific utility rules
1720# First, the (generic) UNIX versions
1721#
1722
1723rule FQuote { return \\\"$(<)\\\" ; }
1724rule FDefines { return -D$(<) ; }
1725rule FIncludes { return -I$(<) ; }
1726
1727rule FDirName
1728{
1729	# Turn individual elements in $(<) into a usable path.
1730
1731	local _i ;
1732	local _s = $(DOT) ;
1733
1734	for _i in $(<)
1735	{
1736	    _s = $(_i:R=$(_s)) ;
1737	}
1738
1739	return $(_s) ;
1740}
1741
1742if $(OS2)
1743{
1744	rule FQuote { return \"$(<)\" ; }
1745	rule FIncludes { return /I$(<) ; }
1746}
1747
1748else if $(NT)
1749{
1750	rule FDefines { return /D$(<) ; }
1751	rule FIncludes { return /I$(<) ; }
1752}
1753
1754else if $(MAC)
1755{
1756	rule FQuote { return \"$(<)\" ; }
1757	rule FDefines { return "-define '$(<)'" ; }
1758	rule FIncludes { return \"$(<:J=,)\" ; }
1759}
1760
1761else if $(VMS)
1762{
1763	rule FQuote { return \"\"\"$(<)\"\"\" ; }
1764	rule FDefines { return "/define=( $(<:J=,) )" ; }
1765	rule FIncludes { return "/inc=( $(<:J=,) )" ; }
1766
1767	rule FDirName
1768	{
1769		local _s _i ;
1770
1771		# Turn individual elements in $(<) into a usable path.
1772
1773		if ! $(<)
1774		{
1775		    _s = $(DOT) ;
1776		}
1777		else 
1778		{
1779		    # This handles the following cases:
1780		    # 	a -> [.a]
1781		    # 	a b c -> [.a.b.c]
1782		    # 	x: -> x:
1783		    # 	x: a -> x:[a]
1784		    # 	x:[a] b -> x:[a.b]
1785
1786		    switch $(<[1])
1787		    {
1788		    case *:* : _s = $(<[1]) ;
1789		    case \\[*\\] : _s = $(<[1]) ;
1790		    case * : _s = [.$(<[1])] ;
1791		    }
1792
1793		    for _i in [.$(<[2-])]
1794		    {
1795			_s = $(_i:R=$(_s)) ;
1796		    }
1797		}
1798
1799		return $(_s) ;
1800	}
1801}
1802
1803#
1804# Actions
1805#
1806
1807#
1808# First the defaults
1809#
1810
1811actions updated together piecemeal Archive
1812{
1813	$(AR) $(<) $(>)
1814}
1815
1816actions As
1817{
1818	$(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>)
1819}
1820
1821actions C++
1822{
1823	$(C++) -c -o $(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>)
1824}
1825
1826actions Cc
1827{
1828	$(CC) -c -o $(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)
1829}
1830
1831actions Chgrp
1832{
1833	$(CHGRP) $(GROUP) $(<)
1834}
1835
1836actions Chmod1
1837{
1838	$(CHMOD) $(MODE) $(<)
1839}
1840
1841actions Chown
1842{
1843	$(CHOWN) $(OWNER) $(<)
1844}
1845
1846actions piecemeal together existing Clean
1847{
1848	$(RM) $(>)
1849}
1850
1851actions File
1852{
1853	$(CP) $(>) $(<)
1854}
1855
1856actions GenFile1
1857{
1858	$(>[1]) $(<) $(>[2-])
1859}
1860
1861actions Fortran
1862{
1863	$(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>)
1864}
1865
1866actions HardLink
1867{
1868	$(RM) $(<) && $(LN) $(>) $(<)
1869}
1870
1871actions Install
1872{
1873	$(CP) $(>) $(<) 
1874}
1875
1876actions Lex
1877{
1878	$(LEX) $(>)
1879}
1880
1881actions LexMv
1882{
1883	$(MV) lex.yy.c $(<)
1884}
1885
1886actions Link bind NEEDLIBS
1887{
1888	$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) 
1889}
1890
1891actions MkDir1
1892{
1893	$(MKDIR) "$(<)"
1894}
1895
1896actions together Ranlib
1897{
1898	$(RANLIB) $(<)
1899}
1900
1901actions quietly updated piecemeal together RmTemps
1902{
1903	$(RM) $(>)
1904}
1905
1906actions Shell
1907{
1908	$(AWK) '
1909		NR == 1 { print "$(SHELLHEADER)" }
1910		NR == 1 && /^[#:]/ { next }
1911		/^##/ { next }
1912		{ print }
1913	' < $(>) > $(<)
1914}
1915
1916actions SoftLink
1917{
1918	$(RM) $(<) && $(LN) -s $(>) $(<)
1919}
1920
1921actions Yacc1
1922{
1923	$(YACC) $(YACCFLAGS) $(>)
1924}
1925
1926actions YaccMv
1927{
1928	$(MV) $(YACCFILES).c $(<[1])
1929	$(MV) $(YACCFILES).h $(<[2])
1930}
1931
1932#
1933# RELOCATE - for compilers with broken -o flags
1934#
1935
1936if $(RELOCATE)
1937{
1938	actions C++
1939	{
1940	$(C++) -c $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>)
1941	}
1942
1943	actions Cc
1944	{
1945	$(CC) -c $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)
1946	}
1947
1948	actions ignore CcMv
1949	{
1950	[ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)
1951	}
1952}
1953
1954#
1955# NOARUPDATE - can't update an archive
1956#
1957
1958if $(NOARUPDATE)
1959{
1960	actions Archive
1961	{
1962	$(AR) $(<) $(>)
1963	}
1964}
1965
1966#
1967# UNIX specific actions
1968#
1969
1970if $(UNIX)
1971{
1972	actions GenFile1
1973	{
1974	PATH="$PATH:."
1975	$(>[1]) $(<) $(>[2-])
1976	}
1977}
1978
1979#
1980# NT specific actions
1981#
1982
1983if $(NT) && $(MSVCNT)
1984{
1985	actions updated together piecemeal Archive
1986	{
1987	if exist $(<) set _$(<:B)_=$(<)
1988	$(AR) /out:$(<) %_$(<:B)_% $(>)
1989	}
1990
1991	actions As
1992	{
1993	$(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul;
1994	}
1995
1996	actions Cc
1997	{
1998	$(CC) /c /Fo$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) $(>)
1999	}
2000
2001	actions C++
2002	{
2003	$(C++) /c /Fo$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) /Tp$(>)
2004	}
2005
2006	actions Link bind NEEDLIBS
2007	{
2008	$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2009	}
2010}
2011else if $(NT) && $(MSVC)
2012{
2013	actions updated together piecemeal Archive
2014	{
2015	$(AR) $(<) -+$(>)
2016	}
2017
2018	actions Cc
2019	{
2020	$(CC) /c /Fo$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)
2021	}
2022
2023	actions C++
2024	{
2025	$(C++) /c /Fo$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) /Tp$(>)
2026	}
2027
2028	actions Link bind NEEDLIBS
2029	{
2030	$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2031	}
2032}
2033else if $(NT) && $(BCCROOT)
2034{
2035	actions updated together piecemeal Archive
2036	{
2037	$(AR) $(<) -+$(>)
2038	}
2039
2040	actions Link bind NEEDLIBS
2041	{
2042	$(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>)
2043	}
2044
2045	actions C++
2046	{
2047	$(C++) -c -o$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>)
2048	}
2049
2050	actions Cc
2051	{
2052	$(CC) -c -o$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)
2053	}
2054}
2055
2056#
2057# OS2 specific actions
2058#
2059
2060else if $(OS2) && $(WATCOM)
2061{
2062	actions together piecemeal Archive
2063	{
2064	$(AR) $(<) +-$(>) 
2065	}
2066
2067	actions Cc
2068	{
2069	$(CC) /Fo=$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>)
2070	}
2071
2072	actions C++
2073	{
2074	$(C++) /Fo=$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>)
2075	}
2076
2077	actions Link bind NEEDLIBS
2078	{
2079	$(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2080	}
2081
2082	actions Shell
2083	{
2084	$(CP) $(>) $(<)
2085	}
2086}
2087
2088#
2089# VMS specific actions
2090#
2091
2092else if $(VMS)
2093{
2094    actions updated together piecemeal Archive 
2095    {
2096	lib/replace $(<) $(>[1]) ,$(>[2-])
2097    }
2098
2099    actions Cc
2100    { 
2101	$(CC)/obj=$(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) $(>) 
2102    }
2103
2104    actions C++
2105    { 
2106	$(C++)/obj=$(<) $(C++FLAGS) $(CCDEFS) $(CCHDRS) $(>) 
2107    }
2108
2109    actions piecemeal together existing Clean
2110    {
2111	$(RM) $(>[1]);* ,$(>[2-]);*
2112    }
2113
2114    actions together quietly CreLib
2115    {
2116	if f$search("$(<)") .eqs. "" then lib/create $(<)
2117    }
2118
2119    actions GenFile1
2120    {
2121	mcr $(>[1]) $(<) $(>[2-])
2122    }
2123
2124    actions Link bind NEEDLIBS
2125    {
2126	$(LINK)/exe=$(<) $(LINKFLAGS) $(>:J=,) ,$(NEEDLIBS)/lib ,$(LINKLIBS)
2127    }
2128
2129    actions quietly updated piecemeal together RmTemps
2130    {
2131	$(RM) $(>[1]);* ,$(>[2-]);*
2132    }
2133
2134    actions Shell
2135    {
2136	$(CP) $(>) $(<)
2137    }
2138}
2139
2140#
2141# Mac specifc actions
2142#
2143
2144else if $(MAC)
2145{
2146    actions together Archive 
2147    {
2148	$(LINK) -library -o $(<) $(>)
2149    }
2150
2151    actions Cc
2152    {
2153	set -e MWCincludes $(CCHDRS)
2154	$(CC) -o $(<) $(CCFLAGS) $(CCDEFS) $(>) 
2155    }
2156
2157    actions C++
2158    {
2159	set -e MWCincludes $(CCHDRS)
2160	$(CC) -o $(<) $(C++FLAGS) $(CCDEFS) $(>) 
2161    }
2162
2163    actions Link bind NEEDLIBS
2164    {
2165	$(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) "$(LINKLIBS)"
2166    }
2167}
2168
2169if $(WIN98)
2170{
2171    actions existing Clean
2172    {
2173	del $(>)
2174    }
2175}
2176
2177#
2178# Backwards compatibility with jam 1, where rules were uppercased.
2179#
2180
2181rule BULK { Bulk $(<) : $(>) ; }
2182rule FILE { File $(<) : $(>) ; }
2183rule HDRRULE { HdrRule $(<) : $(>) ; }
2184rule INSTALL { Install $(<) : $(>) ; }
2185rule LIBRARY { Library $(<) : $(>) ; }
2186rule LIBS { LinkLibraries $(<) : $(>) ; }
2187rule LINK { Link $(<) : $(>) ; }
2188rule MAIN { Main $(<) : $(>) ; }
2189rule SETUID { Setuid $(<) ; }
2190rule SHELL { Shell $(<) : $(>) ; }
2191rule UNDEFINES { Undefines $(<) : $(>) ; }
2192
2193# Old INSTALL* didn't take dest directory.
2194
2195rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; }
2196rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; }
2197rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; }
2198
2199# Compatibility with jam 2.2.
2200
2201rule addDirName { $(<) += [ FDirName $(>) ] ; }
2202rule makeCommon { FStripCommon $(<) : $(>) ; }
2203rule _makeCommon { FStripCommon $(<) : $(>) ; }
2204rule makeDirName { $(<) = [ FDirName $(>) ] ; }
2205rule makeGrist { $(<) = [ FGrist $(>) ] ; }
2206rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; }
2207rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; }
2208rule makeString { $(<) = $(>:J) ; }
2209rule makeSubDir { $(<) = [ FSubDir $(>) ] ; }
2210rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; }
2211
2212#
2213# Now include the user's Jamfile.
2214#
2215
2216include $(JAMFILE) ;
2217