glob omits "." and ".."; removed built-in that will never be ported
[k8jam.git] / Jambase.ORG
blob128996f00ceeff7f1ca35586aa43b607e5170951
2 # /+\
3 #  +\    Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
4 # \+/
6 # This file is part of Jam - see jam.c for Copyright information.
10 # JAMBASE - jam 2.5 ruleset providing make(1)-like functionality
12 # Supports UNIX, NT, and VMS.
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.
41 # Special targets defined in this file:
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
54 # Rules defined by this file:
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 # Main image : source ;         link executable from compiled sources
77 # MainFromObjects image : objects ; link executable from objects
78 # MkDir dir ;               make a directory, if not there
79 # Object object : source ;      compile object from source
80 # ObjectCcFlags source : flags ;    add compiler flags for object
81 # ObjectC++Flags source : flags ;   add compiler flags for object
82 # ObjectHdrs source : dirs ;        add include directories for object
83 # Objects sources ;         compile sources
84 # RmTemps target : sources ;        remove temp sources after target made
85 # Setuid images ;           mark executables Setuid
86 # SoftLink target : source ;        make symlink from source to target
87 # SubDir TOP d1 d2 ... ;        start a subdirectory Jamfile
88 # SubDirCcFlags flags ;         add compiler flags until next SubDir
89 # SubDirC++Flags flags ;        add compiler flags until next SubDir
90 # SubDirHdrs d1 d2 ... ;        add include dir until next SubDir
91 # SubInclude TOP d1 d2 ... ;        include a subdirectory Jamfile
92 # Shell exe : source ;          make a shell executable
93 # Undefines images : symbols ;      save undef's for linking
94 # UserObject object : source ;      handle unknown suffixes for Object
95 # Yacc source.c : source.y ;        .y -> .c
97 # Utility rules that have no side effects (not supported):
99 # FAppendSuffix f1 f2 ... : $(SUF) ;    return $(<) with suffixes
100 # FDirName d1 d2 ... ;          return path from root to dir
101 # FGrist d1 d2 ... ;            return d1!d2!...
102 # FGristFiles value ;           return $(value:G=$(SOURCE_GRIST))
103 # FGristSourceFiles value ;     return $(value:G=$(SOURCE_GRIST))
104 # FStripCommon v1 : v2 ;        strip common initial parts of v1 v2
105 # FReverse a1 a2 ... ;          return ... a2 a1
106 # FRelPath d1 : d2 ;            return rel path from d1 to d2
107 # FSubDir d1 d2 ... ;           return path to root
111 # Brief review of the jam language:
113 # Statements:
114 #   rule RULE - statements to process a rule
115 #   actions RULE - system commands to carry out target update
117 # Modifiers on actions:
118 #   together - multiple instances of same rule on target get executed
119 #          once with their sources ($(>)) concatenated
120 #   updated - refers to updated sources ($(>)) only
121 #   ignore - ignore return status of command
122 #   quietly - don't trace its execution unless verbose
123 #   piecemeal - iterate command each time with a small subset of $(>)
124 #   existing - refers to currently existing sources ($(>)) only
125 #   bind vars - subject to binding before expanding in actions
127 # Special rules:
128 #   Always - always build a target
129 #   Depends - builds the dependency graph
130 #   Echo - blurt out targets on stdout
131 #   Exit - blurt out targets and exit
132 #   Includes - marks sources as headers for target (a codependency)
133 #   NoCare - don't panic if the target can't be built
134 #   NoUpdate - create the target if needed but never update it
135 #   NotFile - ignore the timestamp of the target (it's not a file)
136 #   Temporary - target need not be present if sources haven't changed
138 # Special variables set by jam:
139 #   $(<) - targets of a rule (to the left of the :)
140 #   $(>) - sources of a rule (to the right of the :)
141 #   $(xxx) - true on xxx (UNIX, VMS, NT, OS2, MAC)
142 #   $(OS) - name of OS - varies wildly
143 #   $(JAMVERSION) - version number (2.5)
145 # Special variables used by jam:
146 #   SEARCH - where to find something (used during binding and actions)
147 #   LOCATE - where to plop something not found with SEARCH
148 #   HDRRULE - rule to call to handle include files
149 #   HDRSCAN - egrep regex to extract include files
151 # Special targets:
152 #   all - default if none given on command line
155 # for perforce use -- jambase version
157 JAMBASEDATE = 2004.10.07 ;
159 # Initialize variables
163 # OS specific variable settings
166 if $(NT)
168     # the list of supported toolsets on Windows NT and Windows 95/98
169     #
170     local SUPPORTED_TOOLSETS = BORLANDC
171                                VISUALC
172                                VISUALC16
173                                INTELC
174                                WATCOM
175                                MINGW
176                                LCC
177                                DIGITALMARS
178                                PELLESC
179                                ;
181     # if the JAM_TOOLSET environment variable is defined, check that it is
182     # one of our supported values
183     #
184     if $(JAM_TOOLSET)
185     {
186         if ! $(JAM_TOOLSET) in $(SUPPORTED_TOOLSETS)
187         {
188             Echo  "The JAM_TOOLSET environment variable is defined but its value" ;
189             Echo  "is invalid, please use one of the following:" ;
190             Echo  ;
192             for t in $(SUPPORTED_TOOLSETS) { Echo "  " $(t) ; }
193             Exit ;
194         }
195     }
197     # if JAM_TOOLSET is empty, we'll try to detect the toolset from other
198     # environment variables to remain backwards compatible with Jam 2.5
199     #
200     if ! $(JAM_TOOLSET)
201     {
202         if $(BCCROOT)
203         {
204             JAM_TOOLSET  = BORLANDC ;
205             BORLANDC     = $(BCCROOT) ;
206         }
207         else if $(MSVC)
208         {
209             JAM_TOOLSET = VISUALC16 ;
210             VISUALC16   = $(MSVC) ;
211         }
212         else if $(MSVCNT)
213         {
214             JAM_TOOLSET = VISUALC ;
215             VISUALC     = $(MSVCNT) ;
216         }
217         else if $(MINGW)
218         {
219             # MINGW is defined when trying to compile FT-Jam with
220             # classic Jam
221             #
222             JAM_TOOLSET = MINGW ;
223         }
224         else
225         {
226             Echo  "Jam cannot be run because you didn't indicate which compilation toolset" ;
227             Echo  "to use. To do so, define the JAM_TOOLSET environment variable with" ;
228             Echo  "one of the following values:" ;
229             Echo  ;
230             Echo  "   Value       Toolset Description" ;
231             Echo  ;
232             Echo  "   BORLANDC     Borland C++" ;
233             Echo  "   VISUALC      Microsoft Visual C++" ;
234             Echo  "   VISUALC16    Microsoft Visual C++ 16 bit" ;
235             Echo  "   INTELC       Intel C/C++" ;
236             Echo  "   WATCOM       Watcom C/C++" ;
237             Echo  "   MINGW        MinGW (gcc)" ;
238             Echo  "   LCC          Win32-LCC" ;
239             Echo  "   DIGITALMARS  Digital Mars C/C++" ;
240             Echo  "   PELLESC      Pelles C" ;
241             Echo  ;
242             Echo  "The corresponding compiler must be in your path" ;
243             Echo  ;
244             Echo  "  e.g.:  set JAM_TOOLSET=VISUALC" ;
245             Exit  ;
246         }
247     }
249     MV      ?= move /y ;
250     CP      ?= copy ;
251     RM      ?= del /f/q ;
252     RMDIR       ?= rmdir /s/q ;
253     SLASH   ?= \\ ;
254     SUFLIB  ?= .lib ;
255     SUFOBJ  ?= .obj ;
256     SUFEXE  ?= .exe ;
258     SUFLIBSHR ?= .dll ;
260     if $(JAM_TOOLSET) = BORLANDC
261     {
262         Echo "Compiler is Borland C++" ;
264         AR          ?= tlib /C /P64 ;
265         CC          ?= bcc32 ;
266         CCFLAGS     ?= -w- -q -DWIN -tWR -tWM -tWC ;
267         C++         ?= $(CC) ;
268         C++FLAGS    ?= $(CCFLAGS) -P ;
269         LINK        ?= $(CC) ;
270         ILINK       ?= ilink32 -q ;
271         IMPLIB      ?= implib ;
272         LINKFLAGS   ?= $(CCFLAGS) ;
273         STDLIBPATH  ?= $(BORLANDC)\\lib ;
274         STDHDRS     ?= $(BORLANDC)\\include ;
275         NOARSCAN    ?= true ;
276         ILINKLIBS   ?= C0D32.OBJ CW32.LIB IMPORT32.LIB ;
277         PICFLAGS    ?= -tWD ;
278     }
279     else if $(JAM_TOOLSET) = VISUALC16
280     {
281         Echo "Compiler is Microsoft Visual C++ 16 bit" ;
283         AR      ?= lib /nologo ;
284         CC      ?= cl /nologo ;
285         CCFLAGS     ?= /D "\"WIN\"" ;
286         C++     ?= $(CC) ;
287         C++FLAGS    ?= $(CCFLAGS) ;
288         LINK        ?= $(CC) ;
289         LINKFLAGS   ?= $(CCFLAGS) ;
290         LINKLIBS    ?=
291                 $(MSVC)\\lib\\mlibce.lib
292                 $(MSVC)\\lib\\oldnames.lib
293             ;
294         LINKLIBS    ?= ;
295         NOARSCAN    ?= true ;
296         OPTIM       ?= "" ;
297         STDHDRS     ?= $(VISUALC16)\\include ;
298         UNDEFFLAG   ?= "/u _" ;
299     }
300         else if $(JAM_TOOLSET) = VISUALC
301     {
302         # Visual C++ 6.0 uses MSVCDIR
304         MSVCNT      ?= $(MSVCDIR) ;
306         # bury IA64 in the path for the SDK
308         local I ; if $(OSPLAT) = IA64 { I = ia64\\ ; } else { I = "" ; }
310         AR          ?= lib ;
311         AS          ?= masm386 ;
312         CC          ?= cl /nologo ;
313         CCFLAGS     ?= "" ;
314         C++         ?= $(CC) ;
315         C++FLAGS    ?= $(CCFLAGS) ;
316         LINK        ?= link /nologo ;
317         LINKFLAGS   ?= "" ;
318         LINKLIBS    ?=
319                 $(MSVCNT)\\lib\\$(I)libc.lib
320                 $(MSVCNT)\\lib\\$(I)oldnames.lib
321                 $(MSVCNT)\\lib\\$(I)kernel32.lib ;
322         OPTIM       ?= "" ;
323         STDHDRS     ?= $(VISUALC)\\include ;
324         UNDEFFLAG   ?= "/u _" ;
325     }
326     else if $(JAM_TOOLSET) = INTELC
327     {
328         Echo "Compiler is Intel C/C++" ;
330         if ! $(VISUALC)
331         {
332             Echo "As a special exception, when using the Intel C++ compiler, you need" ;
333             Echo "to define the VISUALC environment variable to indicate the location" ;
334             Echo "of your Visual C++ installation. Aborting.." ;
335             Exit ;
336         }
338         AR          ?= lib ;
339         AS          ?= masm386 ;
340         CC          ?= icl /nologo ;
341         CCFLAGS     ?= "" ;
342         C++         ?= $(CC) ;
343         C++FLAGS    ?= $(CCFLAGS) ;
344         LINK        ?= link /nologo ;
345         LINKFLAGS   ?= "" ;
346         LINKLIBS    ?= $(VISUALC)\\lib\\advapi32.lib
347                $(VISUALC)\\lib\\libc.lib
348                $(VISUALC)\\lib\\oldnames.lib
349                $(VISUALC)\\lib\\kernel32.lib ;
350         OPTIM       ?= "" ;
351         STDHDRS     ?= $(INTELC)\include $(VISUALC)\\include ;
352         UNDEFFLAG   ?= "/u _" ;
353     }
354     else if $(JAM_TOOLSET) = WATCOM
355     {
356         Echo "Compiler is Watcom C/C++" ;
358         AR          ?= wlib ;
359         CC          ?= wcc386 ;
360         CCFLAGS     ?= /zq /DWIN32 /I$(WATCOM)\\h ; # zq=quiet
361         C++         ?= wpp386 ;
362         C++FLAGS    ?= $(CCFLAGS) ;
363         CP          ?= copy ;
364         DOT         ?= . ;
365         DOTDOT      ?= .. ;
366         LINK        ?= wcl386 ;
367         LINKFLAGS   ?= /zq ; # zq=quiet
368         LINKLIBS    ?= ;
369         MV          ?= move ;
370         NOARSCAN    ?= true ;
371         OPTIM       ?= ;
372         RM          ?= del /f ;
373         SLASH       ?= \\ ;
374         STDHDRS     ?= $(WATCOM)\\h $(WATCOM)\\h\\nt ;
375         SUFEXE      ?= .exe ;
376         SUFLIB      ?= .lib ;
377         SUFOBJ      ?= .obj ;
378         UNDEFFLAG   ?= "/u _" ;
379         PICFLAGS     = -s ;  # disable stack checks
380     }
381     else if $(JAM_TOOLSET) = MINGW
382     {
383         Echo "Compiler is GCC with Mingw" ;
385         AR              ?= ar -ru ;
386         CC              ?= gcc ;
387         CCFLAGS         ?= "" ;
388         C++             ?= $(CC) ;
389         C++FLAGS        ?= $(CCFLAGS) ;
390         LINK            ?= $(CC) ;
391         LINKFLAGS       ?= "" ;
392         LINKLIBS        ?= "" ;
393         OPTIM           ?= ;
394         SUFOBJ           = .o ;
395         SUFLIB           = .a ;
396         SLASH            = / ;
397 #       NOARSCAN        ?= true ;
398     }
399     else if $(JAM_TOOLSET) = LCC
400     {
401         Echo "Compiler is Win32-LCC" ;
403         AR              ?= lcclib ;
404         CC              ?= lcc ;
405         CCFLAGS         ?= "" ;
406         C++             ?= $(CC) ;
407         C++FLAGS        ?= $(CCFLAGS) ;
408         LINK            ?= lcclnk ;
409         LINKFLAGS       ?= "" ;
410         LINKLIBS        ?= "" ;
411         OPTIM           ?= ;
412         NOARSCAN         = true ;
413     }
414     else if $(JAM_TOOLSET) = DIGITALMARS
415     {
416         Echo "Compiler is Digital Mars C/C++" ;
418         AR              ?= lib -c ;
419         CC              ?= dmc ;
420         CCFLAGS         ?= "" ;
421         C++             ?= $(CC) ;
422         C++FLAGS        ?= $(CCFLAGS) ;
423         LINK            ?= link /nologo ;
424         LINKFLAGS       ?= "/EXETYPE:NT /NOMAP" ;
425         LINKLIBS        ?= USER32.LIB
426                            KERNEL32.LIB
427                            GDI32.LIB ;
428         OPTIM           ?= ;
429         NOARSCAN         = true ;
430         PICFLAGS         = -mn -WD ;
431     }
432     else if $(JAM_TOOLSET) = PELLESC
433     {
434         Echo "Compiler is PellesC" ;
436         AR        ?= polib ;
437         CC        ?= pocc ;
438         CCFLAGS   ?= "" ;
439         LINK      ?= polink ;
440         LINKFLAGS ?= ;
441         LINKLIBS  ?= ;
442         OPTIM     ?= ;
443         NOARSCAN   = true ;
444         LINKLIBS  ?=
445                 crt.lib oldnames.lib Win\\kernel32.lib ;
446     }
447     else
448     {
450 # XXX: We need better comments here !!
452         Exit "On NT, set BCCROOT, MSVCNT, MINGW or MSVC to the root of the"
453              "Borland or Microsoft directories." ;
454     }
456     STDHRS ?= "" ;
458 else if $(OS2)
460     # the list of supported toolsets on OS/2
461     #
462     local SUPPORTED_TOOLSETS = "EMX" "WATCOM" ;
464     # this variable holds the current toolset
465     #
466     TOOLSET = "" ;
468     # if the JAM_TOOLSET environment variable is defined, check that it is
469     # one of our supported values
470     #
471     if $(JAM_TOOLSET)
472     {
473         if ! $(JAM_TOOLSET) in $(SUPPORTED_TOOLSETS)
474         {
475             Echo  "The JAM_TOOLSET environment variable is defined but its value" ;
476             Echo  "is invalid, please use one of the following:" ;
477             Echo  ;
479             for t in $(SUPPORTED_TOOLSETS) { Echo "  " $(t) ; }
480             Exit ;
481         }
482     }
484     # if TOOLSET is empty, we'll try to detect the toolset from other
485     # environment variables to remain backwards compatible with Jam 2.3
486     #
487     if ! $(JAM_TOOLSET)
488     {
489         if $(watcom)
490         {
491             WATCOM   = $(watcom) ;
492             TOOLSET  = WATCOM ;
493         }
494         else
495         {
496             Echo  "Jam cannot be run because you didn't indicate which compilation toolset" ;
497             Echo  "to use. To do so, follow these simple instructions:" ;
498             Echo  ;
499             Echo  "  - define one of the following environment variable, with the" ;
500             Echo  "    appropriate value according to this list:" ;
501             Echo  ;
502             Echo  "   Variable    Toolset                      Description" ;
503             Echo  ;
504             Echo  "   WATCOM      Watcom C/C++                 Watcom install path" ;
505             Echo  "   EMX         EMX (gcc)                    EMX install path" ;
506 ############Echo  "   VISUALAGE   IBM Visual Age C/C++         VisualAge install path" ;
507             Echo  ;
508             Echo  "  - define the JAM_TOOLSET environment variable with the *name*" ;
509             Echo  "    of the toolset variable you want to use." ;
510             Echo  ;
511             Echo  "  e.g.:  set WATCOM=C:\WATCOM" ;
512             Echo  "         set JAM_TOOLSET=WATCOM" ;
513             Echo  ;
514             Exit  ;
515         }
516     }
518     RM       = del /f ;
519     CP       = copy ;
520     MV      ?= move ;
521     DOT     ?= . ;
522     DOTDOT  ?= .. ;
523     SUFLIB  ?= .lib ;
524     SUFOBJ  ?= .obj ;
525     SUFEXE  ?= .exe ;
527     SUFLIBSHR ?= .dll ;
529     if $(JAM_TOOLSET) = WATCOM
530     {
531         AR          ?= wlib ;
532         BINDIR      ?= \\os2\\apps ;
533         CC          ?= wcc386 ;
534         CCFLAGS     ?= /zq /DOS2 /I$(WATCOM)\\h ; # zq=quiet
535         C++         ?= wpp386 ;
536         C++FLAGS    ?= $(CCFLAGS) ;
537         CP          ?= copy ;
538         DOT         ?= . ;
539         DOTDOT      ?= .. ;
540         LINK        ?= wcl386 ;
541         LINKFLAGS   ?= /zq ; # zq=quiet
542         LINKLIBS    ?= ;
543         MV          ?= move ;
544         NOARSCAN    ?= true ;
545         OPTIM       ?= ;
546         RM          ?= del /f ;
547         SLASH       ?= \\ ;
548         STDHDRS     ?= $(WATCOM)\\h ;
549         SUFEXE      ?= .exe ;
550         SUFLIB      ?= .lib ;
551         SUFOBJ      ?= .obj ;
552         UNDEFFLAG   ?= "/u _" ;
553     }
554     else if $(JAM_TOOLSET) = EMX
555     {
556         Echo "Compiler is GCC-EMX" ;
557         AR            ?= ar -ru ;
558         CC            ?= gcc ;
559         CCFLAGS       ?= "" ;
560         C++           ?= $(CC) ;
561         C++FLAGS      ?= $(CCFLAGS) ;
562         LINK          ?= $(CC) ;
563         LINKFLAGS     ?= "" ;
564         LINKLIBS      ?= "" ;
565         OPTIM         ?= ;
566         SUFOBJ         = .o ;
567         SUFLIB         = .a ;
568         UNDEFFLAG     ?= "-U" ;
569         SLASH          = / ;
570     }
571     else
572     {
573         # should never happen
574         Exit  "Sorry, but the $(JAM_TOOLSET) toolset isn't supported for now" ;
575     }
577 else if $(VMS)
579     C++     ?= cxx ;
580     C++FLAGS    ?= ;
581     CC      ?= cc ;
582     CCFLAGS     ?= ;
583     CHMOD       ?= set file/prot= ;
584     CP      ?= copy/replace ;
585     CRELIB      ?= true ;
586     DOT     ?= [] ;
587     DOTDOT      ?= [-] ;
588     EXEMODE     ?= (w:e) ;
589     FILEMODE    ?= (w:r) ;
590     HDRS        ?= ;
591     LINK        ?= link ;
592     LINKFLAGS   ?= "" ;
593     LINKLIBS    ?= ;
594     MKDIR       ?= create/dir ;
595     MV      ?= rename ;
596     OPTIM       ?= "" ;
597     RM      ?= delete ;
598     RUNVMS      ?= mcr ;
599     SHELLMODE   ?= (w:er) ;
600     SLASH       ?= . ;
601     STDHDRS     ?= decc$library_include ;
602     SUFEXE      ?= .exe ;
603     SUFLIB      ?= .olb ;
604     SUFOBJ      ?= .obj ;
606     switch $(OS)
607     {
608     case OPENVMS : CCFLAGS ?= /stand=vaxc ;
609     case VMS     : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ;
610     }
612 else if $(MAC)
614     local OPT ;
616     CW  ?= "{CW}" ;
618     MACHDRS ?=
619         "$(UMACHDRS):Universal:Interfaces:CIncludes"
620         "$(CW):MSL:MSL_C:MSL_Common:Include"
621         "$(CW):MSL:MSL_C:MSL_MacOS:Include" ;
623     MACLIBS ?=
624         "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib"
625         "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib" ;
627     MPWLIBS ?=
628         "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib"
629         "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW.Lib" ;
631     MPWNLLIBS ?=
632         "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib"
633         "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW(NL).Lib" ;
635     SIOUXHDRS ?= ;
637     SIOUXLIBS ?=
638         "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_Runtime_PPC.lib"
639         "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_SIOUX_PPC.Lib"
640         "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC.Lib" ;
642     C++     ?= mwcppc ;
643     C++FLAGS    ?= -w off ;
644     CC      ?= mwcppc ;
645     CCFLAGS     ?= -w off ;
646     CP      ?= duplicate -y ;
647     DOT     ?= ":" ;
648     DOTDOT      ?= "::" ;
649     HDRS        ?= $(MACHDRS) $(MPWHDRS) ;
650     LINK        ?= mwlinkppc ;
651     LINKFLAGS   ?= -mpwtool -warn ;
652     LINKLIBS    ?= $(MACLIBS) $(MPWLIBS) ;
653     MKDIR       ?= newfolder ;
654     MV      ?= rename -y ;
655     NOARSCAN    ?= true ;
656     OPTIM       ?= ;
657     RM      ?= delete -y ;
658     SLASH       ?= ":" ;
659     STDHDRS     ?= ;
660     SUFLIB      ?= .lib ;
661     SUFOBJ      ?= .o ;
663 else if $(OS) = BEOS && $(OSPLAT) = PPC
665     AR      ?= mwld -xml -o ;
666     BINDIR      ?= /boot/home/config/bin ;
667     CC      ?= mwcc ;
668     CCFLAGS     ?= -nosyspath ;
669     C++     ?= $(CC) ;
670     C++FLAGS    ?= -nosyspath ;
671     CHMOD       ?= chmod ;
672     CHGRP       ?= chgrp ;
673     CHOWN       ?= chown ;
674     FORTRAN     ?= "" ;
675     LEX     ?= flex ;
676     LIBDIR      ?= /boot/home/config/lib ;
677     LINK        ?= mwld ;
678     LINKFLAGS   ?= "" ;
679     MANDIR      ?= /boot/home/config/man ;
680     NOARSCAN    ?= true ;
681     RANLIB      ?= ranlib ;
682     STDHDRS     ?= /boot/develop/headers/posix ;
683     YACC        ?= bison -y ;
684     YACCGEN     ?= .c ;
685     YACCFILES   ?= y.tab ;
686     YACCFLAGS   ?= -d ;
688 else if $(OS) = BEOS
690     BINDIR      ?= /boot/home/config/bin ;
691     CC      ?= gcc ;
692     C++     ?= $(CC) ;
693     CHMOD       ?= chmod ;
694     CHGRP       ?= chgrp ;
695     CHOWN       ?= chown ;
696     FORTRAN     ?= "" ;
697     LEX     ?= flex ;
698     LIBDIR      ?= /boot/home/config/lib ;
699     LINK        ?= gcc ;
700     MANDIR      ?= /boot/home/config/man ;
701     NOARSCAN    ?= true ;
702     RANLIB      ?= ranlib ;
703     STDHDRS     ?= /boot/develop/headers/posix ;
704     YACC        ?= bison -y ;
705     YACCGEN     ?= .c ;
706     YACCFILES   ?= y.tab ;
707     YACCFLAGS   ?= -d ;
709 else if $(UNIX)
711     switch $(OS)
712     {
713     case AIX :
714     LINKLIBS    ?= -lbsd ;
716     case AMIGA :
717     CC      ?= gcc ;
718     YACC        ?= bison -y ;
720     case CYGWIN :
721     CC      ?= gcc ;
722     CCFLAGS     += -D__cygwin__ ;
723     LEX     ?= flex ;
724     JAMSHELL    ?= sh -c ;
725     RANLIB      ?= "" ;
726     SUFEXE      ?= .exe ;
727     YACC        ?= bison -y ;
729     case DGUX :
730     RANLIB      ?= "" ;
731     RELOCATE    ?= true ;
733     case HPUX :
734     RANLIB      ?= "" ;
736     case INTERIX :
737     CC      ?= gcc ;
738     JAMSHELL    ?= sh -c ;
739     RANLIB      ?= "" ;
741     case IRIX :
742     RANLIB      ?= "" ;
744     case MPEIX :
745     CC      ?= gcc ;
746     C++     ?= gcc ;
747     CCFLAGS     += -D_POSIX_SOURCE ;
748     HDRS        += /usr/include ;
749     RANLIB      ?= "" ;
750     NOARSCAN    ?= true ;
751     NOARUPDATE  ?= true ;
753     case MVS :
754     RANLIB      ?= "" ;
756     case NEXT :
757     AR      ?= libtool -o ;
758     RANLIB      ?= "" ;
760     case MACOSX :
761     C++     ?= c++ ;
762     MANDIR      ?= /usr/local/share/man ;
764     case NCR :
765     RANLIB      ?= "" ;
767     case PTX :
768     RANLIB      ?= "" ;
770     case QNX :
771     AR      ?= wlib ;
772     CC      ?= cc ;
773     CCFLAGS     ?= -Q ; # quiet
774     C++     ?= $(CC) ;
775     C++FLAGS    ?= -Q ; # quiet
776     LINK        ?= $(CC) ;
777     LINKFLAGS   ?= -Q ; # quiet
778     NOARSCAN    ?= true ;
779     RANLIB      ?= "" ;
781     case SCO :
782     RANLIB      ?= "" ;
783     RELOCATE    ?= true ;
785     case SINIX :
786     RANLIB      ?= "" ;
788     case SOLARIS :
789     RANLIB      ?= "" ;
790     AR      ?= "/usr/ccs/bin/ar ru" ;
792     case UNICOS :
793     NOARSCAN    ?= true ;
794     OPTIM       ?= -O0 ;
796     case UNIXWARE :
797     RANLIB      ?= "" ;
798     RELOCATE    ?= true ;
799     }
801     # UNIX defaults
803     CCFLAGS     ?= ;
804     C++FLAGS    ?= $(CCFLAGS) ;
805     CHMOD       ?= chmod ;
806     CHGRP       ?= chgrp ;
807     CHOWN       ?= chown ;
808     LEX         ?= lex ;
809     LINKFLAGS   ?= $(CCFLAGS) ;
810     LINKLIBS    ?= ;
811     #OPTIM       ?= -O ;  # k8: was -O
812     RANLIB      ?= ranlib ;
813     YACC        ?= yacc ;
814     YACCGEN     ?= .c ;
815     YACCFILES   ?= y.tab ;
816     YACCFLAGS   ?= -d ;
818     SUFOBJSHR   ?= .lo ;
819     SUFLIBSHR   ?= .la ;
820     PICFLAGS    ?= -fpic ;
821     STDHDRS     ?= /usr/include ;
824 # shared library object file suffix. We assume that it is identical
825 # than the normal one
826 SUFOBJSHR ?= $(SUFOBJ) ;
827 SUFLIBSHR ?= $(SUFLIB) ;
830 # the D compiler
831 DC ?= dmd ;
834 # General defaults; a lot like UNIX
837     AR      ?= ar ru ;
838     AS      ?= as ;
839     ASFLAGS     ?= ;
840     AWK     ?= awk ;
841     BINDIR      ?= /usr/local/bin ;
842     C++     ?= g++ ;  # k8: was cc
843     C++FLAGS    ?= ;
844     CC      ?= gcc ;  # k8: was cc
845     CCFLAGS     ?= ;
846     CP      ?= cp -f ;
847     CRELIB      ?= ;
848     DOT     ?= . ;
849     DOTDOT      ?= .. ;
850     EXEMODE     ?= 711 ;
851     FILEMODE    ?= 644 ;
852     FORTRAN     ?= f77 ;
853     FORTRANFLAGS    ?= ;
854     HDRS        ?= ;
855     INSTALLGRIST    ?= installed ;
856     JAMFILE     ?= Jamfile ;
857     JAMRULES    ?= Jamrules ;
858     LEX     ?= ;
859     LIBDIR      ?= /usr/local/lib ;
860     LINK        ?= $(CC) ;
861     LINKFLAGS   ?= ;
862     LINKLIBS    ?= ;
863     LN      ?= ln ;
864     MANDIR      ?= /usr/local/man ;
865     MKDIR       ?= mkdir ;
866     MV      ?= mv -f ;
867     OPTIM       ?= ;
868     RCP     ?= rcp ;
869     RM      ?= rm -f ;
870     RMDIR       ?= $(RM) ;
871     RSH     ?= rsh ;
872     SED     ?= sed ;
873     SHELLHEADER ?= "#!/bin/sh" ;
874     SHELLMODE   ?= 755 ;
875     SLASH       ?= / ;
876     SUBDIRRULES     ?= ;
877     SUBDIRRESET     ?= ASFLAGS HDRS C++FLAGS CCFLAGS ;
878     SUFEXE      ?= "" ;
879     SUFLIB      ?= .a ;
880     SUFOBJ      ?= .o ;
881     UNDEFFLAG   ?= "-u _" ;
882     YACC        ?= ;
883     YACCGEN     ?= ;
884     YACCFILES   ?= ;
885     YACCFLAGS   ?= ;
887     HDRPATTERN =
888             "^[   ]*#[  ]*include[  ]*[<\"]([^\">]*)[\">].*$" ;
890     OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;
894 # Base dependencies - first for "bootstrap" kinds of rules
897 Depends all : shell files lib exe obj ;
898 Depends all shell files lib exe obj : first ;
899 NotFile all first shell files lib exe obj dirs clean uninstall ;
900 Always  clean uninstall ;
903 # Rules
906 # /As object : source ;
908 # Assemble the file _source_, called by the @Object rule.
910 # Do not call this rule directly, since _object_ and _source_ may have
911 # have platform-specific file extensions
913 rule As
915     Depends $(<) : $(>) ;
916     ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;
917     ASHDRS on $(<) = [ FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
920 # /Bulk  directory : sources ;
922 # Copies _sources_ into _directory_
924 rule Bulk
926     local i ;
928     for i in $(>)
929     {
930         File $(i:D=$(<)) : $(i) ;
931     }
935 # /Dc object : source ;
937 # Compile the file source into object, usin the D compiler $(DC), its
938 # flags $(DCFLAGS) and $(DOPTIM)
939 # Called by the @Object rule
941 # Do not call this rule directly, since _object_ and _source_ may have
942 # have platform-specific file extensions
944 rule Dc
946     Depends $(<) : $(>) ;
948     # Just to clarify here: this sets the per-target DCFLAGS to
949     # be the current value of (global) DCFLAGS and SUBDIRDCFLAGS.
951     DCFLAGS on $(<) += $(DCFLAGS) $(SUBDIRDCFLAGS) ;
955 # /Cc object : source ;
957 # Compile the file source into object, using the C compiler $(CC), its
958 # flags $(CCFLAGS) and $(OPTIM), and the header file directories $(HDRS).
959 # Called by the @Object rule
961 # Do not call this rule directly, since _object_ and _source_ may have
962 # have platform-specific file extensions
964 rule Cc
966     Depends $(<) : $(>) ;
968     # If the compiler's -o flag doesn't work, relocate the .o
970     if $(RELOCATE)
971     {
972         CcMv $(<) : $(>) ;
973     }
975     # Just to clarify here: this sets the per-target CCFLAGS to
976     # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
977     # CCHDRS and CCDEFS must be reformatted each time for some
978     # compiles (VMS, NT) that malign multiple -D or -I flags.
980     CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ;
982     CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
983     CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
986 # /C++ object : source ;
988 # Compile the C++ source file _source_. Similar to @CC, called by @Object
990 # Do not call this rule directly, since _object_ and _source_ may have
991 # have platform-specific file extensions
993 rule C++
995     Depends $(<) : $(>) ;
997     if $(RELOCATE)
998     {
999         CcMv $(<) : $(>) ;
1000     }
1002     C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) ;
1004     CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
1005     CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
1008 # /Chmod target ;
1010 # (Unix and VMS only). Change file permissions on _target_ to target-specific
1011 # $(MODE) value set by @Link, @File, @Install* and @Shell rules
1013 rule Chmod
1015     if $(CHMOD) { Chmod1 $(<) ; }
1018 # /Clean  clean : targets ;
1020 # Removes existing _targets_ when _clean_ is built. clean is not a dependency
1021 # of all, and must be built explicitely for targets to be removed
1024 # /File target : source ;
1026 # Copies _source_ into _target_
1028 rule File
1030     Depends files : $(<) ;
1031     Depends $(<) : $(>) ;
1032     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1033     MODE on $(<) = $(FILEMODE) ;
1034     Chmod $(<) ;
1037 # /Fortran object : source ;
1039 # Compile the Fortran source file _source_. Called by the @Object rule
1041 # Do not call this rule directly, since _obj_ and _source_ may have
1042 # have platform-specific file extensions
1044 rule Fortran
1046     Depends $(<) : $(>) ;
1049 # /GenFile target : image sources ;
1051 # Runs the command "_image_ _target_ _sources_" to create _target_ from
1052 # _sources_ and _image_ (where _image_ is an executable built by the
1053 # @Main rule)
1055 rule GenFile
1057     local _t = [ FGristSourceFiles $(<) ] ;
1058     local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;
1059     Depends $(_t) : $(_s) $(>[2-]) ;
1060     GenFile1 $(_t) : $(_s) $(>[2-]) ;
1061     Clean clean : $(_t) ;
1064 rule GenFile1
1066     MakeLocate $(<) : $(LOCATE_SOURCE) ;
1067     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1070 # /HardLink target : source ;
1072 # Makes _target_ a hard link to _source_, if it isn't one already
1073 # (Unix only)
1075 rule HardLink
1077     Depends files : $(<) ;
1078     Depends $(<) : $(>) ;
1079     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1082 # /HdrMacroFile
1084 # this rule is specific to FT-Jam. It is used to indicate that a given file
1085 # contains definitions for filename macros (e.g. "#define MYFILE_H <myfile>.h")
1086 # that can later be used in #include statements in the rest of the source
1088 # these files must be parsed before any make is tried.
1090 rule HdrMacroFile
1092   HDRMACRO $(<) ;
1095 # /HdrRule source : headers ;
1097 # Arranges the proper dependencies when the file _source_ includes the files
1098 # _headers_ through the #include C preprocessor directive
1100 # this rule is not intendend to be called explicitely. It is called
1101 # automatically during header scanning on sources handled by the @Object
1102 # rule (e.g. sources in @Main or @Library rules)
1104 rule HdrRule
1106     # HdrRule source : headers ;
1108     # N.B.  This rule is called during binding, potentially after
1109     # the fate of many targets has been determined, and must be
1110     # used with caution: don't add dependencies to unrelated
1111     # targets, and don't set variables on $(<).
1113     # Tell Jam that anything depending on $(<) also depends on $(>),
1114     # set SEARCH so Jam can find the headers, but then say we don't
1115     # care if we can't actually find the headers (they may have been
1116     # within ifdefs),
1118     local s = $(>:G=$(HDRGRIST:E)) ;
1120     Includes $(<) : $(s) ;
1121     SEARCH on $(s) = $(HDRSEARCH) ;
1122     NoCare $(s) ;
1124     # Propagate on $(<) to $(>)
1126     HDRSEARCH on $(s) = $(HDRSEARCH) ;
1127     HDRSCAN on $(s) = $(HDRSCAN) ;
1128     HDRRULE on $(s) = $(HDRRULE) ;
1129     HDRGRIST on $(s) = $(HDRGRIST) ;
1133 rule InstallInto
1135     # InstallInto dir : sources ;
1137     local i t ;
1139     t = $(>:G=$(INSTALLGRIST)) ;
1141     # Arrange for jam install
1142     # Arrange for jam uninstall
1143     # sources are in SEARCH_SOURCE
1144     # targets are in dir
1146     Depends install : $(t) ;
1147     Clean uninstall : $(t) ;
1148     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1149     MakeLocate $(t) : $(<) ;
1151     # For each source, make gristed target name
1152     # and Install, Chmod, Chown, and Chgrp
1154     for i in $(>)
1155     {
1156         local tt = $(i:G=$(INSTALLGRIST)) ;
1158         Depends $(tt) : $(i) ;
1159         Install $(tt) : $(i) ;
1160         Chmod $(tt) ;
1162         if $(OWNER) && $(CHOWN)
1163         {
1164         Chown $(tt) ;
1165         OWNER on $(tt) = $(OWNER) ;
1166         }
1168         if $(GROUP) && $(CHGRP)
1169         {
1170         Chgrp $(tt) ;
1171         GROUP on $(tt) = $(GROUP) ;
1172         }
1173     }
1176 # /InstallBin dir : sources ;
1178 # Copy _sources_ into _dir_ with mode $(EXEMODE)
1180 rule InstallBin
1182     local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;
1184     InstallInto $(<) : $(_t) ;
1185     MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ;
1188 # /InstallFile dir : sources ;
1190 # Copy _sources_ into _dir_ with mode $(FILEMODE)
1192 rule InstallFile
1194     InstallInto $(<) : $(>) ;
1195     MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
1198 # /InstallLib dir : sources ;
1200 # Copy _sources_ into _dir_ with mode $(FILEMODE)
1202 rule InstallLib
1204     InstallInto $(<) : $(>) ;
1205     MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
1208 # /InstallLib dir : sources ;
1210 #  Copy _sources_ into the appropriate subdirectory of _dir_ with mode
1211 #  $(FILEMODE). The subdirectory is manS, where S is the suffix of each of
1212 #  sources.
1214 rule InstallMan
1216     # Really this just strips the . from the suffix
1218     local i s d ;
1220     for i in $(>)
1221     {
1222         switch $(i:S)
1223         {
1224         case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;
1225         case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;
1226         case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;
1227         case .n : s = n ; case .man : s = 1 ;
1228         }
1230         d = man$(s) ;
1232         InstallInto $(d:R=$(<)) : $(i) ;
1233     }
1235     MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
1238 # /InstallShell dir : sources ;
1240 # Copy _sources_ into _dir_ with mode $(SHELLMODE)
1242 rule InstallShell
1244     InstallInto $(<) : $(>) ;
1245     MODE on $(>:G=$(INSTALLGRIST)) = $(SHELLMODE) ;
1248 # /Lex source.c : source.l ;
1250 # Process the lex source file _source.l_ and rename the lex.yy.c
1251 # to _source.c_ . Called by the @Object rule
1253 rule Lex
1255     LexMv $(<) : $(>) ;
1256     Depends $(<) : $(>) ;
1257     MakeLocate $(<) : $(LOCATE_SOURCE) ;
1258     Clean clean : $(<) ;
1261 # /Library  library : sources ;
1263 #  Compiles _sources_ and archives them into _library_. The intermediate
1264 #  objects are deleted. Calles @Object and @LibraryFromObjects
1266 #  If @Library is invoked with no suffix on _library_, the $(SUFLIB)
1267 #  suffix is used
1269 rule Library
1271     LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
1272     Objects $(>) ;
1275 # /SharedLibrary  library : sources : def : import ;
1277 # Compiles _sources_ and generates a shared _library_ (i.e. DLL on Windows,
1278 # or shared object on Unix). Calls @SharedObjects and @SharedLibraryFromObjects
1280 # If @SharedLibrary is invoked with no suffix on _library_, then
1281 # $(SUFLIBSHR) suffix is used
1283 # _def_ is the name of the corresponding definition file used to generate
1284 # the library on Windows and OS/2 (ignored otherwise). If undefined, it
1285 # will default to _library_ with the .def suffix
1287 # _import_ is the name of the corresponding import library for Windows
1288 # and OS/2 platforms (ignored otherwise). If undefined, it will default
1289 # to _library_ with the .dll.lib suffix.
1291 rule SharedLibrary
1293   SharedLibraryFromObjects $(<) : $(>:S=$(SUFOBJSHR)) : $(3) : $(4) ;
1294   SharedObjects            $(>) ;
1297 if $(UNIX)
1299   # this rule is used to find the 'libtool' script in the current
1300   # path, this is required when compiling shared objects on Unix
1301   #
1302   rule LibToolFind
1303   {
1304     if $(LIBTOOL) { return $(LIBTOOL) ; }
1306     local  matches = [ Glob $(PATH) : libtool ] ;
1308     if ! $(matches)
1309     {
1310       Exit "could not find 'libtool' program in current path. Aborting !" ;
1311     }
1312     LIBTOOL = $(matches[1]) ;
1314     return $(LIBTOOL) ;
1315   }
1318 # /LibraryFromObjects library : objects ;
1320 # Archives _objects_ into _library_. The _objects_ are then deleted
1322 # If _library_ has no suffix, the $(SUFLIB) suffix is used
1324 # Called by @Library rule. Most people should never call this rule
1325 # directly.
1327 rule LibraryFromObjects
1329     local _i _l _s ;
1331     # Add grist to file names
1333     _s = [ FGristFiles $(>) ] ;
1334     _l = $(<:S=$(SUFLIB)) ;
1336     # library depends on its member objects
1338     if $(KEEPOBJS)
1339     {
1340         Depends obj : $(_s) ;
1341     }
1342     else
1343     {
1344         Depends lib : $(_l) ;
1345     }
1347     # Set LOCATE for the library and its contents.  The bound
1348     # value shows up as $(NEEDLIBS) on the Link actions.
1349     # For compatibility, we only do this if the library doesn't
1350     # already have a path.
1352     if ! $(_l:D)
1353     {
1354         MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;
1355     }
1357     if $(NOARSCAN)
1358     {
1359         # If we can't scan the library to timestamp its contents,
1360         # we have to just make the library depend directly on the
1361         # on-disk object files.
1363         Depends $(_l) : $(_s) ;
1364     }
1365     else
1366     {
1367         # If we can scan the library, we make the library depend
1368         # on its members and each member depend on the on-disk
1369         # object file.
1371         Depends $(_l) : $(_l)($(_s:BS)) ;
1373         for _i in $(_s)
1374         {
1375         Depends $(_l)($(_i:BS)) : $(_i) ;
1376         }
1377     }
1379     Clean clean : $(_l) ;
1381     if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
1383     Archive $(_l) : $(_s) ;
1385     if $(RANLIB) { Ranlib $(_l) ; }
1387     # If we can't scan the library, we have to leave the .o's around.
1389     if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; }
1393 # /SharedLibraryFromObjects  library : objects : def : import ;
1395 # Equivalent of @LibraryFromObjects for shared libraries.
1397 # Called by @SharedLibrary. Most people shouldn't call this rule
1398 # directly
1400 rule SharedLibraryFromObjects
1402     local _i _l _s ;
1404     # Add grist to file names
1406     _s = [ FGristFiles $(>) ] ;
1407     _l = $(<:S=$(SUFLIBSHR)) ;
1409     #Echo "Library is $(_l)"    ;
1410     # library depends on its member objects
1412     if $(KEEPOBJS)
1413     {
1414       Depends obj : $(_s) ;
1415     }
1416     else
1417     {
1418       Depends lib : $(_l) ;
1419     }
1421     # Set LOCATE for the library and its contents.  The bound
1422     # value shows up as $(NEEDLIBS) on the Link actions.
1423     # For compatibility, we only do this if the library doesn't
1424     # already have a path.
1426     if ! $(_l:D)
1427     {
1428         MakeLocate $(_l) : $(LOCATE_TARGET) ;
1429     }
1431     # we never scan shared libraries for member objects
1432     Depends $(_l) : $(_s) ;
1434     Clean clean : $(_l) ;
1436     # I don't know if VMS supports shared libraries, so I prefer
1437     # to disable the following right now
1438     #
1439     #if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
1441     # creating the library is so much fun on Unix :-)
1442     if $(UNIX)
1443     {
1444       local  libtool = [ LibToolFind ] ;  # find the right libtool
1446       AR on $(_l) = "$(libtool) --mode=link $(AR)" ;
1447     }
1448     else if $(NT)
1449     {
1450       local  _implib = $(4) ;
1451       local  _def    = $(3) ;
1453       _implib ?= $(_l:S=$(SUFLIBSHR)$(SUFLIB)) ;
1454       _def    ?= $(_l:S=.def) ;
1456       Clean    clean : $(_implib) ;
1457       Depends  lib   : $(_implib) $(_def) ;
1459       Depends $(_implib) : $(_def) $(_l) ;
1460       Depends $(_l)      : $(_def) ;
1462       DEFFILENAME on $(_l) = $(_def) ;
1463       IMPLIBNAME  on $(_l) = $(_implib) ;
1465       MakeLocate $(_implib)        : $(LOCATE_TARGET) ;
1466       MakeLocate $(_implib:S=.exp) : $(LOCATE_TARGET) ;
1468       if $(JAM_TOOLSET) in VISUALC BORLANDC LCC WATCOM DIGITALMARS
1469       {
1470         SharedLink-$(JAM_TOOLSET) $(_l) : $(_s) : $(_implib) : $(_def) ;
1471       }
1473       DllLink $(_l) : $(_s) ;
1474     }
1475     else
1476     {
1477       Echo "Sorry, I don't know how to make a shared library on your system" ;
1478       Exit "Please contact the FTJam maintainer for help" ;
1479     }
1483 # Since building shared libraries is so different depending on the
1484 # compiler being used, I've broken this task into compiler-specific
1485 # ones
1489 # This contains the Visual C++ specific rule used to build a DLL
1490 # and its import library
1492 rule SharedLink-VISUALC
1494   # get rid of the '.exp' file when cleaning
1495   #
1496   Clean  clean : $(3:S=.exp) ;
1500 rule SharedLink-BORLANDC
1502   local  _deffile = $(4) ;
1503   local  _implib  = $(3) ;
1505   LINKFLAGS on $(<) += /x /Gn /Tpd ;
1506   LINKLIBS on $(<) = $(LINKLIBS) $(ILINKLIBS) ;
1508   # Generate import library with the IMPLIB tool !!
1509   #
1510   DllImplib $(_implib) : $(<) ;
1511   Depends   $(_implib) : $(_deffile) $(<) ;
1512   Depends   lib        : $(_implib) ;
1514   DEFFILENAME on $(_implib) = $(_deffile) ;
1516   # clean the TDS file, since the compiler refuses to not generate it !
1517   MakeLocate $(<:S=.tds) : $(LOCATE_TARGET) ;
1518   Clean  clean : $(<:S=.tds) ;
1522 rule SharedLink-LCC
1524   if "" {
1525   #Echo "Sorry, but generating DLLs with LCC is not supported. That's" ;
1526   #Echo "because the 'lcclnk' tool that comes with this compiler is" ;
1527   #Echo "unreliable and doesn't work as expected. For more information" ;
1528   #Echo "contact the FT-Jam maintainer" ;
1529   #Exit ;
1530   }
1532   # the 'lcclnk' tool is absolutely broken:
1533   #   - its -o flag doesn't work when there is a LIBRARY statement
1534   #     in the .def file.
1535   #
1536   #   - it uses the LIBRARY name in the .def file to determine
1537   #     the name of the dll and its import library, and always
1538   #     places them in the current directory !!
1539   #
1540   #   - if there is no LIBRARY statement, the -o flag is only
1541   #     used to determine where the DLL is placed, the import
1542   #     library will always be placed in the current directory !!
1543   #
1545   # clean the .exp file too, don't know how to get rid of it
1546   Clean clean : $(4:S=.exp) ;
1550 rule SharedLink-WATCOM
1552   #Echo "Sorry, but building DLLs with Watcom isn't supported by this tool" ;
1553   #Echo "this comes from the fact that the Watcom linker isn't capable of"  ;
1554   #Echo "using normal .def files" ;
1555   #Exit ;
1557   local  _deffile = $(4) ;
1558   local  _implib  = $(3) ;
1560   IMPLIB on $(<) = $(_implib) ;
1561   DEFFILE on $(<) = $(_deffile) ;
1563   # clean the TDS file, since the compiler refuses to not generate it !
1564   MakeLocate $(<:S=.tds) : $(LOCATE_TARGET) ;
1565   Clean  clean : $(<:S=.tds) ;
1569 rule SharedLink-DIGITALMARS
1571   #Echo "Sorry, but building DLLs with Digital Mars isn't supported at the" ;
1572   #Echo "moment, please contact the FT-Jam maintainers" ;
1573   #Exit ;
1577 # /Link  image : objects ;
1579 # Links _image_ from _objects_ and sets permissions on _image_ to
1580 # $(EXEMODE). _image_ must be an actual filename; suffix is not
1581 # supplied.
1583 # Called by @Main, shouldn't be called by most people
1585 rule Link
1587     MODE on $(<) = $(EXEMODE) ;
1588     Chmod $(<) ;
1591 # /LinkLibraries image : libraries ;
1593 # Makes _image_ depend on _libraries_ and includes them during linking
1595 # _image_ may be referenced without a suffix in this rule invocation.
1596 # @LinkLibraries supplies the suffix
1598 # You should only use this rule with libraries created through the
1599 # @Library rule. For external libraries, use something else (XXX)
1601 rule LinkLibraries
1603     # make library dependencies of target
1604     # set NEEDLIBS variable used by 'actions Main'
1606     local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1608     Depends $(_t) : $(>:S=$(SUFLIB)) ;
1609     NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ;
1612 # /LinkSharedLibraries image : libraries :
1614 # Same as @LinkLibraries, but to link _image_ with shared libraries
1615 # generated through the @SharedLibrary rule
1617 rule LinkSharedLibraries
1619     # make library dependencies of target
1620     # set NEEDLIBS variable used by 'actions Main'
1622     local _t   = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1623     local _ext = $(SUFLIBSHR) ;
1625     if $(NT) || $(OS2)
1626     {
1627       # on NT or OS/2, we need to link agains the import library,
1628       # not the DLL itself !!
1629       #
1630       _ext = $(SUFLIBSHR)$(SUFLIB) ;
1631     }
1632     Depends $(_t) : $(>:S=$(_ext))  ;
1633     NEEDLIBS on $(_t) += $(>:S=$(_ext)) ;
1636 # /Main image : sources ;
1638 # Compiles _sources_ and links them into _image_. Calls @Objects and
1639 # @MainFromObjects.
1641 # _image_ may be supplied without suffix.
1643 rule Main
1645     MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
1646     Objects $(>) ;
1649 # /MainFromObjects image : objects ;
1651 # Links _objects_ into _image_. Dependency of exe.
1652 # @MainFromObjects provides a default suffix for _image_
1654 rule MainFromObjects
1656     local _s _t ;
1658     # Add grist to file names
1659     # Add suffix to exe
1661     _s = [ FGristFiles $(>) ] ;
1662     _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1664     # so 'jam foo' works when it's really foo.exe
1666     if $(_t) != $(<)
1667     {
1668         Depends $(<) : $(_t) ;
1669         NotFile $(<) ;
1670     }
1672     # make compiled sources a dependency of target
1674     Depends exe : $(_t) ;
1675     Depends $(_t) : $(_s) ;
1676     MakeLocate $(_t) : $(LOCATE_TARGET) ;
1678     Clean clean : $(_t) ;
1680     # special case for stupid Borland C++, which always generates a
1681     # .tds file for executables, even when no debug information is needed
1682     #
1683     if $(JAM_TOOLSET) = BORLANDC {
1684       MakeLocate $(_t:S=.tds) : $(LOCATE_TARGET) ;
1685       Clean  clean : $(_t:S=.tds) ;
1686     }
1688     Link $(_t) : $(_s) ;
1691 # /MakeLocate  targets : directory
1693 # Creates _dir_ and causes _target_ to be built into _dir_
1695 # This is done by setting the target-specific variable LOCATE
1696 # on _targets_, and arranges with @MkDir to create the target
1697 # directory
1699 rule MakeLocate
1701     # Note we grist the directory name with 'dir',
1702     # so that directory path components and other
1703     # targets don't conflict.
1705     if $(>)
1706     {
1707         LOCATE on $(<) = $(>) ;
1708         Depends $(<) : $(>[1]:G=dir) ;
1709         MkDir $(>[1]:G=dir) ;
1710     }
1713 # /MkDir  dir ;
1715 # Creates _dir_ and its parent directories
1717 rule MkDir
1719     # Ignore timestamps on directories: we only care if they
1720     # exist.
1722     NoUpdate $(<) ;
1724     # Don't create . or any directory already created.
1726     if $(<:G=) != $(DOT) && ! $($(<)-mkdir)
1727     {
1728         # Cheesy gate to prevent multiple invocations on same dir
1729         # Arrange for jam dirs
1730         # MkDir1 has the actions
1732         $(<)-mkdir = true ;
1733         Depends dirs : $(<) ;
1734         MkDir1 $(<) ;
1736         # Recursively make parent directories.
1737         # $(<:P) = $(<)'s parent, & we recurse until root
1739         local s = $(<:P) ;
1741         # Don't try to create A: or A:\ on windows
1743         if $(NT)
1744         {
1745             switch $(s)
1746             {
1747                 case *:   : s = ;
1748                 case *:\\ : s = ;
1749             }
1750         }
1752         # handle "C:", "C:/", "/cygdrive" and "/cygdrive/" in Cygwin
1753         if $(UNIX) && $(OS) = CYGWIN
1754         {
1755             switch $(s)
1756             {
1757               case ?:   : s = ;
1758               case ?:/  : s = ;
1759               case <dir>/cygdrive   : s = ;
1760               case <dir>/cygdrive/  : s = ;
1761             }
1762         }
1764         if $(s) = $(<)
1765         {
1766         # The parent is the same as the dir.
1767         # We're at the root, which some OS's can't stat, so we mark
1768         # it as NotFile.
1770             NotFile $(s) ;
1771         }
1772         else if $(s:G=)
1773         {
1774         # There's a parent; recurse.
1776         Depends $(<) : $(s) ;
1777         MkDir $(s) ;
1778         }
1779     }
1782 # /Object object : source ;
1784 # Compile s a single _source_ file into _object_. The @Main and @Library
1785 # rules use it to compile sources.
1787 # Causes _source_ to be scanned for #include directives and calls @HdrRule
1788 # to make all included files dependencies of _object_.
1790 # Calls one of the following rules depending on the suffix to do the
1791 # actual compilation:
1793 rule Object
1795     # locate object and search for source, if wanted
1797     Clean clean : $(<) ;
1799     MakeLocate $(<) : $(LOCATE_TARGET) ;
1800     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1802     # Save HDRS for -I$(HDRS) on compile.
1803     # We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers
1804     # in the .c file's directory, but generated .c files (from
1805     # yacc, lex, etc) are located in $(LOCATE_TARGET), possibly
1806     # different from $(SEARCH_SOURCE).
1808     HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;
1810     # handle #includes for source: Jam scans for headers with
1811     # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
1812     # with the scanned file as the target and the found headers
1813     # as the sources.  HDRSEARCH is the value of SEARCH used for
1814     # the found header files.  Finally, if jam must deal with
1815     # header files of the same name in different directories,
1816     # they can be distinguished with HDRGRIST.
1818     # $(SEARCH_SOURCE:E) is where cc first looks for #include
1819     # "foo.h" files.  If the source file is in a distant directory,
1820     # look there.  Else, look in "" (the current directory).
1822     HDRRULE on $(>) = HdrRule ;
1823     HDRSCAN on $(>) = $(HDRPATTERN) ;
1824     HDRSEARCH on $(>) =
1825         $(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ;
1827     HDRGRIST on $(>) = $(HDRGRIST) ;
1829     # propagate target specific-defines
1831     DEFINES on $(<) += $(DEFINES) ;
1833     # if source is not .c, generate .c with specific rule
1835     switch $(>:S)
1836     {
1837         case .asm : As $(<) : $(>) ;
1838         case .c :   Cc $(<) : $(>) ;
1839         case .C :   C++ $(<) : $(>) ;
1840         case .cc :  C++ $(<) : $(>) ;
1841         case .cpp : C++ $(<) : $(>) ;
1842         case .cxx : C++ $(<) : $(>) ;
1843         case .c++ : C++ $(<) : $(>) ;
1844         case .C++ : C++ $(<) : $(>) ;
1845         case .d :   Dc $(<) : $(>) ;
1846         case .f :   Fortran $(<) : $(>) ;
1847         case .l :   Cc $(<) : $(<:S=.c) ;
1848                     Lex $(<:S=.c) : $(>) ;
1849         case .s :   As $(<) : $(>) ;
1850         case .y :   Cc $(<) : $(<:S=$(YACCGEN)) ;
1851                     Yacc $(<:S=$(YACCGEN)) : $(>) ;
1852         case * :    UserObject $(<) : $(>) ;
1853     }
1856 # /ObjectCcFlags  sources : flags ;
1858 # this rule is used to add compiler flags to the compilation of
1859 # specific C sources files.
1861 rule ObjectCcFlags
1863     CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1866 # /ObjectC++Flags  sources : flags ;
1868 # this rule is used to add compiler flags to the compilation of
1869 # specific C++ source files
1871 rule ObjectC++Flags
1873     C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1876 # /ObjectDefines  objects : macros ;
1878 # this rule is used to add macro defines to the compilation of
1879 # specific C and C++ source files
1881 rule ObjectDefines
1883     # must reformat CCDEFS according to current defines
1885     local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;
1887     DEFINES on $(s) += $(>) ;
1888     CCDEFS on $(s) = [ on $(s) FDefines $(DEFINES) ] ;
1891 # /ObjectHdrs  sources : paths ;
1893 # this rule is used to add include paths to the compilation of
1894 # specific C and C++ source files
1896 rule ObjectHdrs
1898     # Add to HDRS for HdrScan's benefit.
1899     # must reformat CCHDRS according to headers
1901     local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;
1903     HDRS on $(s) += $(>) ;
1904     CCHDRS on $(s) = [ on $(s) FIncludes $(HDRS) ] ;
1907 # /Objects sources ;
1909 # this rule is used to compile one or more sources into object files.
1910 # do not call it directly, it is used by the Main and Library rules
1911 # automatically
1913 rule Objects
1915     local _i ;
1917     for _i in [ FGristFiles $(<) ]
1918     {
1919         Object $(_i:S=$(SUFOBJ)) : $(_i) ;
1920         Depends obj : $(_i:S=$(SUFOBJ)) ;
1921     }
1924 # /SharedObjects
1926 # this rule is used to compile one or more sources into 'shared object
1927 # files'. This means object files used to build either DLLs or Unix shared
1928 # libraries.
1930 # do not call this rule directly, it is called by SharedLibrary automatically
1932 rule SharedObjects
1934   # temporarily override SUFOBJ with $(SUFOBJSHR) to
1935   #
1936   local SUFOBJ = $(SUFOBJSHR) ;
1938   # call the normal Objects rule
1939   #
1940   Objects $(<) ;
1942   # add the compiler-specific position-independent-code flag
1943   # where needed
1944   #
1945   ObjectCcFlags $(<) : $(PICFLAGS) ;
1947   # change the compiler invokation for all these objects
1948   # to use Libtool on Unix systems. We explicitely disable the
1949   # generation of static objects here
1950   #
1951   if $(UNIX)
1952   {
1953     libtool on $(<:S=$(SUFOBJ)) = [ LibToolFind ] ;
1954     CC on $(<:S=$(SUFOBJ))      = "$(libtool) --mode=compile $(CC) -dynamic" ;
1955   }
1959 rule RmTemps
1961     Temporary $(>) ;
1964 rule Setuid
1966     MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ;
1969 rule Shell
1971     Depends shell : $(<) ;
1972     Depends $(<) : $(>) ;
1973     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1974     MODE on $(<) = $(SHELLMODE) ;
1975     Clean clean : $(<) ;
1976     Chmod $(<) ;
1979 rule SoftLink
1981     Depends files : $(<) ;
1982     Depends $(<) : $(>) ;
1983     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1984     Clean clean : $(<) ;
1987 rule SubDir
1989     #
1990     # SubDir TOP d1 d2 ... ;
1991     #
1992     # Support for a project tree spanning multiple directories.
1993     #
1994     # SubDir declares a Jamfile's location in a project tree, setting
1995     # Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source
1996     # files can be found.
1997     #
1998     # TOP is a user-select variable name for root of the tree, and
1999     # d1 d2 ...  are the directory elements that lead from the root
2000     # of the tree to the directory of the Jamfile.
2001     #
2002     # TOP can be set externally, but normally the first SubDir call
2003     # computes TOP as the path up from the current directory; the
2004     # path contains one ../ for each of d1 d2 ...
2005     #
2006     # SubDir reads once the project-specific rules file Jamrules
2007     # in the TOP directory, if present.  This can be overridden
2008     # with the variable TOPRULES.
2009     #
2010     # SubDir supports multiple, overlaid project trees:  SubDir
2011     # invocations with different TOPs can appear in the same Jamfile.
2012     # The location established by the first SubDir call is used set
2013     # the TOPs for the subsequent SubDir calls.
2014     #
2015     # SubDir's public variables:
2016     #
2017     #   $(TOP) = path from CWD to root.
2018     #   $(SUBDIR) = path from CWD to the directory SubDir names.
2019     #   $(SUBDIR_TOKENS) = path from $(TOP) to $(SUBDIR) as dir names
2020     #   $(SEARCH_SOURCE) = $(SUBDIR)
2021     #   $(LOCATE_SOURCE) = $(ALL_LOCATE_TARGET) $(SUBDIR)
2022     #   $(LOCATE_TARGET) = $(ALL_LOCATE_TARGET) $(SUBDIR)
2023     #   $(SOURCE_GRIST) = $(SUBDIR_TOKENS) with !'s
2024     #
2026     local _top = $(<[1]) ;
2027     local _tokens = $(<[2-]) ;
2029     #
2030     # First time through sets up relative root and includes Jamrules.
2031     #
2033         if ! $(_top)
2034         {
2035             Exit SubDir syntax error ;
2036         }
2038     if ! $($(_top)-SET)
2039     {
2040         $(_top)-SET = true ;
2042         # First time we've seen this TOP.
2043         # We'll initialize a number of internal variables:
2044         #
2045         #   $(TOP-UP) = directories from ROOT to a common point
2046         #   $(TOP-DOWN) = directories from common point to TOP
2047         #   $(TOP-ROOT) = root directory for UP/DOWN -- normally CWD
2048         #   $(SUBDIR_UP) = current value of $(TOP-UP)
2049         #   $(SUBDIR_DOWN) = current value of $(TOP-DOWN)
2050         #   $(SUBDIR_ROOT) = current value of $(TOP-ROOT)
2051         #
2053         if $($(_top))
2054         {
2055             # TOP externally set.
2056             # We'll ignore the relative (UP/DOWN) path that
2057             # got us here, and instead remember the hard ROOT.
2059             $(_top)-UP = ;
2060             $(_top)-DOWN = ;
2061             $(_top)-ROOT = $($(_top)) ;
2062         }
2063         else
2064     {
2065         # TOP not preset.
2067         # Establishing a new TOP.  In the simplest case,
2068         # (SUBDIR_UP/SUBDIR_DOWN/SUBDIR_ROOT unset), it's
2069         # merely a certain number of directories down from
2070         # the current directory, and FSubDirPath will set
2071         # TOP to a path consisting of ../ for each of the
2072         # elements of _tokens, because that represents how
2073         # far below TOP the current directory sits.
2074         #
2075         # In the more complicated case, the starting directory
2076         # isn't the directory of jam's invocation but an
2077         # location established by previous SubDir call.  The
2078         # starting directory is SUBDIR_UP directories up from
2079         # SUBDIR_ROOT, and then SUBDIR_DOWN directories down
2080         # from that.   If SUBDIR_ROOT is not set, that means
2081         # SUBDIR_DOWN and SUBDIR_UP represent the path from
2082         # the directory of jam's invocation.
2083         #
2084         # In the most complicated case, the _tokens also
2085         # represents directories down, because TOP is being
2086         # estalished in a directory other than TOP's root.
2087         # Hopefully, _tokens and SUBDIR_DOWN represent the
2088         # same final directory, relative to the new TOP and
2089         # the previous SubDIr's TOP.  To find the new TOP,
2090         # we have to chop off any common directories from
2091         # then ends of _tokens and SUBDIR_DOWN.  To do so,
2092         # we reverse each of them, call FStripCommon to
2093         # remove the initial common elements, and then
2094         # reverse them again.  After this process, if
2095         # both _tokens and SUBDIR_DOWN have elements, it
2096         # means the directory names estalished by the two
2097         # SubDir calls don't match, and a warning is issued.
2098         # All hell will likely break loose at this point,
2099         # since the whole SubDir scheme relies on the SubDir
2100         # calls accurately naming the current directory.
2102         # Strip common trailing elements of _tokens and SUBDIR_DOWN.
2104         _tokens = [ FReverse $(_tokens) ] ;
2105         SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
2106         FStripCommon _tokens : SUBDIR_DOWN ;
2107         SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
2108         _tokens = [ FReverse $(_tokens) ] ;
2110         if $(SUBDIR_DOWN) && $(_tokens)
2111         {
2112             Echo Warning: SubDir $(<) misplaced! ;
2113         }
2115         # We'll remember the relative (UP/DOWN) path that
2116         # got us here, plus any hard ROOT starting point
2117         # for the UP/DOWN.  If TOP is never set externally,
2118         # ROOT will always be "" (directory of jam's invocation).
2120         $(_top)-UP = $(SUBDIR_UP) $(_tokens) ;
2121         $(_top)-DOWN = $(SUBDIR_DOWN) ;
2122         $(_top)-ROOT = $(SUBDIR_ROOT:E="") ;
2123         $(_top) = [ FSubDirPath $(_top) ] ;
2124         }
2126         # Set subdir vars for the inclusion of the Jamrules,
2127         # just in case they have SubDir rules of their own.
2128         # Note that SUBDIR_DOWN is empty: it's all the way
2129         # up where the Jamrules live.  These gets overrided
2130         # just after the inclusion.
2132         SUBDIR_UP = $($(_top)-UP) ;
2133         SUBDIR_DOWN = ;
2134         SUBDIR_ROOT = $($(_top)-ROOT) ;
2136         # Include $(TOPRULES) or $(TOP)/Jamrules.
2137         # Include $(TOPRULES) if set.
2138         # Otherwise include $(TOP)/Jamrules if present.
2140         if $($(_top)RULES) {
2141             include $($(_top)RULES) ;
2142         } else {
2143             NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ;
2144             include $(JAMRULES:R=$($(_top)):G=$(_top)) ;
2145         }
2146     }
2148     # Get path from $(TOP) to named directory.
2149     # Save dir tokens for other potential uses.
2151     SUBDIR_UP = $($(_top)-UP) ;
2152     SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ;
2153     SUBDIR_ROOT = $($(_top)-ROOT) ;
2154     SUBDIR_TOKENS = $(SUBDIR_DOWN) ;
2156     SUBDIR = [ FSubDirPath $(<) ] ;
2158     # Now set up SEARCH_SOURCE, LOCATE_TARGET, SOURCE_GRIST
2159     # These can be reset if needed.  For example, if the source
2160     # directory should not hold object files, LOCATE_TARGET can
2161     # subsequently be redefined.
2163     SEARCH_SOURCE = $(SUBDIR) ;
2164     LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
2165     LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
2166     SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ;
2168     # Reset per-directory ccflags, hdrs, etc,
2169     # listed in SUBDIRRESET.
2170     # Note use of variable expanded assignment var
2172     SUBDIR$(SUBDIRRESET) = ;
2174     # Invoke user-specific SubDir extensions,
2175     # rule names listed in SUBDIRRULES.
2176     # Note use of variable expanded rule invocation
2178     $(SUBDIRRULES) $(<) ;
2181 rule FSubDirPath
2183     # FSubDirPath TOP d1 ... ;
2185     # Returns path to named directory.
2187     # If jam is invoked in a subdirectory of the TOP, then we
2188     # need to prepend a ../ for every level we must climb up
2189     # (TOP-UP), and then append the directory names we must
2190     # climb down (TOP-DOWN), plus the named directories d1 ...
2191     # If TOP was set externally, or computed from another TOP
2192     # that was, we'll have to reroot the whole thing at TOP-ROOT.
2194     local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ;
2196     return $(_r:R=$($(<[1])-ROOT)) ;
2199 rule SubDirDcFlags
2201     SUBDIRDCFLAGS += $(<) ;
2204 rule SubDirCcFlags
2206     SUBDIRCCFLAGS += $(<) ;
2209 rule SubDirC++Flags
2211     SUBDIRC++FLAGS += $(<) ;
2214 rule SubDirHdrs
2216     SUBDIRHDRS += [ FDirName $(<) ] ;
2219 rule SubInclude
2221     # SubInclude TOP d1 ... ;
2222     #
2223     # Include a subdirectory's Jamfile.
2225     # We use SubDir to get there, in case the included Jamfile
2226     # either doesn't have its own SubDir (naughty) or is a subtree
2227     # with its own TOP.
2229     if ! $($(<[1]))
2230     {
2231         Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ;
2232     }
2234     SubDir $(<) ;
2236     include $(JAMFILE:D=$(SUBDIR)) ;
2239 rule SubRules
2241     # SubRules TOP d1 ... : Other-TOP ;
2242     #
2243     # Read another tree's Jamrules, by giving it's path according
2244     # to this tree and it's own name.
2246     if ! $($(<[1]))
2247     {
2248         Exit SubRules $(<[1]) without prior SubDir $(<[1]) ;
2249     }
2251     SubDir $(<) ;
2252     SubDir $(>) ;
2255 rule Undefines
2257     UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ;
2260 rule UserObject
2262     Exit "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ;
2265 rule Yacc
2267     local _h ;
2269     _h = $(<:BS=.h) ;
2271     # Some places don't have a yacc.
2273     MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;
2275     if $(YACC)
2276     {
2277         Depends $(<) $(_h) : $(>) ;
2278         Yacc1 $(<) $(_h) : $(>) ;
2279         YaccMv $(<) $(_h) : $(>) ;
2280         Clean clean : $(<) $(_h) ;
2281     }
2283     # make sure someone includes $(_h) else it will be
2284     # a deadly independent target
2286     Includes $(<) : $(_h) ;
2290 # Utility rules; no side effects on these
2293 # /FGrist path to file ;
2295 # Returns a single string that is used as grist
2297 rule FGrist
2299     return $(<:J=!) ;
2304 rule FGristFiles
2306     return $(<:G=$(SOURCE_GRIST:E)) ;
2310 rule FGristSourceFiles
2312     # Produce source file name name with grist in it,
2313     # if SOURCE_GRIST is set.
2315     # Leave header files alone, because they have a global
2316     # visibility.
2318     if ! $(SOURCE_GRIST)
2319     {
2320         return $(<) ;
2321     }
2322     else
2323     {
2324         local _i _o ;
2326         for _i in $(<)
2327         {
2328         switch $(_i)
2329         {
2330         case *.h :  _o += $(_i) ;
2331         case * :    _o += $(_i:G=$(SOURCE_GRIST)) ;
2332         }
2333         }
2335         return $(_o) ;
2336     }
2340 rule FReverse
2342     if $(1) { return [ FReverse $(1[2-]) ] $(1[1]) ; }
2346 rule FSubDir
2348     # If $(>) is the path to the current directory, compute the
2349     # path (using ../../ etc) back to that root directory.
2350     # Sets result in $(<)
2352     if ! $(<[1])
2353     {
2354         return $(DOT) ;
2355     }
2356     else
2357     {
2358         local _i _d ;
2360         _d = $(DOTDOT) ;
2362         for _i in $(<[2-])
2363         {
2364         _d = $(_d:R=$(DOTDOT)) ;
2365         }
2367         return $(_d) ;
2368     }
2372 rule FStripCommon
2374     # FStripCommon v1 : v2 ;
2376     # Strip common initial elements of variables v1 and v2.
2377     # Modifies the variable values themselves.
2379     if $($(<)[1]) && $($(<)[1]) = $($(>)[1])
2380     {
2381         $(<) = $($(<)[2-]) ;
2382         $(>) = $($(>)[2-]) ;
2383         FStripCommon $(<) : $(>) ;
2384     }
2388 rule FRelPath
2390     local _l _r ;
2392     # first strip off common parts
2394     _l = $(<) ;
2395     _r = $(>) ;
2397     FStripCommon _l : _r ;
2399     # now make path to root and path down
2401     _l = [ FSubDir $(_l) ] ;
2402     _r = [ FDirName $(_r) ] ;
2404     # Concatenate and save
2406     # XXX This should be better
2408     if $(_r) = $(DOT) {
2409         return $(_l) ;
2410     } else {
2411         return $(_r:R=$(_l)) ;
2412     }
2416 rule FAppendSuffix
2418        # E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;"
2419        # returns (yacc,lex,foo.bat) on Unix and
2420        # (yacc.exe,lex.exe,foo.bat) on NT.
2422     if $(>)
2423     {
2424         local _i _o ;
2426         for _i in $(<)
2427         {
2428         if $(_i:S)
2429         {
2430             _o += $(_i) ;
2431         }
2432         else
2433         {
2434             _o += $(_i:S=$(>)) ;
2435         }
2436         }
2437         return $(_o) ;
2438     }
2439     else
2440     {
2441         return $(<) ;
2442     }
2446 # Operating system specific utility rules
2447 # First, the (generic) UNIX versions
2450 rule FQuote { return "\\\"$(<)\\\"" ; }
2451 rule FDefines { return -D$(<) ; }
2452 rule FIncludes { return -I$(<) ; }
2454 rule FDirName
2456     # Turn individual elements in $(<) into a usable path.
2458     local _i ;
2459     local _s = $(DOT) ;
2461     for _i in $(<)
2462     {
2463         _s = $(_i:R=$(_s)) ;
2464     }
2466     return $(_s) ;
2469 if $(OS2)
2471     rule FQuote { return "\"$(<)\"" ; }
2472     rule FIncludes { return /I$(<) ; }
2474 else if $(NT) && $(JAM_TOOLSET) != MINGW && $(JAM_TOOLSET) != LCC
2476     rule FDefines { return /D$(<) ; }
2477     rule FIncludes { return /I$(<) ; }
2480 else if $(MAC)
2482     rule FQuote { return "\"$(<)\"" ; }
2483     rule FDefines { return "-define '$(<)'" ; }
2484     rule FIncludes { return "\"$(<:J=,)\"" ; }
2487 else if $(VMS)
2489     rule FQuote { return "\"\"\"$(<)\"\"\"" ; }
2490     rule FDefines { return "/define=( $(<:J=,) )" ; }
2491     rule FIncludes { return "/inc=( $(<:J=,) )" ; }
2493     rule FDirName
2494     {
2495         local _s _i ;
2497         # Turn individual elements in $(<) into a usable path.
2499         if ! $(<)
2500         {
2501             _s = $(DOT) ;
2502         }
2503         else
2504         {
2505             # This handles the following cases:
2506             #   a -> [.a]
2507             #   a b c -> [.a.b.c]
2508             #   x: -> x:
2509             #   x: a -> x:[a]
2510             #   x:[a] b -> x:[a.b]
2512             switch $(<[1])
2513             {
2514                 case *:* :     _s = $(<[1]) ;
2515                 case \\[*\\] : _s = $(<[1]) ;
2516                 case * :       _s = [.$(<[1])] ;
2517             }
2519             for _i in [.$(<[2-])]
2520             {
2521                 _s = $(_i:R=$(_s)) ;
2522             }
2523         }
2525         return $(_s) ;
2526     }
2530 # Actions
2534 # First the defaults
2537 actions updated together piecemeal Archive
2539     $(AR) $(<) $(>)
2542 actions As
2544     $(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>)
2547 actions C++
2549     $(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2552 actions Cc
2554     $(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2557 actions Dc
2559     $(DC) -c -of$(<) $(DCFLAGS) $(DOPTIM) $(>)
2562 actions Chgrp
2564     $(CHGRP) $(GROUP) $(<)
2567 actions Chmod1
2569     $(CHMOD) $(MODE) $(<)
2572 actions Chown
2574     $(CHOWN) $(OWNER) $(<)
2577 actions piecemeal together existing Clean
2579     $(RM) $(>)
2582 actions File
2584     $(CP) $(>) $(<)
2587 actions GenFile1
2589     $(>[1]) $(<) $(>[2-])
2592 actions Fortran
2594     $(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>)
2597 actions HardLink
2599     $(RM) $(<) && $(LN) $(>) $(<)
2602 actions Install
2604     $(CP) $(>) $(<)
2607 actions Lex
2609     $(LEX) $(>)
2612 actions LexMv
2614     $(MV) lex.yy.c $(<)
2617 actions Link bind NEEDLIBS
2619     $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2622 actions MkDir1
2624     $(MKDIR) $(<)
2627 actions together Ranlib
2629     $(RANLIB) $(<)
2632 actions quietly updated piecemeal together RmTemps
2634     $(RM) $(>)
2637 actions Shell
2639     $(AWK) '
2640         NR == 1 { print "$(SHELLHEADER)" }
2641         NR == 1 && /^[#:]/ { next }
2642         /^##/ { next }
2643         { print }
2644     ' < $(>) > $(<)
2647 actions SoftLink
2649     $(RM) $(<) && $(LN) -s $(>) $(<)
2652 actions Yacc1
2654     $(YACC) $(YACCFLAGS) $(>)
2657 actions YaccMv
2659     $(MV) $(YACCFILES).c $(<[1])
2660     $(MV) $(YACCFILES).h $(<[2])
2664 # RELOCATE - for compilers with broken -o flags
2667 if $(RELOCATE)
2669     actions C++
2670     {
2671     $(C++) -c $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2672     }
2674     actions Cc
2675     {
2676     $(CC) -c $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2677     }
2679     actions ignore CcMv
2680     {
2681     [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)
2682     }
2686 # NOARUPDATE - can't update an archive
2689 if $(NOARUPDATE)
2691     actions Archive
2692     {
2693         $(AR) $(<) $(>)
2694     }
2698 # UNIX specific actions
2701 if $(UNIX)
2703     actions GenFile1
2704     {
2705     PATH="$PATH:."
2706     $(>[1]) $(<) $(>[2-])
2707     }
2711 # NT specific actions
2714 if $(NT)
2716     if $(JAM_TOOLSET) = VISUALC || $(JAM_TOOLSET) = INTELC
2717     {
2718         actions updated together piecemeal Archive
2719         {
2720             if exist $(<) set _$(<:B)_=$(<)
2721             $(AR) /out:$(<) %_$(<:B)_% $(>)
2722         }
2724         actions As
2725         {
2726             $(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul;
2727         }
2729         actions Cc
2730         {
2731             $(CC) /c /Fo$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) $(>)
2732         }
2734         actions C++
2735         {
2736             $(C++) /c /Fo$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) /Tp$(>)
2737         }
2739         actions Link bind NEEDLIBS
2740         {
2741             $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2742         }
2744         actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME
2745         {
2746             $(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2747         }
2748     }
2749     else if $(JAM_TOOLSET) = VISUALC16
2750     {
2751         actions updated together piecemeal Archive
2752         {
2753             $(AR) $(<) -+$(>)
2754         }
2756         actions Cc
2757         {
2758             $(CC) /c /Fo$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2759         }
2761         actions C++
2762         {
2763             $(C++) /c /Fo$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Tp$(>)
2764         }
2766         actions Link bind NEEDLIBS
2767         {
2768             $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2769         }
2771         actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME
2772         {
2773             $(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2774         }
2775     }
2776     else if $(JAM_TOOLSET) = BORLANDC
2777     {
2778         actions updated together piecemeal Archive
2779         {
2780             $(AR) $(<) -+$(>)
2781         }
2783         actions Link bind NEEDLIBS
2784         {
2785             $(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>)
2786         }
2788         actions DllLink bind NEEDLIBS DEFFILENAME
2789         {
2790             $(ILINK) $(LINKFLAGS) $(>) , $(<) ,, $(LINKLIBS:E) $(NEEDLIBS:E) , $(DEFFILENAME)
2791         }
2793         actions DllImplib bind DEFFILENAME
2794         {
2795             $(IMPLIB) -a $(<) $(>) $(DEFFILENAME)
2796         }
2798         actions C++
2799         {
2800             $(C++) -c -o$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2801         }
2803         actions Cc
2804         {
2805             $(CC) -c -o$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2806         }
2807     }
2808     else if $(JAM_TOOLSET) = MINGW
2809     {
2810         actions together piecemeal Archive
2811         {
2812             $(AR) $(<) $(>:T)
2813         }
2815         actions Cc
2816         {
2817             $(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>)
2818         }
2820         actions C++
2821         {
2822             $(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>)
2823         }
2825         actions DllLink bind DEFFILENAME IMPLIBNAME
2826         {
2827             $(LINK) $(LINKFLAGS) -shared -o $(<) $(>) $(DEFFILENAME) -Wl,--out-implib,$(IMPLIBNAME)
2828         }
2829     }
2830     else if $(JAM_TOOLSET) = WATCOM
2831     {
2832         actions together piecemeal Archive
2833         {
2834             $(AR) -q $(<) +-$(>)
2835         }
2837         actions Cc
2838         {
2839             $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Fo=$(<) -I$(STDHDRS) $(>)
2840         }
2842         actions C++
2843         {
2844             $(C++) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Fo=$(<) -I$(STDHDRS) $(>)
2845         }
2847         actions Link bind NEEDLIBS
2848         {
2849             $(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2850         }
2852         actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME
2853         {
2854             $(LINK) $(LINKFLAGS) -l=NT_DLL -"export=$(DEFFILENAME) option implib=$(IMPLIBNAME)" /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2855         }
2857         actions Shell
2858         {
2859             $(CP) $(>) $(<)
2860         }
2861     }
2862     else if $(JAM_TOOLSET) = LCC
2863     {
2864         actions together piecemeal Archive
2865         {
2866             $(AR) /out:$(<) $(>)
2867         }
2869         actions Cc
2870         {
2871             $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -Fo$(<) -I$(STDHDRS) $(>)
2872         }
2874         actions Link bind NEEDLIBS
2875         {
2876             $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2877         }
2879         actions DllLink bind NEEDLIBS DEFFILENAME
2880         {
2881             $(LINK) $(LINKFLAGS) -DLL -o $(<) $(UNDEFS) $(>) $(DEFFILENAME) $(NEEDLIBS) $(LINKLIBS)
2882         }
2884         actions ignore DllLinkMv
2885         {
2886             $(MV) $(2) $(1)
2887         }
2889         actions Shell
2890         {
2891             $(CP) $(>) $(<)
2892         }
2893     }
2894     else if $(JAM_TOOLSET) = DIGITALMARS
2895     {
2896         actions together piecemeal Archive
2897         {
2898             $(AR) $(<) $(>)
2899         }
2901         actions Cc
2902         {
2903             $(CC) -c $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -o$(<) -I$(STDHDRS) $(>)
2904         }
2906         actions C++
2907         {
2908             $(C++) -c $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -o$(<) -I$(STDHDRS) $(>)
2909         }
2911         # note: we don't generate MAP files here !
2912         actions Link bind NEEDLIBS
2913         {
2914             $(LINK) $(LINKFLAGS) $(>),$(<),NUL, $(NEEDLIBS) $(LINKLIBS)
2915         }
2917         # note: we don't generate MAP files here !
2918         actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME
2919         {
2920             $(LINK) $(LINKFLAGS) /IMPLIB:$(IMPLIBNAME) $(>) , $(<) ,NUL, $(LINKLIBS:E) $(NEEDLIBS:E) , $(DEFFILENAME)
2921         }
2923         actions Shell
2924         {
2925             $(CP) $(>) $(<)
2926         }
2927     }
2928     else if $(JAM_TOOLSET) = PELLESC
2929     {
2930         actions together piecemeal Archive
2931         {
2932             $(AR) /OUT:$(<) $(>)
2933         }
2935         actions Cc
2936         {
2937             $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS)   /Fo $(<) -I$(STDHDRS)  $(>)
2938         }
2940         actions Link bind NEEDLIBS
2941         {
2942             $(LINK) $(LINKFLAGS) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS)
2943         }
2945         actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME
2946         {
2947             $(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS)
2948         }
2950         actions Shell
2951         {
2952             $(CP) $(>) $(<)
2953         }
2954     }
2958 # OS2 specific actions
2961 else if $(OS2)
2963     if $(JAM_TOOLSET) = WATCOM
2964     {
2965         actions together piecemeal Archive
2966         {
2967             $(AR) -q $(<) +-$(>)
2968         }
2970         actions Cc
2971         {
2972             $(CC) /Fo=$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2973         }
2975         actions C++
2976         {
2977             $(C++) /Fo=$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2978         }
2980         actions Link bind NEEDLIBS
2981         {
2982             $(LINK) -q $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2983         }
2985         actions Shell
2986         {
2987             $(CP) $(>) $(<)
2988         }
2989     }
2990     else if $(JAM_TOOLSET) = EMX
2991     {
2992         actions together piecemeal Archive
2993         {
2994           $(AR) $(<) $(>:T)
2995         }
2997         actions Cc
2998         {
2999             $(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
3000         }
3002         actions C++
3003         {
3004             $(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
3005         }
3006     }
3010 # VMS specific actions
3013 else if $(VMS)
3015     actions updated together piecemeal Archive
3016     {
3017         lib/replace $(<) $(>[1]) ,$(>[2-])
3018     }
3020     actions Cc
3021     {
3022         $(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
3023     }
3025     actions C++
3026     {
3027         $(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
3028     }
3030     actions piecemeal together existing Clean
3031     {
3032         $(RM) $(>[1]);* ,$(>[2-]);*
3033     }
3035     actions together quietly CreLib
3036     {
3037         if f$search("$(<)") .eqs. "" then lib/create $(<)
3038     }
3040     actions GenFile1
3041     {
3042         mcr $(>[1]) $(<) $(>[2-])
3043     }
3045     actions Link bind NEEDLIBS
3046     {
3047         $(LINK)/exe=$(<) $(LINKFLAGS) $(>:J=,) ,$(NEEDLIBS)/lib ,$(LINKLIBS)
3048     }
3050     actions quietly updated piecemeal together RmTemps
3051     {
3052         $(RM) $(>[1]);* ,$(>[2-]);*
3053     }
3055     actions Shell
3056     {
3057         $(CP) $(>) $(<)
3058     }
3062 # Mac specifc actions
3065 else if $(MAC)
3067     actions together Archive
3068     {
3069         $(LINK) -library -o $(<) $(>)
3070     }
3072     actions Cc
3073     {
3074         set -e MWCincludes $(CCHDRS)
3075         $(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(>)
3076     }
3078     actions C++
3079     {
3080         set -e MWCincludes $(CCHDRS)
3081         $(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(>)
3082     }
3084     actions Link bind NEEDLIBS
3085     {
3086         $(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) "$(LINKLIBS)"
3087     }
3090 if $(WIN98)
3092     actions existing Clean
3093     {
3094         del $(>)
3095     }
3099 # Backwards compatibility with jam 1, where rules were uppercased.
3102 rule BULK { Bulk $(<) : $(>) ; }
3103 rule FILE { File $(<) : $(>) ; }
3104 rule HDRRULE { HdrRule $(<) : $(>) ; }
3105 rule INSTALL { Install $(<) : $(>) ; }
3106 rule LIBRARY { Library $(<) : $(>) ; }
3107 rule LIBS { LinkLibraries $(<) : $(>) ; }
3108 rule LINK { Link $(<) : $(>) ; }
3109 rule MAIN { Main $(<) : $(>) ; }
3110 rule SETUID { Setuid $(<) ; }
3111 rule SHELL { Shell $(<) : $(>) ; }
3112 rule UNDEFINES { Undefines $(<) : $(>) ; }
3114 # Old INSTALL* didn't take dest directory.
3116 rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; }
3117 rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; }
3118 rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; }
3120 # Compatibility with jam 2.2.
3122 rule addDirName { $(<) += [ FDirName $(>) ] ; }
3123 rule makeCommon { FStripCommon $(<) : $(>) ; }
3124 rule _makeCommon { FStripCommon $(<) : $(>) ; }
3125 rule makeDirName { $(<) = [ FDirName $(>) ] ; }
3126 rule makeGrist { $(<) = [ FGrist $(>) ] ; }
3127 rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; }
3128 rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; }
3129 rule makeString { $(<) = $(>:J) ; }
3130 rule makeSubDir { $(<) = [ FSubDir $(>) ] ; }
3131 rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; }
3135 # special package-management rules
3137 # check that the package root directory is set
3138 # otherwise, set it to $HOME/packages by default
3141 # $(1)   : list variable identifier
3142 # $(2)   : new list
3144 rule _PkgAppend
3146   local result = $($(1)) ;
3147   local i ;
3149   for i in $(2)
3150   {
3151     if ! $(i) in $(result)
3152     {
3153       result += $(i) ;
3154     }
3155   }
3156   $(1) = $(result) ;
3160 # $(1)   : list variable identifier
3161 # $(2)   : new list
3163 rule _PkgPrepend
3165   local result = $($(1)) ;
3166   local i ;
3168   for i in $(2)
3169   {
3170     if ! $(i) in $(result)
3171     {
3172       result = $(i) $(result) ;
3173     }
3174   }
3175   $(1) = $(result) ;
3179 # $(1) : Package Name
3180 # $(2) : optional top-level installation directory
3182 rule PkgBegin
3184   if $(_PKG_NAME)
3185   {
3186     Echo "nested package declarations are not allowed. please use"
3187     Exit "PkgEnd to finish" $(_PKG_NAME)"'s declaration" ;
3188   }
3190   if ! $(PACKAGE_ROOT)
3191   {
3192     PACKAGE_ROOT = [ FDirName  $(HOME) packages ] ;
3193     Echo "PACKAGE_ROOT  variable not set, using" $(PACKAGE_ROOT) "directory" ;
3194   }
3196   _PKG_NAME = $(1[1]) ;
3197   _PKG_DESC = [ FDirName $(PACKAGE_ROOT) $(_PKG_NAME).pc ] ;
3198   _PKG_TOP  = $(2) ;
3199   if ! $(_PKG_TOP)
3200   {
3201     _PKG_TOP = [ FDirName $(PACKAGE_ROOT) $(_PKG_NAME) ] ;
3202   }
3204   _PKG_ORG_HDRS       = $(HDRS) ;
3205   _PKG_ORG_DEFINES    = $(DEFINES) ;
3206   _PKG_ORG_LINKLIBS   = $(LINKLIBS) ;
3207   _PKG_ORG_SUBDIRHDRS = $(SUBDIRHDRS) ;
3209    pkg-$(_PKG_NAME)-top = $(_PKG_TOP) ;
3211   _PKG_USES = ;
3212   _PKG_DEFINES = ;
3213   _PKG_INCLUDES = ;
3214   _PKG_LIBS = ;
3215   _PKG_DO_INSTALL = ;
3217   _PKG_ALL_USES = ;
3219   _PkgUpdate ;
3223 rule PkgEnd
3225   if $(_PKG_DO_INSTALL)
3226   {
3227     _PkgGeneratePc $(_PKG_DESC) ;
3228     PKG on $(_PKG_DESC) = $(_PKG_NAME) ;
3229   }
3231   HDRS     = $(_PKG_ORG_HDRS) ;
3232   DEFINES  = $(_PKG_ORG_DEFINES) ;
3233   LINKLIBS = $(_PKG_ORG_LINKLIBS) ;
3235   SUBDIRHDRS = $(_PKG_ORG_SUBDIRHDRS) ;
3237   _PKG_NAME = ;
3238   _PKG_DO_INSTALL = ;
3243 rule _PkgReverse
3245   local p ;
3247   result = $(1[1]) ;
3249   for p in $(1[2-])
3250   {
3251     result = $(p) $(result) ;
3252   }
3253   return $(result) ;
3256 # $(1) : package descriptor file path
3258 rule _PkgGeneratePc
3260   MkDir $(PACKAGE_ROOT) ;
3261   Depends $(1) : $(PACKAGE_ROOT) ;
3262   Depends install : $(1) ;
3263   Clean uninstall : $(1) ;
3264   Always $(1) ;   # always re-install, overwrite old version
3267 if $(UNIX)
3269   actions _PkgGeneratePc
3270   {
3271     echo "# this file was generated automatically - do not edit" > $(1)
3272     echo "pkg-$(PKG)-uses     = $(pkg-$(PKG)-uses) ;" >> $(1)
3273     echo "pkg-$(PKG)-libs     = $(pkg-$(PKG)-libs:Q) ;" >> $(1)
3274     echo "pkg-$(PKG)-defines  = $(pkg-$(PKG)-defines) ;" >> $(1)
3275     echo "pkg-$(PKG)-includes = $(pkg-$(PKG)-includes:Q) ;" >> $(1)
3276     echo "pkg-$(PKG)-ok       = 1 ;" >> $(1)
3277   }
3279 else
3281   actions _PkgGeneratePc
3282   {
3283     echo # this file was generated automatically - do not edit > $(1)
3284     echo pkg-$(PKG)-uses     = $(pkg-$(PKG)-uses) ; >> $(1)
3285     echo pkg-$(PKG)-libs     = $(pkg-$(PKG)-libs:Q) ; >> $(1)
3286     echo pkg-$(PKG)-defines  = $(pkg-$(PKG)-defines) ; >> $(1)
3287     echo pkg-$(PKG)-includes = $(pkg-$(PKG)-includes:Q) ; >> $(1)
3288     echo pkg-$(PKG)-ok       = 1 ; >> $(1)
3289   }
3292 rule PkgInstallPc
3294   # nothing, this is now handled automatically by PkgEnd
3297 # recomputes current package's settings whenever needed
3299 # no arguments
3301 rule _PkgUpdate
3303   local p z ;
3305   _PKG_ALL_DEFINES  = ;
3306   _PKG_ALL_INCLUDES = ;
3307   _PKG_ALL_LIBS     = ;
3308   _PKG_USE_LIBS     = ;
3310   for p in $(_PKG_ALL_USES)
3311   {
3312     _PkgAppend  _PKG_ALL_DEFINES  : $(pkg-$(p)-defines) ;
3313     _PkgAppend  _PKG_ALL_INCLUDES : $(pkg-$(p)-includes)    ;
3314   }
3316   for p in [ _PkgReverse  $(_PKG_ALL_USES) ]
3317   {
3318     local  thelibs = $(pkg-$(p)-libs) ;
3320     _PKG_ALL_LIBS += $(thelibs) ;
3321     _PKG_USE_LIBS += $(thelibs[1]) ;
3322   }
3324   _PkgAppend _PKG_ALL_DEFINES  : $(_PKG_DEFINES) ;
3325   _PkgAppend _PKG_ALL_INCLUDES : $(_PKG_INCLUDES) ;
3327   HDRS     = $(_PKG_ORG_HDRS)     $(_PKG_ALL_INCLUDES) ;
3328   DEFINES  = $(_PKG_ORG_DEFINES)  $(_PKG_ALL_DEFINES) ;
3329   LINKLIBS = $(_PKG_ORG_LINKLIBS) $(_PKG_ALL_LIBS) ;
3331   pkg-$(_PKG_NAME)-includes = $(_PKG_INCLUDES) ;
3332   pkg-$(_PKG_NAME)-defines  = $(_PKG_DEFINES) ;
3333   pkg-$(_PKG_NAME)-uses     = $(_PKG_USES) ;
3334   pkg-$(_PKG_NAME)-libs     = $(_PKG_LIBS) ;
3338 # $(1) : list of packages to use
3339 # $(2) : name of missing packages variable
3341 rule _PkgUses
3343   local p ;
3345   for p in $(1)
3346   {
3347     if ! $(p) in $(_PKG_ALL_USES)
3348     {
3349       local  pcfile = [ FDirName $(PACKAGE_ROOT) $(p).pc ] ;
3351       NoCare $(pcfile) ;
3352       include $(pcfile) ;
3354       if ! $(pkg-$(p)-ok)
3355       {
3356         $(2) += $(p) ;
3357       }
3358       else if $(pkg-$(p)-uses)
3359       {
3360         _PkgUses $(pkg-$(p)-uses) ;
3361       }
3362       _PKG_ALL_USES  +=  $(p) ;
3363     }
3364   }
3368 # $(1) : Package name list
3370 rule PkgUses
3372   local  pkg-missing = ;
3374   _PkgUses $(1) : pkg-missing ;
3376   if $(pkg-missing)
3377   {
3378     Exit "Please install the following required packages:" $(pkg-missing) ;
3379   }
3381   _PkgPrepend _PKG_USES : $(1) ;
3383   _PkgUpdate ;
3387 # $(1) : target directory
3388 # $(2) : list of sources relative to $(3)
3389 # $(3) : top source directory
3391 rule _PkgMakeLocate
3393   local  top = $(3:E=$(DOT)) ;
3394   local  dir file ss ;
3395   local  dirs ;
3397     for ss in $(2)
3398     {
3399     file = [ FDirName $(top) $(ss:G="") ] ;
3400     dir  = $(1) ;
3402     if $(ss:D)
3403     {
3404       dir = [ FDirName $(dir) $(ss:D) ] ;
3405     }
3407       LOCATE on $(ss) = $(1) ;
3408       Depends $(ss) : $(dir) ;
3410     if ! $(dir) in $(dirs)
3411     {
3412       dirs += $(dir) ;
3413     }
3414   }
3416   MkDir $(dirs) ;
3419 # $(1) : target directory
3420 # $(2) : list of source files relative to $(3)
3421 # $(3) : top source directory
3423 rule _PkgInstallInto
3425   # InstallInto dir : sources ;
3426   local sources = $(2) ;
3427   local targets = $(sources:G=$(INSTALLGRIST)) ;
3429   # Arrange for jam install
3430   # Arrange for jam uninstall
3431   # sources are in SEARCH_SOURCE
3432   # targets are in dir
3434   Depends  install : $(targets) ;
3435   Clean uninstall : $(targets) ;
3437   _PkgMakeLocate $(1) : $(targets) : $(3) ;
3439   # For each source, make gristed target name
3440   # and Install, Chmod, Chown, and Chgrp
3442   for s in $(sources)
3443   {
3444     local t = $(s:G=$(INSTALLGRIST)) ;
3446     Depends $(t) : $(s) ;
3448     SEARCH on $(s) = $(3) ;
3450     Install $(t) : $(s) ;
3451     Chmod $(t) ;
3453     if $(OWNER) && $(CHOWN)
3454     {
3455       Chown $(t) ;
3456       OWNER on $(t) = $(OWNER) ;
3457     }
3459     if $(GROUP) && $(CHGRP)
3460     {
3461       Chgrp $(t) ;
3462       GROUP on $(t) = $(GROUP) ;
3463     }
3464   }
3467 # $(1) : target directory
3468 # $(2) : list of source binaries
3469 # $(3) : top source directory
3471 rule _PkgInstallBin
3473   local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;
3475   _PkgInstallInto $(<) : $(_t) : $(3) ;
3476   MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ;
3480 # $(1) : target directory
3481 # $(2) : list of source shells
3482 # $(3) : top source directory
3484 rule _PkgInstallShell
3486   _PkgInstallInto $(1) : $(2) : $(3) ;
3487   MODE on $(2:G=$(INSTALLGRIST)) = $(SHELLMODE) ;
3491 # $(1) : target directory
3492 # $(2) : list of source files
3493 # $(3) : top source directory
3495 rule _PkgInstallFile
3497   _PkgInstallInto $(1) : $(2) : $(3) ;
3498   MODE on $(2:G=$(INSTALLGRIST)) = $(FILEMODE) ;
3501 # $(1) : list of include paths
3503 rule PkgIncludes
3505   _PKG_INCLUDES += $(1) ;
3506   _PkgUpdate ;
3509 rule PkgDefines
3511   _PKG_DEFINES += $(1) ;
3512   _PkgUpdate ;
3515 # $(1) : list of header files
3516 # $(2) : top-level source directory
3517 # $(3) : optional directory suffix
3519 rule PkgInstallHeader
3521   local  dir = [ FDirName $(_PKG_TOP) include ] ;
3523   _PKG_DO_INSTALL = 1 ;
3525   _PkgInstallFile  [ FDirName $(dir) $(3) ] : $(1) : $(2)   ;
3526   _PkgAppend _PKG_INCLUDES : $(dir) ;
3527   _PkgUpdate ;
3530 # $(1) : library name
3532 rule PkgInstallLib
3534   local  lib = $(1:S=$(SUFLIB)) ;
3535   local  dir = [ FDirName $(_PKG_TOP) lib ] ;
3537   _PKG_DO_INSTALL = 1 ;
3539   _PkgInstallFile  $(dir) : $(lib) : $(DOT) ;
3540   _PkgPrepend _PKG_LIBS : [ FDirName $(dir) $(lib) ] ;
3541   _PkgUpdate ;
3545 # $(1) : required library names or link flags
3547 rule PkgNeedLib
3549   _PkgAppend _PKG_LIBS : $(1) ;
3550   _PkgUpdate ;
3554 rule PkgMain
3556     MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
3557     Objects $(>) ;
3558     LINKLIBS on $(<:S=$(SUFEXE)) += $(LINKLIBS) ;
3559     Depends $(<:S=$(SUFEXE)) : $(_PKG_USE_LIBS) ;
3563 # $(1) : list of directories relative to $(2)
3564 # $(2) : top search directory
3565 # $(3) : pattern
3567 rule PkgGlob
3569   local files dir ;
3570   files = [ GLOB [ FDirName $(2) $(1) ] : $(3) ] ;
3571   dir   = [ FDirName $(1) ] ;
3573   return  $(files:D=$(dir)) ;
3577 # Now include the user's Jamfile.
3580 include $(JAMFILE) ;