added check for GCC 4.2+ and "native" CPU type for it
[k8jam.git] / Jambase.old
blobb2bd102080ef9e61b4e53bf8406c0ba8635e9b50
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 THIS_IS_KJAM = "tan" ; # we are using kjam
161 # Initialize variables
165 # OS specific variable settings
168 if $(NT)
170     # the list of supported toolsets on Windows NT and Windows 95/98
171     #
172     local SUPPORTED_TOOLSETS = BORLANDC
173                                VISUALC
174                                VISUALC16
175                                INTELC
176                                WATCOM
177                                MINGW
178                                LCC
179                                DIGITALMARS
180                                PELLESC
181                                ;
183     # if the JAM_TOOLSET environment variable is defined, check that it is
184     # one of our supported values
185     #
186     if $(JAM_TOOLSET)
187     {
188         if ! $(JAM_TOOLSET) in $(SUPPORTED_TOOLSETS)
189         {
190             Echo  "The JAM_TOOLSET environment variable is defined but its value" ;
191             Echo  "is invalid, please use one of the following:" ;
192             Echo  ;
194             for t in $(SUPPORTED_TOOLSETS) { Echo "  " $(t) ; }
195             Exit ;
196         }
197     }
199     # if JAM_TOOLSET is empty, we'll try to detect the toolset from other
200     # environment variables to remain backwards compatible with Jam 2.5
201     #
202     if ! $(JAM_TOOLSET)
203     {
204         if $(BCCROOT)
205         {
206             JAM_TOOLSET  = BORLANDC ;
207             BORLANDC     = $(BCCROOT) ;
208         }
209         else if $(MSVC)
210         {
211             JAM_TOOLSET = VISUALC16 ;
212             VISUALC16   = $(MSVC) ;
213         }
214         else if $(MSVCNT)
215         {
216             JAM_TOOLSET = VISUALC ;
217             VISUALC     = $(MSVCNT) ;
218         }
219         else if $(MINGW)
220         {
221             # MINGW is defined when trying to compile FT-Jam with
222             # classic Jam
223             #
224             JAM_TOOLSET = MINGW ;
225         }
226         else
227         {
228             Echo  "Jam cannot be run because you didn't indicate which compilation toolset" ;
229             Echo  "to use. To do so, define the JAM_TOOLSET environment variable with" ;
230             Echo  "one of the following values:" ;
231             Echo  ;
232             Echo  "   Value       Toolset Description" ;
233             Echo  ;
234             Echo  "   BORLANDC     Borland C++" ;
235             Echo  "   VISUALC      Microsoft Visual C++" ;
236             Echo  "   VISUALC16    Microsoft Visual C++ 16 bit" ;
237             Echo  "   INTELC       Intel C/C++" ;
238             Echo  "   WATCOM       Watcom C/C++" ;
239             Echo  "   MINGW        MinGW (gcc)" ;
240             Echo  "   LCC          Win32-LCC" ;
241             Echo  "   DIGITALMARS  Digital Mars C/C++" ;
242             Echo  "   PELLESC      Pelles C" ;
243             Echo  ;
244             Echo  "The corresponding compiler must be in your path" ;
245             Echo  ;
246             Echo  "  e.g.:  set JAM_TOOLSET=VISUALC" ;
247             Exit  ;
248         }
249     }
251     MV      ?= move /y ;
252     CP      ?= copy ;
253     RM      ?= del /f/q ;
254     RMDIR       ?= rmdir /s/q ;
255     SLASH   ?= \\ ;
256     SUFLIB  ?= .lib ;
257     SUFOBJ  ?= .obj ;
258     SUFEXE  ?= .exe ;
260     SUFLIBSHR ?= .dll ;
262     if $(JAM_TOOLSET) = BORLANDC
263     {
264         Echo "Compiler is Borland C++" ;
266         AR          ?= tlib /C /P64 ;
267         CC          ?= bcc32 ;
268         CCFLAGS     ?= -w- -q -DWIN -tWR -tWM -tWC ;
269         C++         ?= $(CC) ;
270         C++FLAGS    ?= $(CCFLAGS) -P ;
271         LINK        ?= $(CC) ;
272         ILINK       ?= ilink32 -q ;
273         IMPLIB      ?= implib ;
274         LINKFLAGS   ?= $(CCFLAGS) ;
275         STDLIBPATH  ?= $(BORLANDC)\\lib ;
276         STDHDRS     ?= $(BORLANDC)\\include ;
277         NOARSCAN    ?= true ;
278         ILINKLIBS   ?= C0D32.OBJ CW32.LIB IMPORT32.LIB ;
279         PICFLAGS    ?= -tWD ;
280     }
281     else if $(JAM_TOOLSET) = VISUALC16
282     {
283         Echo "Compiler is Microsoft Visual C++ 16 bit" ;
285         AR      ?= lib /nologo ;
286         CC      ?= cl /nologo ;
287         CCFLAGS     ?= /D "\"WIN\"" ;
288         C++     ?= $(CC) ;
289         C++FLAGS    ?= $(CCFLAGS) ;
290         LINK        ?= $(CC) ;
291         LINKFLAGS   ?= $(CCFLAGS) ;
292         LINKLIBS    ?=
293                 $(MSVC)\\lib\\mlibce.lib
294                 $(MSVC)\\lib\\oldnames.lib
295             ;
296         LINKLIBS    ?= ;
297         NOARSCAN    ?= true ;
298         OPTIM       ?= "" ;
299         STDHDRS     ?= $(VISUALC16)\\include ;
300         UNDEFFLAG   ?= "/u _" ;
301     }
302         else if $(JAM_TOOLSET) = VISUALC
303     {
304         # Visual C++ 6.0 uses MSVCDIR
306         MSVCNT      ?= $(MSVCDIR) ;
308         # bury IA64 in the path for the SDK
310         local I ; if $(OSPLAT) = IA64 { I = ia64\\ ; } else { I = "" ; }
312         AR          ?= lib ;
313         AS          ?= masm386 ;
314         CC          ?= cl /nologo ;
315         CCFLAGS     ?= "" ;
316         C++         ?= $(CC) ;
317         C++FLAGS    ?= $(CCFLAGS) ;
318         LINK        ?= link /nologo ;
319         LINKFLAGS   ?= "" ;
320         LINKLIBS    ?=
321                 $(MSVCNT)\\lib\\$(I)libc.lib
322                 $(MSVCNT)\\lib\\$(I)oldnames.lib
323                 $(MSVCNT)\\lib\\$(I)kernel32.lib ;
324         OPTIM       ?= "" ;
325         STDHDRS     ?= $(VISUALC)\\include ;
326         UNDEFFLAG   ?= "/u _" ;
327     }
328     else if $(JAM_TOOLSET) = INTELC
329     {
330         Echo "Compiler is Intel C/C++" ;
332         if ! $(VISUALC)
333         {
334             Echo "As a special exception, when using the Intel C++ compiler, you need" ;
335             Echo "to define the VISUALC environment variable to indicate the location" ;
336             Echo "of your Visual C++ installation. Aborting.." ;
337             Exit ;
338         }
340         AR          ?= lib ;
341         AS          ?= masm386 ;
342         CC          ?= icl /nologo ;
343         CCFLAGS     ?= "" ;
344         C++         ?= $(CC) ;
345         C++FLAGS    ?= $(CCFLAGS) ;
346         LINK        ?= link /nologo ;
347         LINKFLAGS   ?= "" ;
348         LINKLIBS    ?= $(VISUALC)\\lib\\advapi32.lib
349                $(VISUALC)\\lib\\libc.lib
350                $(VISUALC)\\lib\\oldnames.lib
351                $(VISUALC)\\lib\\kernel32.lib ;
352         OPTIM       ?= "" ;
353         STDHDRS     ?= $(INTELC)\include $(VISUALC)\\include ;
354         UNDEFFLAG   ?= "/u _" ;
355     }
356     else if $(JAM_TOOLSET) = WATCOM
357     {
358         Echo "Compiler is Watcom C/C++" ;
360         AR          ?= wlib ;
361         CC          ?= wcc386 ;
362         CCFLAGS     ?= /zq /DWIN32 /I$(WATCOM)\\h ; # zq=quiet
363         C++         ?= wpp386 ;
364         C++FLAGS    ?= $(CCFLAGS) ;
365         CP          ?= copy ;
366         DOT         ?= . ;
367         DOTDOT      ?= .. ;
368         LINK        ?= wcl386 ;
369         LINKFLAGS   ?= /zq ; # zq=quiet
370         LINKLIBS    ?= ;
371         MV          ?= move ;
372         NOARSCAN    ?= true ;
373         OPTIM       ?= ;
374         RM          ?= del /f ;
375         SLASH       ?= \\ ;
376         STDHDRS     ?= $(WATCOM)\\h $(WATCOM)\\h\\nt ;
377         SUFEXE      ?= .exe ;
378         SUFLIB      ?= .lib ;
379         SUFOBJ      ?= .obj ;
380         UNDEFFLAG   ?= "/u _" ;
381         PICFLAGS     = -s ;  # disable stack checks
382     }
383     else if $(JAM_TOOLSET) = MINGW
384     {
385         Echo "Compiler is GCC with Mingw" ;
387         AR              ?= ar -ru ;
388         CC              ?= gcc ;
389         CCFLAGS         ?= "" ;
390         C++             ?= $(CC) ;
391         C++FLAGS        ?= $(CCFLAGS) ;
392         LINK            ?= $(CC) ;
393         LINKFLAGS       ?= "" ;
394         LINKLIBS        ?= "" ;
395         OPTIM           ?= ;
396         SUFOBJ           = .o ;
397         SUFLIB           = .a ;
398         SLASH            = / ;
399 #       NOARSCAN        ?= true ;
400     }
401     else if $(JAM_TOOLSET) = LCC
402     {
403         Echo "Compiler is Win32-LCC" ;
405         AR              ?= lcclib ;
406         CC              ?= lcc ;
407         CCFLAGS         ?= "" ;
408         C++             ?= $(CC) ;
409         C++FLAGS        ?= $(CCFLAGS) ;
410         LINK            ?= lcclnk ;
411         LINKFLAGS       ?= "" ;
412         LINKLIBS        ?= "" ;
413         OPTIM           ?= ;
414         NOARSCAN         = true ;
415     }
416     else if $(JAM_TOOLSET) = DIGITALMARS
417     {
418         Echo "Compiler is Digital Mars C/C++" ;
420         AR              ?= lib -c ;
421         CC              ?= dmc ;
422         CCFLAGS         ?= "" ;
423         C++             ?= $(CC) ;
424         C++FLAGS        ?= $(CCFLAGS) ;
425         LINK            ?= link /nologo ;
426         LINKFLAGS       ?= "/EXETYPE:NT /NOMAP" ;
427         LINKLIBS        ?= USER32.LIB
428                            KERNEL32.LIB
429                            GDI32.LIB ;
430         OPTIM           ?= ;
431         NOARSCAN         = true ;
432         PICFLAGS         = -mn -WD ;
433     }
434     else if $(JAM_TOOLSET) = PELLESC
435     {
436         Echo "Compiler is PellesC" ;
438         AR        ?= polib ;
439         CC        ?= pocc ;
440         CCFLAGS   ?= "" ;
441         LINK      ?= polink ;
442         LINKFLAGS ?= ;
443         LINKLIBS  ?= ;
444         OPTIM     ?= ;
445         NOARSCAN   = true ;
446         LINKLIBS  ?=
447                 crt.lib oldnames.lib Win\\kernel32.lib ;
448     }
449     else
450     {
452 # XXX: We need better comments here !!
454         Exit "On NT, set BCCROOT, MSVCNT, MINGW or MSVC to the root of the"
455              "Borland or Microsoft directories." ;
456     }
458     STDHRS ?= "" ;
460 else if $(OS2)
462     # the list of supported toolsets on OS/2
463     #
464     local SUPPORTED_TOOLSETS = "EMX" "WATCOM" ;
466     # this variable holds the current toolset
467     #
468     TOOLSET = "" ;
470     # if the JAM_TOOLSET environment variable is defined, check that it is
471     # one of our supported values
472     #
473     if $(JAM_TOOLSET)
474     {
475         if ! $(JAM_TOOLSET) in $(SUPPORTED_TOOLSETS)
476         {
477             Echo  "The JAM_TOOLSET environment variable is defined but its value" ;
478             Echo  "is invalid, please use one of the following:" ;
479             Echo  ;
481             for t in $(SUPPORTED_TOOLSETS) { Echo "  " $(t) ; }
482             Exit ;
483         }
484     }
486     # if TOOLSET is empty, we'll try to detect the toolset from other
487     # environment variables to remain backwards compatible with Jam 2.3
488     #
489     if ! $(JAM_TOOLSET)
490     {
491         if $(watcom)
492         {
493             WATCOM   = $(watcom) ;
494             TOOLSET  = WATCOM ;
495         }
496         else
497         {
498             Echo  "Jam cannot be run because you didn't indicate which compilation toolset" ;
499             Echo  "to use. To do so, follow these simple instructions:" ;
500             Echo  ;
501             Echo  "  - define one of the following environment variable, with the" ;
502             Echo  "    appropriate value according to this list:" ;
503             Echo  ;
504             Echo  "   Variable    Toolset                      Description" ;
505             Echo  ;
506             Echo  "   WATCOM      Watcom C/C++                 Watcom install path" ;
507             Echo  "   EMX         EMX (gcc)                    EMX install path" ;
508 ############Echo  "   VISUALAGE   IBM Visual Age C/C++         VisualAge install path" ;
509             Echo  ;
510             Echo  "  - define the JAM_TOOLSET environment variable with the *name*" ;
511             Echo  "    of the toolset variable you want to use." ;
512             Echo  ;
513             Echo  "  e.g.:  set WATCOM=C:\WATCOM" ;
514             Echo  "         set JAM_TOOLSET=WATCOM" ;
515             Echo  ;
516             Exit  ;
517         }
518     }
520     RM       = del /f ;
521     CP       = copy ;
522     MV      ?= move ;
523     DOT     ?= . ;
524     DOTDOT  ?= .. ;
525     SUFLIB  ?= .lib ;
526     SUFOBJ  ?= .obj ;
527     SUFEXE  ?= .exe ;
529     SUFLIBSHR ?= .dll ;
531     if $(JAM_TOOLSET) = WATCOM
532     {
533         AR          ?= wlib ;
534         BINDIR      ?= \\os2\\apps ;
535         CC          ?= wcc386 ;
536         CCFLAGS     ?= /zq /DOS2 /I$(WATCOM)\\h ; # zq=quiet
537         C++         ?= wpp386 ;
538         C++FLAGS    ?= $(CCFLAGS) ;
539         CP          ?= copy ;
540         DOT         ?= . ;
541         DOTDOT      ?= .. ;
542         LINK        ?= wcl386 ;
543         LINKFLAGS   ?= /zq ; # zq=quiet
544         LINKLIBS    ?= ;
545         MV          ?= move ;
546         NOARSCAN    ?= true ;
547         OPTIM       ?= ;
548         RM          ?= del /f ;
549         SLASH       ?= \\ ;
550         STDHDRS     ?= $(WATCOM)\\h ;
551         SUFEXE      ?= .exe ;
552         SUFLIB      ?= .lib ;
553         SUFOBJ      ?= .obj ;
554         UNDEFFLAG   ?= "/u _" ;
555     }
556     else if $(JAM_TOOLSET) = EMX
557     {
558         Echo "Compiler is GCC-EMX" ;
559         AR            ?= ar -ru ;
560         CC            ?= gcc ;
561         CCFLAGS       ?= "" ;
562         C++           ?= $(CC) ;
563         C++FLAGS      ?= $(CCFLAGS) ;
564         LINK          ?= $(CC) ;
565         LINKFLAGS     ?= "" ;
566         LINKLIBS      ?= "" ;
567         OPTIM         ?= ;
568         SUFOBJ         = .o ;
569         SUFLIB         = .a ;
570         UNDEFFLAG     ?= "-U" ;
571         SLASH          = / ;
572     }
573     else
574     {
575         # should never happen
576         Exit  "Sorry, but the $(JAM_TOOLSET) toolset isn't supported for now" ;
577     }
579 else if $(VMS)
581     C++     ?= cxx ;
582     C++FLAGS    ?= ;
583     CC      ?= cc ;
584     CCFLAGS     ?= ;
585     CHMOD       ?= set file/prot= ;
586     CP      ?= copy/replace ;
587     CRELIB      ?= true ;
588     DOT     ?= [] ;
589     DOTDOT      ?= [-] ;
590     EXEMODE     ?= (w:e) ;
591     FILEMODE    ?= (w:r) ;
592     HDRS        ?= ;
593     LINK        ?= link ;
594     LINKFLAGS   ?= "" ;
595     LINKLIBS    ?= ;
596     MKDIR       ?= create/dir ;
597     MV      ?= rename ;
598     OPTIM       ?= "" ;
599     RM      ?= delete ;
600     RUNVMS      ?= mcr ;
601     SHELLMODE   ?= (w:er) ;
602     SLASH       ?= . ;
603     STDHDRS     ?= decc$library_include ;
604     SUFEXE      ?= .exe ;
605     SUFLIB      ?= .olb ;
606     SUFOBJ      ?= .obj ;
608     switch $(OS)
609     {
610     case OPENVMS : CCFLAGS ?= /stand=vaxc ;
611     case VMS     : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ;
612     }
614 else if $(MAC)
616     local OPT ;
618     CW  ?= "{CW}" ;
620     MACHDRS ?=
621         "$(UMACHDRS):Universal:Interfaces:CIncludes"
622         "$(CW):MSL:MSL_C:MSL_Common:Include"
623         "$(CW):MSL:MSL_C:MSL_MacOS:Include" ;
625     MACLIBS ?=
626         "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib"
627         "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib" ;
629     MPWLIBS ?=
630         "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib"
631         "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW.Lib" ;
633     MPWNLLIBS ?=
634         "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_MPWCRuntime_PPC.lib"
635         "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC_MPW(NL).Lib" ;
637     SIOUXHDRS ?= ;
639     SIOUXLIBS ?=
640         "$(CW):MacOS Support:Libraries:Runtime:Libs:MSL_Runtime_PPC.lib"
641         "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_SIOUX_PPC.Lib"
642         "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL_C_PPC.Lib" ;
644     C++     ?= mwcppc ;
645     C++FLAGS    ?= -w off ;
646     CC      ?= mwcppc ;
647     CCFLAGS     ?= -w off ;
648     CP      ?= duplicate -y ;
649     DOT     ?= ":" ;
650     DOTDOT      ?= "::" ;
651     HDRS        ?= $(MACHDRS) $(MPWHDRS) ;
652     LINK        ?= mwlinkppc ;
653     LINKFLAGS   ?= -mpwtool -warn ;
654     LINKLIBS    ?= $(MACLIBS) $(MPWLIBS) ;
655     MKDIR       ?= newfolder ;
656     MV      ?= rename -y ;
657     NOARSCAN    ?= true ;
658     OPTIM       ?= ;
659     RM      ?= delete -y ;
660     SLASH       ?= ":" ;
661     STDHDRS     ?= ;
662     SUFLIB      ?= .lib ;
663     SUFOBJ      ?= .o ;
665 else if $(OS) = BEOS && $(OSPLAT) = PPC
667     AR      ?= mwld -xml -o ;
668     BINDIR      ?= /boot/home/config/bin ;
669     CC      ?= mwcc ;
670     CCFLAGS     ?= -nosyspath ;
671     C++     ?= $(CC) ;
672     C++FLAGS    ?= -nosyspath ;
673     CHMOD       ?= chmod ;
674     CHGRP       ?= chgrp ;
675     CHOWN       ?= chown ;
676     FORTRAN     ?= "" ;
677     LEX     ?= flex ;
678     LIBDIR      ?= /boot/home/config/lib ;
679     LINK        ?= mwld ;
680     LINKFLAGS   ?= "" ;
681     MANDIR      ?= /boot/home/config/man ;
682     NOARSCAN    ?= true ;
683     RANLIB      ?= ranlib ;
684     STDHDRS     ?= /boot/develop/headers/posix ;
685     YACC        ?= bison -y ;
686     YACCGEN     ?= .c ;
687     YACCFILES   ?= y.tab ;
688     YACCFLAGS   ?= -d ;
690 else if $(OS) = BEOS
692     BINDIR      ?= /boot/home/config/bin ;
693     CC      ?= gcc ;
694     C++     ?= $(CC) ;
695     CHMOD       ?= chmod ;
696     CHGRP       ?= chgrp ;
697     CHOWN       ?= chown ;
698     FORTRAN     ?= "" ;
699     LEX     ?= flex ;
700     LIBDIR      ?= /boot/home/config/lib ;
701     LINK        ?= gcc ;
702     MANDIR      ?= /boot/home/config/man ;
703     NOARSCAN    ?= true ;
704     RANLIB      ?= ranlib ;
705     STDHDRS     ?= /boot/develop/headers/posix ;
706     YACC        ?= bison -y ;
707     YACCGEN     ?= .c ;
708     YACCFILES   ?= y.tab ;
709     YACCFLAGS   ?= -d ;
711 else if $(UNIX)
713     switch $(OS)
714     {
715     case AIX :
716     LINKLIBS    ?= -lbsd ;
718     case AMIGA :
719     CC      ?= gcc ;
720     YACC        ?= bison -y ;
722     case CYGWIN :
723     CC      ?= gcc ;
724     CCFLAGS     += -D__cygwin__ ;
725     LEX     ?= flex ;
726     JAMSHELL    ?= sh -c ;
727     RANLIB      ?= "" ;
728     SUFEXE      ?= .exe ;
729     YACC        ?= bison -y ;
731     case DGUX :
732     RANLIB      ?= "" ;
733     RELOCATE    ?= true ;
735     case HPUX :
736     RANLIB      ?= "" ;
738     case INTERIX :
739     CC      ?= gcc ;
740     JAMSHELL    ?= sh -c ;
741     RANLIB      ?= "" ;
743     case IRIX :
744     RANLIB      ?= "" ;
746     case MPEIX :
747     CC      ?= gcc ;
748     C++     ?= gcc ;
749     CCFLAGS     += -D_POSIX_SOURCE ;
750     HDRS        += /usr/include ;
751     RANLIB      ?= "" ;
752     NOARSCAN    ?= true ;
753     NOARUPDATE  ?= true ;
755     case MVS :
756     RANLIB      ?= "" ;
758     case NEXT :
759     AR      ?= libtool -o ;
760     RANLIB      ?= "" ;
762     case MACOSX :
763     C++     ?= c++ ;
764     MANDIR      ?= /usr/local/share/man ;
766     case NCR :
767     RANLIB      ?= "" ;
769     case PTX :
770     RANLIB      ?= "" ;
772     case QNX :
773     AR      ?= wlib ;
774     CC      ?= cc ;
775     CCFLAGS     ?= -Q ; # quiet
776     C++     ?= $(CC) ;
777     C++FLAGS    ?= -Q ; # quiet
778     LINK        ?= $(CC) ;
779     LINKFLAGS   ?= -Q ; # quiet
780     NOARSCAN    ?= true ;
781     RANLIB      ?= "" ;
783     case SCO :
784     RANLIB      ?= "" ;
785     RELOCATE    ?= true ;
787     case SINIX :
788     RANLIB      ?= "" ;
790     case SOLARIS :
791     RANLIB      ?= "" ;
792     AR      ?= "/usr/ccs/bin/ar ru" ;
794     case UNICOS :
795     NOARSCAN    ?= true ;
796     OPTIM       ?= -O0 ;
798     case UNIXWARE :
799     RANLIB      ?= "" ;
800     RELOCATE    ?= true ;
801     }
803     # UNIX defaults
805     CCFLAGS     ?= ;
806     C++FLAGS    ?= $(CCFLAGS) ;
807     CHMOD       ?= chmod ;
808     CHGRP       ?= chgrp ;
809     CHOWN       ?= chown ;
810     LEX         ?= lex ;
811     LINKFLAGS   ?= $(CCFLAGS) ;
812     LINKLIBS    ?= ;
813     #OPTIM       ?= -O ;  # k8: was -O
814     RANLIB      ?= ranlib ;
815     YACC        ?= yacc ;
816     YACCGEN     ?= .c ;
817     YACCFILES   ?= y.tab ;
818     YACCFLAGS   ?= -d ;
820     SUFOBJSHR   ?= .lo ;
821     SUFLIBSHR   ?= .la ;
822     PICFLAGS    ?= -fpic ;
823     STDHDRS     ?= /usr/include ;
826 # shared library object file suffix. We assume that it is identical
827 # than the normal one
828 SUFOBJSHR ?= $(SUFOBJ) ;
829 SUFLIBSHR ?= $(SUFLIB) ;
832 # the D compiler
833 DC ?= dmd ;
836 # General defaults; a lot like UNIX
839     AR      ?= ar ru ;
840     AS      ?= as ;
841     ASFLAGS     ?= ;
842     AWK     ?= awk ;
843     BINDIR      ?= /usr/local/bin ;
844     C++     ?= g++ ;  # k8: was cc
845     C++FLAGS    ?= ;
846     CC      ?= gcc ;  # k8: was cc
847     CCFLAGS     ?= ;
848     CP      ?= cp -f ;
849     CRELIB      ?= ;
850     DOT     ?= . ;
851     DOTDOT      ?= .. ;
852     EXEMODE     ?= 711 ;
853     FILEMODE    ?= 644 ;
854     FORTRAN     ?= f77 ;
855     FORTRANFLAGS    ?= ;
856     HDRS        ?= ;
857     INSTALLGRIST    ?= installed ;
858     JAMFILE     ?= Jamfile ;
859     JAMRULES    ?= Jamrules ;
860     LEX     ?= ;
861     LIBDIR      ?= /usr/local/lib ;
862     LINK        ?= $(CC) ;
863     LINKFLAGS   ?= ;
864     LINKLIBS    ?= ;
865     LN      ?= ln ;
866     MANDIR      ?= /usr/local/man ;
867     MKDIR       ?= mkdir ;
868     MV      ?= mv -f ;
869     OPTIM       ?= ;
870     RCP     ?= rcp ;
871     RM      ?= rm -f ;
872     RMDIR       ?= $(RM) ;
873     RSH     ?= rsh ;
874     SED     ?= sed ;
875     SHELLHEADER ?= "#!/bin/sh" ;
876     SHELLMODE   ?= 755 ;
877     SLASH       ?= / ;
878     SUBDIRRULES     ?= ;
879     SUBDIRRESET     ?= ASFLAGS HDRS C++FLAGS CCFLAGS ;
880     SUFEXE      ?= "" ;
881     SUFLIB      ?= .a ;
882     SUFOBJ      ?= .o ;
883     UNDEFFLAG   ?= "-u _" ;
884     YACC        ?= ;
885     YACCGEN     ?= ;
886     YACCFILES   ?= ;
887     YACCFLAGS   ?= ;
889     HDRPATTERN =
890             "^[   ]*#[  ]*include[  ]*[<\"]([^\">]*)[\">].*$" ;
892     OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;
896 # Base dependencies - first for "bootstrap" kinds of rules
899 Depends all : shell files lib exe obj ;
900 Depends all shell files lib exe obj : first ;
901 NotFile all first shell files lib exe obj dirs clean uninstall ;
902 Always  clean uninstall ;
905 # Rules
908 # /As object : source ;
910 # Assemble the file _source_, called by the @Object rule.
912 # Do not call this rule directly, since _object_ and _source_ may have
913 # have platform-specific file extensions
915 rule As
917     Depends $(<) : $(>) ;
918     ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;
919     ASHDRS on $(<) = [ FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
922 # /Bulk  directory : sources ;
924 # Copies _sources_ into _directory_
926 rule Bulk
928     local i ;
930     for i in $(>)
931     {
932         File $(i:D=$(<)) : $(i) ;
933     }
937 # /Dc object : source ;
939 # Compile the file source into object, usin the D compiler $(DC), its
940 # flags $(DCFLAGS) and $(DOPTIM)
941 # Called by the @Object rule
943 # Do not call this rule directly, since _object_ and _source_ may have
944 # have platform-specific file extensions
946 rule Dc
948     Depends $(<) : $(>) ;
950     # Just to clarify here: this sets the per-target DCFLAGS to
951     # be the current value of (global) DCFLAGS and SUBDIRDCFLAGS.
953     DCFLAGS on $(<) += $(DCFLAGS) $(SUBDIRDCFLAGS) ;
957 # /Cc object : source ;
959 # Compile the file source into object, using the C compiler $(CC), its
960 # flags $(CCFLAGS) and $(OPTIM), and the header file directories $(HDRS).
961 # Called by the @Object rule
963 # Do not call this rule directly, since _object_ and _source_ may have
964 # have platform-specific file extensions
966 rule Cc
968     Depends $(<) : $(>) ;
970     # If the compiler's -o flag doesn't work, relocate the .o
972     if $(RELOCATE)
973     {
974         CcMv $(<) : $(>) ;
975     }
977     # Just to clarify here: this sets the per-target CCFLAGS to
978     # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
979     # CCHDRS and CCDEFS must be reformatted each time for some
980     # compiles (VMS, NT) that malign multiple -D or -I flags.
982     CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ;
984     CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
985     CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
988 # /C++ object : source ;
990 # Compile the C++ source file _source_. Similar to @CC, called by @Object
992 # Do not call this rule directly, since _object_ and _source_ may have
993 # have platform-specific file extensions
995 rule C++
997     Depends $(<) : $(>) ;
999     if $(RELOCATE)
1000     {
1001         CcMv $(<) : $(>) ;
1002     }
1004     C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) ;
1006     CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
1007     CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
1010 # /Chmod target ;
1012 # (Unix and VMS only). Change file permissions on _target_ to target-specific
1013 # $(MODE) value set by @Link, @File, @Install* and @Shell rules
1015 rule Chmod
1017     if $(CHMOD) { Chmod1 $(<) ; }
1020 # /Clean  clean : targets ;
1022 # Removes existing _targets_ when _clean_ is built. clean is not a dependency
1023 # of all, and must be built explicitely for targets to be removed
1026 # /File target : source ;
1028 # Copies _source_ into _target_
1030 rule File
1032     Depends files : $(<) ;
1033     Depends $(<) : $(>) ;
1034     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1035     MODE on $(<) = $(FILEMODE) ;
1036     Chmod $(<) ;
1039 # /Fortran object : source ;
1041 # Compile the Fortran source file _source_. Called by the @Object rule
1043 # Do not call this rule directly, since _obj_ and _source_ may have
1044 # have platform-specific file extensions
1046 rule Fortran
1048     Depends $(<) : $(>) ;
1051 # /GenFile target : image sources ;
1053 # Runs the command "_image_ _target_ _sources_" to create _target_ from
1054 # _sources_ and _image_ (where _image_ is an executable built by the
1055 # @Main rule)
1057 rule GenFile
1059     local _t = [ FGristSourceFiles $(<) ] ;
1060     local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;
1061     Depends $(_t) : $(_s) $(>[2-]) ;
1062     GenFile1 $(_t) : $(_s) $(>[2-]) ;
1063     Clean clean : $(_t) ;
1066 rule GenFile1
1068     MakeLocate $(<) : $(LOCATE_SOURCE) ;
1069     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1072 # /HardLink target : source ;
1074 # Makes _target_ a hard link to _source_, if it isn't one already
1075 # (Unix only)
1077 rule HardLink
1079     Depends files : $(<) ;
1080     Depends $(<) : $(>) ;
1081     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1084 # /HdrMacroFile
1086 # this rule is specific to FT-Jam. It is used to indicate that a given file
1087 # contains definitions for filename macros (e.g. "#define MYFILE_H <myfile>.h")
1088 # that can later be used in #include statements in the rest of the source
1090 # these files must be parsed before any make is tried.
1092 rule HdrMacroFile
1094   HDRMACRO $(<) ;
1097 # /HdrRule source : headers ;
1099 # Arranges the proper dependencies when the file _source_ includes the files
1100 # _headers_ through the #include C preprocessor directive
1102 # this rule is not intendend to be called explicitely. It is called
1103 # automatically during header scanning on sources handled by the @Object
1104 # rule (e.g. sources in @Main or @Library rules)
1106 rule HdrRule
1108     # HdrRule source : headers ;
1110     # N.B.  This rule is called during binding, potentially after
1111     # the fate of many targets has been determined, and must be
1112     # used with caution: don't add dependencies to unrelated
1113     # targets, and don't set variables on $(<).
1115     # Tell Jam that anything depending on $(<) also depends on $(>),
1116     # set SEARCH so Jam can find the headers, but then say we don't
1117     # care if we can't actually find the headers (they may have been
1118     # within ifdefs),
1120     local s = $(>:G=$(HDRGRIST:E)) ;
1122     Includes $(<) : $(s) ;
1123     SEARCH on $(s) = $(HDRSEARCH) ;
1124     NoCare $(s) ;
1126     # Propagate on $(<) to $(>)
1128     HDRSEARCH on $(s) = $(HDRSEARCH) ;
1129     HDRSCAN on $(s) = $(HDRSCAN) ;
1130     HDRRULE on $(s) = $(HDRRULE) ;
1131     HDRGRIST on $(s) = $(HDRGRIST) ;
1135 rule InstallInto
1137     # InstallInto dir : sources ;
1139     local i t ;
1141     t = $(>:G=$(INSTALLGRIST)) ;
1143     # Arrange for jam install
1144     # Arrange for jam uninstall
1145     # sources are in SEARCH_SOURCE
1146     # targets are in dir
1148     Depends install : $(t) ;
1149     Clean uninstall : $(t) ;
1150     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1151     MakeLocate $(t) : $(<) ;
1153     # For each source, make gristed target name
1154     # and Install, Chmod, Chown, and Chgrp
1156     for i in $(>)
1157     {
1158         local tt = $(i:G=$(INSTALLGRIST)) ;
1160         Depends $(tt) : $(i) ;
1161         Install $(tt) : $(i) ;
1162         Chmod $(tt) ;
1164         if $(OWNER) && $(CHOWN)
1165         {
1166         Chown $(tt) ;
1167         OWNER on $(tt) = $(OWNER) ;
1168         }
1170         if $(GROUP) && $(CHGRP)
1171         {
1172         Chgrp $(tt) ;
1173         GROUP on $(tt) = $(GROUP) ;
1174         }
1175     }
1178 # /InstallBin dir : sources ;
1180 # Copy _sources_ into _dir_ with mode $(EXEMODE)
1182 rule InstallBin
1184     local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;
1186     InstallInto $(<) : $(_t) ;
1187     MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ;
1190 # /InstallFile dir : sources ;
1192 # Copy _sources_ into _dir_ with mode $(FILEMODE)
1194 rule InstallFile
1196     InstallInto $(<) : $(>) ;
1197     MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
1200 # /InstallLib dir : sources ;
1202 # Copy _sources_ into _dir_ with mode $(FILEMODE)
1204 rule InstallLib
1206     InstallInto $(<) : $(>) ;
1207     MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
1210 # /InstallLib dir : sources ;
1212 #  Copy _sources_ into the appropriate subdirectory of _dir_ with mode
1213 #  $(FILEMODE). The subdirectory is manS, where S is the suffix of each of
1214 #  sources.
1216 rule InstallMan
1218     # Really this just strips the . from the suffix
1220     local i s d ;
1222     for i in $(>)
1223     {
1224         switch $(i:S)
1225         {
1226         case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;
1227         case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;
1228         case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;
1229         case .n : s = n ; case .man : s = 1 ;
1230         }
1232         d = man$(s) ;
1234         InstallInto $(d:R=$(<)) : $(i) ;
1235     }
1237     MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
1240 # /InstallShell dir : sources ;
1242 # Copy _sources_ into _dir_ with mode $(SHELLMODE)
1244 rule InstallShell
1246     InstallInto $(<) : $(>) ;
1247     MODE on $(>:G=$(INSTALLGRIST)) = $(SHELLMODE) ;
1250 # /Lex source.c : source.l ;
1252 # Process the lex source file _source.l_ and rename the lex.yy.c
1253 # to _source.c_ . Called by the @Object rule
1255 rule Lex
1257     LexMv $(<) : $(>) ;
1258     Depends $(<) : $(>) ;
1259     MakeLocate $(<) : $(LOCATE_SOURCE) ;
1260     Clean clean : $(<) ;
1263 # /Library  library : sources ;
1265 #  Compiles _sources_ and archives them into _library_. The intermediate
1266 #  objects are deleted. Calles @Object and @LibraryFromObjects
1268 #  If @Library is invoked with no suffix on _library_, the $(SUFLIB)
1269 #  suffix is used
1271 rule Library
1273     LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
1274     Objects $(>) ;
1277 # /SharedLibrary  library : sources : def : import ;
1279 # Compiles _sources_ and generates a shared _library_ (i.e. DLL on Windows,
1280 # or shared object on Unix). Calls @SharedObjects and @SharedLibraryFromObjects
1282 # If @SharedLibrary is invoked with no suffix on _library_, then
1283 # $(SUFLIBSHR) suffix is used
1285 # _def_ is the name of the corresponding definition file used to generate
1286 # the library on Windows and OS/2 (ignored otherwise). If undefined, it
1287 # will default to _library_ with the .def suffix
1289 # _import_ is the name of the corresponding import library for Windows
1290 # and OS/2 platforms (ignored otherwise). If undefined, it will default
1291 # to _library_ with the .dll.lib suffix.
1293 rule SharedLibrary
1295   SharedLibraryFromObjects $(<) : $(>:S=$(SUFOBJSHR)) : $(3) : $(4) ;
1296   SharedObjects            $(>) ;
1299 if $(UNIX)
1301   # this rule is used to find the 'libtool' script in the current
1302   # path, this is required when compiling shared objects on Unix
1303   #
1304   rule LibToolFind
1305   {
1306     if $(LIBTOOL) { return $(LIBTOOL) ; }
1308     local  matches = [ Glob $(PATH) : libtool ] ;
1310     if ! $(matches)
1311     {
1312       Exit "could not find 'libtool' program in current path. Aborting !" ;
1313     }
1314     LIBTOOL = $(matches[1]) ;
1316     return $(LIBTOOL) ;
1317   }
1320 # /LibraryFromObjects library : objects ;
1322 # Archives _objects_ into _library_. The _objects_ are then deleted
1324 # If _library_ has no suffix, the $(SUFLIB) suffix is used
1326 # Called by @Library rule. Most people should never call this rule
1327 # directly.
1329 rule LibraryFromObjects
1331     local _i _l _s ;
1333     # Add grist to file names
1335     _s = [ FGristFiles $(>) ] ;
1336     _l = $(<:S=$(SUFLIB)) ;
1338     # library depends on its member objects
1340     if $(KEEPOBJS)
1341     {
1342         Depends obj : $(_s) ;
1343     }
1344     else
1345     {
1346         Depends lib : $(_l) ;
1347     }
1349     # Set LOCATE for the library and its contents.  The bound
1350     # value shows up as $(NEEDLIBS) on the Link actions.
1351     # For compatibility, we only do this if the library doesn't
1352     # already have a path.
1354     if ! $(_l:D)
1355     {
1356         MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;
1357     }
1359     if $(NOARSCAN)
1360     {
1361         # If we can't scan the library to timestamp its contents,
1362         # we have to just make the library depend directly on the
1363         # on-disk object files.
1365         Depends $(_l) : $(_s) ;
1366     }
1367     else
1368     {
1369         # If we can scan the library, we make the library depend
1370         # on its members and each member depend on the on-disk
1371         # object file.
1373         Depends $(_l) : $(_l)($(_s:BS)) ;
1375         for _i in $(_s)
1376         {
1377         Depends $(_l)($(_i:BS)) : $(_i) ;
1378         }
1379     }
1381     Clean clean : $(_l) ;
1383     if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
1385     Archive $(_l) : $(_s) ;
1387     if $(RANLIB) { Ranlib $(_l) ; }
1389     # If we can't scan the library, we have to leave the .o's around.
1391     if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; }
1395 # /SharedLibraryFromObjects  library : objects : def : import ;
1397 # Equivalent of @LibraryFromObjects for shared libraries.
1399 # Called by @SharedLibrary. Most people shouldn't call this rule
1400 # directly
1402 rule SharedLibraryFromObjects
1404     local _i _l _s ;
1406     # Add grist to file names
1408     _s = [ FGristFiles $(>) ] ;
1409     _l = $(<:S=$(SUFLIBSHR)) ;
1411     #Echo "Library is $(_l)"    ;
1412     # library depends on its member objects
1414     if $(KEEPOBJS)
1415     {
1416       Depends obj : $(_s) ;
1417     }
1418     else
1419     {
1420       Depends lib : $(_l) ;
1421     }
1423     # Set LOCATE for the library and its contents.  The bound
1424     # value shows up as $(NEEDLIBS) on the Link actions.
1425     # For compatibility, we only do this if the library doesn't
1426     # already have a path.
1428     if ! $(_l:D)
1429     {
1430         MakeLocate $(_l) : $(LOCATE_TARGET) ;
1431     }
1433     # we never scan shared libraries for member objects
1434     Depends $(_l) : $(_s) ;
1436     Clean clean : $(_l) ;
1438     # I don't know if VMS supports shared libraries, so I prefer
1439     # to disable the following right now
1440     #
1441     #if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
1443     # creating the library is so much fun on Unix :-)
1444     if $(UNIX)
1445     {
1446       local  libtool = [ LibToolFind ] ;  # find the right libtool
1448       AR on $(_l) = "$(libtool) --mode=link $(AR)" ;
1449     }
1450     else if $(NT)
1451     {
1452       local  _implib = $(4) ;
1453       local  _def    = $(3) ;
1455       _implib ?= $(_l:S=$(SUFLIBSHR)$(SUFLIB)) ;
1456       _def    ?= $(_l:S=.def) ;
1458       Clean    clean : $(_implib) ;
1459       Depends  lib   : $(_implib) $(_def) ;
1461       Depends $(_implib) : $(_def) $(_l) ;
1462       Depends $(_l)      : $(_def) ;
1464       DEFFILENAME on $(_l) = $(_def) ;
1465       IMPLIBNAME  on $(_l) = $(_implib) ;
1467       MakeLocate $(_implib)        : $(LOCATE_TARGET) ;
1468       MakeLocate $(_implib:S=.exp) : $(LOCATE_TARGET) ;
1470       if $(JAM_TOOLSET) in VISUALC BORLANDC LCC WATCOM DIGITALMARS
1471       {
1472         SharedLink-$(JAM_TOOLSET) $(_l) : $(_s) : $(_implib) : $(_def) ;
1473       }
1475       DllLink $(_l) : $(_s) ;
1476     }
1477     else
1478     {
1479       Echo "Sorry, I don't know how to make a shared library on your system" ;
1480       Exit "Please contact the KJam maintainer for help" ;
1481     }
1485 # Since building shared libraries is so different depending on the
1486 # compiler being used, I've broken this task into compiler-specific
1487 # ones
1491 # This contains the Visual C++ specific rule used to build a DLL
1492 # and its import library
1494 rule SharedLink-VISUALC
1496   # get rid of the '.exp' file when cleaning
1497   #
1498   Clean  clean : $(3:S=.exp) ;
1502 rule SharedLink-BORLANDC
1504   local  _deffile = $(4) ;
1505   local  _implib  = $(3) ;
1507   LINKFLAGS on $(<) += /x /Gn /Tpd ;
1508   LINKLIBS on $(<) = $(LINKLIBS) $(ILINKLIBS) ;
1510   # Generate import library with the IMPLIB tool !!
1511   #
1512   DllImplib $(_implib) : $(<) ;
1513   Depends   $(_implib) : $(_deffile) $(<) ;
1514   Depends   lib        : $(_implib) ;
1516   DEFFILENAME on $(_implib) = $(_deffile) ;
1518   # clean the TDS file, since the compiler refuses to not generate it !
1519   MakeLocate $(<:S=.tds) : $(LOCATE_TARGET) ;
1520   Clean  clean : $(<:S=.tds) ;
1524 rule SharedLink-LCC
1526   if "" {
1527   #Echo "Sorry, but generating DLLs with LCC is not supported. That's" ;
1528   #Echo "because the 'lcclnk' tool that comes with this compiler is" ;
1529   #Echo "unreliable and doesn't work as expected. For more information" ;
1530   #Echo "contact the FT-Jam maintainer" ;
1531   #Exit ;
1532   }
1534   # the 'lcclnk' tool is absolutely broken:
1535   #   - its -o flag doesn't work when there is a LIBRARY statement
1536   #     in the .def file.
1537   #
1538   #   - it uses the LIBRARY name in the .def file to determine
1539   #     the name of the dll and its import library, and always
1540   #     places them in the current directory !!
1541   #
1542   #   - if there is no LIBRARY statement, the -o flag is only
1543   #     used to determine where the DLL is placed, the import
1544   #     library will always be placed in the current directory !!
1545   #
1547   # clean the .exp file too, don't know how to get rid of it
1548   Clean clean : $(4:S=.exp) ;
1552 rule SharedLink-WATCOM
1554   #Echo "Sorry, but building DLLs with Watcom isn't supported by this tool" ;
1555   #Echo "this comes from the fact that the Watcom linker isn't capable of"  ;
1556   #Echo "using normal .def files" ;
1557   #Exit ;
1559   local  _deffile = $(4) ;
1560   local  _implib  = $(3) ;
1562   IMPLIB on $(<) = $(_implib) ;
1563   DEFFILE on $(<) = $(_deffile) ;
1565   # clean the TDS file, since the compiler refuses to not generate it !
1566   MakeLocate $(<:S=.tds) : $(LOCATE_TARGET) ;
1567   Clean  clean : $(<:S=.tds) ;
1571 rule SharedLink-DIGITALMARS
1573   #Echo "Sorry, but building DLLs with Digital Mars isn't supported at the" ;
1574   #Echo "moment, please contact the FT-Jam maintainers" ;
1575   #Exit ;
1579 # /Link  image : objects ;
1581 # Links _image_ from _objects_ and sets permissions on _image_ to
1582 # $(EXEMODE). _image_ must be an actual filename; suffix is not
1583 # supplied.
1585 # Called by @Main, shouldn't be called by most people
1587 rule Link
1589     MODE on $(<) = $(EXEMODE) ;
1590     Chmod $(<) ;
1593 # /LinkLibraries image : libraries ;
1595 # Makes _image_ depend on _libraries_ and includes them during linking
1597 # _image_ may be referenced without a suffix in this rule invocation.
1598 # @LinkLibraries supplies the suffix
1600 # You should only use this rule with libraries created through the
1601 # @Library rule. For external libraries, use something else (XXX)
1603 rule LinkLibraries
1605     # make library dependencies of target
1606     # set NEEDLIBS variable used by 'actions Main'
1608     local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1610     Depends $(_t) : $(>:S=$(SUFLIB)) ;
1611     NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ;
1614 # /LinkSharedLibraries image : libraries :
1616 # Same as @LinkLibraries, but to link _image_ with shared libraries
1617 # generated through the @SharedLibrary rule
1619 rule LinkSharedLibraries
1621     # make library dependencies of target
1622     # set NEEDLIBS variable used by 'actions Main'
1624     local _t   = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1625     local _ext = $(SUFLIBSHR) ;
1627     if $(NT) || $(OS2)
1628     {
1629       # on NT or OS/2, we need to link agains the import library,
1630       # not the DLL itself !!
1631       #
1632       _ext = $(SUFLIBSHR)$(SUFLIB) ;
1633     }
1634     Depends $(_t) : $(>:S=$(_ext))  ;
1635     NEEDLIBS on $(_t) += $(>:S=$(_ext)) ;
1638 # /Main image : sources ;
1640 # Compiles _sources_ and links them into _image_. Calls @Objects and
1641 # @MainFromObjects.
1643 # _image_ may be supplied without suffix.
1645 rule Main
1647     MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
1648     Objects $(>) ;
1651 # /MainFromObjects image : objects ;
1653 # Links _objects_ into _image_. Dependency of exe.
1654 # @MainFromObjects provides a default suffix for _image_
1656 rule MainFromObjects
1658     local _s _t ;
1660     # Add grist to file names
1661     # Add suffix to exe
1663     _s = [ FGristFiles $(>) ] ;
1664     _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1666     # so 'jam foo' works when it's really foo.exe
1668     if $(_t) != $(<)
1669     {
1670         Depends $(<) : $(_t) ;
1671         NotFile $(<) ;
1672     }
1674     # make compiled sources a dependency of target
1676     Depends exe : $(_t) ;
1677     Depends $(_t) : $(_s) ;
1678     MakeLocate $(_t) : $(LOCATE_TARGET) ;
1680     Clean clean : $(_t) ;
1682     # special case for stupid Borland C++, which always generates a
1683     # .tds file for executables, even when no debug information is needed
1684     #
1685     if $(JAM_TOOLSET) = BORLANDC {
1686       MakeLocate $(_t:S=.tds) : $(LOCATE_TARGET) ;
1687       Clean  clean : $(_t:S=.tds) ;
1688     }
1690     Link $(_t) : $(_s) ;
1693 # /MakeLocate  targets : directory
1695 # Creates _dir_ and causes _target_ to be built into _dir_
1697 # This is done by setting the target-specific variable LOCATE
1698 # on _targets_, and arranges with @MkDir to create the target
1699 # directory
1701 rule MakeLocate
1703     # Note we grist the directory name with 'dir',
1704     # so that directory path components and other
1705     # targets don't conflict.
1707     if $(>)
1708     {
1709         LOCATE on $(<) = $(>) ;
1710         Depends $(<) : $(>[1]:G=dir) ;
1711         MkDir $(>[1]:G=dir) ;
1712     }
1715 # /MkDir  dir ;
1717 # Creates _dir_ and its parent directories
1719 rule MkDir
1721     # Ignore timestamps on directories: we only care if they
1722     # exist.
1724     NoUpdate $(<) ;
1726     # Don't create . or any directory already created.
1728     if $(<:G=) != $(DOT) && ! $($(<)-mkdir)
1729     {
1730         # Cheesy gate to prevent multiple invocations on same dir
1731         # Arrange for jam dirs
1732         # MkDir1 has the actions
1734         $(<)-mkdir = true ;
1735         Depends dirs : $(<) ;
1736         MkDir1 $(<) ;
1738         # Recursively make parent directories.
1739         # $(<:P) = $(<)'s parent, & we recurse until root
1741         local s = $(<:P) ;
1743         # Don't try to create A: or A:\ on windows
1745         if $(NT)
1746         {
1747             switch $(s)
1748             {
1749                 case *:   : s = ;
1750                 case *:\\ : s = ;
1751             }
1752         }
1754         # handle "C:", "C:/", "/cygdrive" and "/cygdrive/" in Cygwin
1755         if $(UNIX) && $(OS) = CYGWIN
1756         {
1757             switch $(s)
1758             {
1759               case ?:   : s = ;
1760               case ?:/  : s = ;
1761               case <dir>/cygdrive   : s = ;
1762               case <dir>/cygdrive/  : s = ;
1763             }
1764         }
1766         if $(s) = $(<)
1767         {
1768         # The parent is the same as the dir.
1769         # We're at the root, which some OS's can't stat, so we mark
1770         # it as NotFile.
1772             NotFile $(s) ;
1773         }
1774         else if $(s:G=)
1775         {
1776         # There's a parent; recurse.
1778         Depends $(<) : $(s) ;
1779         MkDir $(s) ;
1780         }
1781     }
1784 # /Object object : source ;
1786 # Compile s a single _source_ file into _object_. The @Main and @Library
1787 # rules use it to compile sources.
1789 # Causes _source_ to be scanned for #include directives and calls @HdrRule
1790 # to make all included files dependencies of _object_.
1792 # Calls one of the following rules depending on the suffix to do the
1793 # actual compilation:
1795 rule Object
1797     # locate object and search for source, if wanted
1799     Clean clean : $(<) ;
1801     MakeLocate $(<) : $(LOCATE_TARGET) ;
1802     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1804     # Save HDRS for -I$(HDRS) on compile.
1805     # We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers
1806     # in the .c file's directory, but generated .c files (from
1807     # yacc, lex, etc) are located in $(LOCATE_TARGET), possibly
1808     # different from $(SEARCH_SOURCE).
1810     HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;
1812     # handle #includes for source: Jam scans for headers with
1813     # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
1814     # with the scanned file as the target and the found headers
1815     # as the sources.  HDRSEARCH is the value of SEARCH used for
1816     # the found header files.  Finally, if jam must deal with
1817     # header files of the same name in different directories,
1818     # they can be distinguished with HDRGRIST.
1820     # $(SEARCH_SOURCE:E) is where cc first looks for #include
1821     # "foo.h" files.  If the source file is in a distant directory,
1822     # look there.  Else, look in "" (the current directory).
1824     HDRRULE on $(>) = HdrRule ;
1825     HDRSCAN on $(>) = $(HDRPATTERN) ;
1826     HDRSEARCH on $(>) =
1827         $(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ;
1829     HDRGRIST on $(>) = $(HDRGRIST) ;
1831     # propagate target specific-defines
1833     DEFINES on $(<) += $(DEFINES) ;
1835     # if source is not .c, generate .c with specific rule
1837     switch $(>:S)
1838     {
1839         case .asm : As $(<) : $(>) ;
1840         case .c :   Cc $(<) : $(>) ;
1841         case .C :   C++ $(<) : $(>) ;
1842         case .cc :  C++ $(<) : $(>) ;
1843         case .cpp : C++ $(<) : $(>) ;
1844         case .cxx : C++ $(<) : $(>) ;
1845         case .c++ : C++ $(<) : $(>) ;
1846         case .C++ : C++ $(<) : $(>) ;
1847         case .d :   Dc $(<) : $(>) ;
1848         case .f :   Fortran $(<) : $(>) ;
1849         case .l :   Cc $(<) : $(<:S=.c) ;
1850                     Lex $(<:S=.c) : $(>) ;
1851         case .s :   As $(<) : $(>) ;
1852         case .y :   Cc $(<) : $(<:S=$(YACCGEN)) ;
1853                     Yacc $(<:S=$(YACCGEN)) : $(>) ;
1854         case * :    UserObject $(<) : $(>) ;
1855     }
1858 # /ObjectCcFlags  sources : flags ;
1860 # this rule is used to add compiler flags to the compilation of
1861 # specific C sources files.
1863 rule ObjectCcFlags
1865     CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1868 # /ObjectC++Flags  sources : flags ;
1870 # this rule is used to add compiler flags to the compilation of
1871 # specific C++ source files
1873 rule ObjectC++Flags
1875     C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1878 # /ObjectDefines  objects : macros ;
1880 # this rule is used to add macro defines to the compilation of
1881 # specific C and C++ source files
1883 rule ObjectDefines
1885     # must reformat CCDEFS according to current defines
1887     local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;
1889     DEFINES on $(s) += $(>) ;
1890     CCDEFS on $(s) = [ on $(s) FDefines $(DEFINES) ] ;
1893 # /ObjectHdrs  sources : paths ;
1895 # this rule is used to add include paths to the compilation of
1896 # specific C and C++ source files
1898 rule ObjectHdrs
1900     # Add to HDRS for HdrScan's benefit.
1901     # must reformat CCHDRS according to headers
1903     local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;
1905     HDRS on $(s) += $(>) ;
1906     CCHDRS on $(s) = [ on $(s) FIncludes $(HDRS) ] ;
1909 # /Objects sources ;
1911 # this rule is used to compile one or more sources into object files.
1912 # do not call it directly, it is used by the Main and Library rules
1913 # automatically
1915 rule Objects
1917     local _i ;
1919     for _i in [ FGristFiles $(<) ]
1920     {
1921         Object $(_i:S=$(SUFOBJ)) : $(_i) ;
1922         Depends obj : $(_i:S=$(SUFOBJ)) ;
1923     }
1926 # /SharedObjects
1928 # this rule is used to compile one or more sources into 'shared object
1929 # files'. This means object files used to build either DLLs or Unix shared
1930 # libraries.
1932 # do not call this rule directly, it is called by SharedLibrary automatically
1934 rule SharedObjects
1936   # temporarily override SUFOBJ with $(SUFOBJSHR) to
1937   #
1938   local SUFOBJ = $(SUFOBJSHR) ;
1940   # call the normal Objects rule
1941   #
1942   Objects $(<) ;
1944   # add the compiler-specific position-independent-code flag
1945   # where needed
1946   #
1947   ObjectCcFlags $(<) : $(PICFLAGS) ;
1949   # change the compiler invokation for all these objects
1950   # to use Libtool on Unix systems. We explicitely disable the
1951   # generation of static objects here
1952   #
1953   if $(UNIX)
1954   {
1955     libtool on $(<:S=$(SUFOBJ)) = [ LibToolFind ] ;
1956     CC on $(<:S=$(SUFOBJ))      = "$(libtool) --mode=compile $(CC) -dynamic" ;
1957   }
1961 rule RmTemps
1963     Temporary $(>) ;
1966 rule Setuid
1968     MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ;
1971 rule Shell
1973     Depends shell : $(<) ;
1974     Depends $(<) : $(>) ;
1975     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1976     MODE on $(<) = $(SHELLMODE) ;
1977     Clean clean : $(<) ;
1978     Chmod $(<) ;
1981 rule SoftLink
1983     Depends files : $(<) ;
1984     Depends $(<) : $(>) ;
1985     SEARCH on $(>) = $(SEARCH_SOURCE) ;
1986     Clean clean : $(<) ;
1989 rule SubDir
1991     #
1992     # SubDir TOP d1 d2 ... ;
1993     #
1994     # Support for a project tree spanning multiple directories.
1995     #
1996     # SubDir declares a Jamfile's location in a project tree, setting
1997     # Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source
1998     # files can be found.
1999     #
2000     # TOP is a user-select variable name for root of the tree, and
2001     # d1 d2 ...  are the directory elements that lead from the root
2002     # of the tree to the directory of the Jamfile.
2003     #
2004     # TOP can be set externally, but normally the first SubDir call
2005     # computes TOP as the path up from the current directory; the
2006     # path contains one ../ for each of d1 d2 ...
2007     #
2008     # SubDir reads once the project-specific rules file Jamrules
2009     # in the TOP directory, if present.  This can be overridden
2010     # with the variable TOPRULES.
2011     #
2012     # SubDir supports multiple, overlaid project trees:  SubDir
2013     # invocations with different TOPs can appear in the same Jamfile.
2014     # The location established by the first SubDir call is used set
2015     # the TOPs for the subsequent SubDir calls.
2016     #
2017     # SubDir's public variables:
2018     #
2019     #   $(TOP) = path from CWD to root.
2020     #   $(SUBDIR) = path from CWD to the directory SubDir names.
2021     #   $(SUBDIR_TOKENS) = path from $(TOP) to $(SUBDIR) as dir names
2022     #   $(SEARCH_SOURCE) = $(SUBDIR)
2023     #   $(LOCATE_SOURCE) = $(ALL_LOCATE_TARGET) $(SUBDIR)
2024     #   $(LOCATE_TARGET) = $(ALL_LOCATE_TARGET) $(SUBDIR)
2025     #   $(SOURCE_GRIST) = $(SUBDIR_TOKENS) with !'s
2026     #
2028     local _top = $(<[1]) ;
2029     local _tokens = $(<[2-]) ;
2031     #
2032     # First time through sets up relative root and includes Jamrules.
2033     #
2035         if ! $(_top)
2036         {
2037             Exit SubDir syntax error ;
2038         }
2040     if ! $($(_top)-SET)
2041     {
2042         $(_top)-SET = true ;
2044         # First time we've seen this TOP.
2045         # We'll initialize a number of internal variables:
2046         #
2047         #   $(TOP-UP) = directories from ROOT to a common point
2048         #   $(TOP-DOWN) = directories from common point to TOP
2049         #   $(TOP-ROOT) = root directory for UP/DOWN -- normally CWD
2050         #   $(SUBDIR_UP) = current value of $(TOP-UP)
2051         #   $(SUBDIR_DOWN) = current value of $(TOP-DOWN)
2052         #   $(SUBDIR_ROOT) = current value of $(TOP-ROOT)
2053         #
2055         if $($(_top))
2056         {
2057             # TOP externally set.
2058             # We'll ignore the relative (UP/DOWN) path that
2059             # got us here, and instead remember the hard ROOT.
2061             $(_top)-UP = ;
2062             $(_top)-DOWN = ;
2063             $(_top)-ROOT = $($(_top)) ;
2064         }
2065         else
2066     {
2067         # TOP not preset.
2069         # Establishing a new TOP.  In the simplest case,
2070         # (SUBDIR_UP/SUBDIR_DOWN/SUBDIR_ROOT unset), it's
2071         # merely a certain number of directories down from
2072         # the current directory, and FSubDirPath will set
2073         # TOP to a path consisting of ../ for each of the
2074         # elements of _tokens, because that represents how
2075         # far below TOP the current directory sits.
2076         #
2077         # In the more complicated case, the starting directory
2078         # isn't the directory of jam's invocation but an
2079         # location established by previous SubDir call.  The
2080         # starting directory is SUBDIR_UP directories up from
2081         # SUBDIR_ROOT, and then SUBDIR_DOWN directories down
2082         # from that.   If SUBDIR_ROOT is not set, that means
2083         # SUBDIR_DOWN and SUBDIR_UP represent the path from
2084         # the directory of jam's invocation.
2085         #
2086         # In the most complicated case, the _tokens also
2087         # represents directories down, because TOP is being
2088         # estalished in a directory other than TOP's root.
2089         # Hopefully, _tokens and SUBDIR_DOWN represent the
2090         # same final directory, relative to the new TOP and
2091         # the previous SubDIr's TOP.  To find the new TOP,
2092         # we have to chop off any common directories from
2093         # then ends of _tokens and SUBDIR_DOWN.  To do so,
2094         # we reverse each of them, call FStripCommon to
2095         # remove the initial common elements, and then
2096         # reverse them again.  After this process, if
2097         # both _tokens and SUBDIR_DOWN have elements, it
2098         # means the directory names estalished by the two
2099         # SubDir calls don't match, and a warning is issued.
2100         # All hell will likely break loose at this point,
2101         # since the whole SubDir scheme relies on the SubDir
2102         # calls accurately naming the current directory.
2104         # Strip common trailing elements of _tokens and SUBDIR_DOWN.
2106         _tokens = [ FReverse $(_tokens) ] ;
2107         SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
2108         FStripCommon _tokens : SUBDIR_DOWN ;
2109         SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
2110         _tokens = [ FReverse $(_tokens) ] ;
2112         if $(SUBDIR_DOWN) && $(_tokens)
2113         {
2114             Echo Warning: SubDir $(<) misplaced! ;
2115         }
2117         # We'll remember the relative (UP/DOWN) path that
2118         # got us here, plus any hard ROOT starting point
2119         # for the UP/DOWN.  If TOP is never set externally,
2120         # ROOT will always be "" (directory of jam's invocation).
2122         $(_top)-UP = $(SUBDIR_UP) $(_tokens) ;
2123         $(_top)-DOWN = $(SUBDIR_DOWN) ;
2124         $(_top)-ROOT = $(SUBDIR_ROOT:E="") ;
2125         $(_top) = [ FSubDirPath $(_top) ] ;
2126         }
2128         # Set subdir vars for the inclusion of the Jamrules,
2129         # just in case they have SubDir rules of their own.
2130         # Note that SUBDIR_DOWN is empty: it's all the way
2131         # up where the Jamrules live.  These gets overrided
2132         # just after the inclusion.
2134         SUBDIR_UP = $($(_top)-UP) ;
2135         SUBDIR_DOWN = ;
2136         SUBDIR_ROOT = $($(_top)-ROOT) ;
2138         # Include $(TOPRULES) or $(TOP)/Jamrules.
2139         # Include $(TOPRULES) if set.
2140         # Otherwise include $(TOP)/Jamrules if present.
2142         if $($(_top)RULES) {
2143             include $($(_top)RULES) ;
2144         } else {
2145             NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ;
2146             include $(JAMRULES:R=$($(_top)):G=$(_top)) ;
2147         }
2148     }
2150     # Get path from $(TOP) to named directory.
2151     # Save dir tokens for other potential uses.
2153     SUBDIR_UP = $($(_top)-UP) ;
2154     SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ;
2155     SUBDIR_ROOT = $($(_top)-ROOT) ;
2156     SUBDIR_TOKENS = $(SUBDIR_DOWN) ;
2158     SUBDIR = [ FSubDirPath $(<) ] ;
2160     # Now set up SEARCH_SOURCE, LOCATE_TARGET, SOURCE_GRIST
2161     # These can be reset if needed.  For example, if the source
2162     # directory should not hold object files, LOCATE_TARGET can
2163     # subsequently be redefined.
2165     SEARCH_SOURCE = $(SUBDIR) ;
2166     LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
2167     LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
2168     SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ;
2170     # Reset per-directory ccflags, hdrs, etc,
2171     # listed in SUBDIRRESET.
2172     # Note use of variable expanded assignment var
2174     SUBDIR$(SUBDIRRESET) = ;
2176     # Invoke user-specific SubDir extensions,
2177     # rule names listed in SUBDIRRULES.
2178     # Note use of variable expanded rule invocation
2180     $(SUBDIRRULES) $(<) ;
2183 rule FSubDirPath
2185     # FSubDirPath TOP d1 ... ;
2187     # Returns path to named directory.
2189     # If jam is invoked in a subdirectory of the TOP, then we
2190     # need to prepend a ../ for every level we must climb up
2191     # (TOP-UP), and then append the directory names we must
2192     # climb down (TOP-DOWN), plus the named directories d1 ...
2193     # If TOP was set externally, or computed from another TOP
2194     # that was, we'll have to reroot the whole thing at TOP-ROOT.
2196     local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ;
2198     return $(_r:R=$($(<[1])-ROOT)) ;
2201 rule SubDirDcFlags
2203     SUBDIRDCFLAGS += $(<) ;
2206 rule SubDirCcFlags
2208     SUBDIRCCFLAGS += $(<) ;
2211 rule SubDirC++Flags
2213     SUBDIRC++FLAGS += $(<) ;
2216 rule SubDirHdrs
2218     SUBDIRHDRS += [ FDirName $(<) ] ;
2221 rule SubInclude
2223     # SubInclude TOP d1 ... ;
2224     #
2225     # Include a subdirectory's Jamfile.
2227     # We use SubDir to get there, in case the included Jamfile
2228     # either doesn't have its own SubDir (naughty) or is a subtree
2229     # with its own TOP.
2231     if ! $($(<[1]))
2232     {
2233         Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ;
2234     }
2236     SubDir $(<) ;
2238     include $(JAMFILE:D=$(SUBDIR)) ;
2241 rule SubRules
2243     # SubRules TOP d1 ... : Other-TOP ;
2244     #
2245     # Read another tree's Jamrules, by giving it's path according
2246     # to this tree and it's own name.
2248     if ! $($(<[1]))
2249     {
2250         Exit SubRules $(<[1]) without prior SubDir $(<[1]) ;
2251     }
2253     SubDir $(<) ;
2254     SubDir $(>) ;
2257 rule Undefines
2259     UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ;
2262 rule UserObject
2264     Exit "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ;
2267 rule Yacc
2269     local _h ;
2271     _h = $(<:BS=.h) ;
2273     # Some places don't have a yacc.
2275     MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;
2277     if $(YACC)
2278     {
2279         Depends $(<) $(_h) : $(>) ;
2280         Yacc1 $(<) $(_h) : $(>) ;
2281         YaccMv $(<) $(_h) : $(>) ;
2282         Clean clean : $(<) $(_h) ;
2283     }
2285     # make sure someone includes $(_h) else it will be
2286     # a deadly independent target
2288     Includes $(<) : $(_h) ;
2292 # Utility rules; no side effects on these
2295 # /FGrist path to file ;
2297 # Returns a single string that is used as grist
2299 rule FGrist
2301     return $(<:J=!) ;
2306 rule FGristFiles
2308     return $(<:G=$(SOURCE_GRIST:E)) ;
2312 rule FGristSourceFiles
2314     # Produce source file name name with grist in it,
2315     # if SOURCE_GRIST is set.
2317     # Leave header files alone, because they have a global
2318     # visibility.
2320     if ! $(SOURCE_GRIST)
2321     {
2322         return $(<) ;
2323     }
2324     else
2325     {
2326         local _i _o ;
2328         for _i in $(<)
2329         {
2330         switch $(_i)
2331         {
2332         case *.h :  _o += $(_i) ;
2333         case * :    _o += $(_i:G=$(SOURCE_GRIST)) ;
2334         }
2335         }
2337         return $(_o) ;
2338     }
2342 rule FReverse
2344     if $(1) { return [ FReverse $(1[2-]) ] $(1[1]) ; }
2348 rule FSubDir
2350     # If $(>) is the path to the current directory, compute the
2351     # path (using ../../ etc) back to that root directory.
2352     # Sets result in $(<)
2354     if ! $(<[1])
2355     {
2356         return $(DOT) ;
2357     }
2358     else
2359     {
2360         local _i _d ;
2362         _d = $(DOTDOT) ;
2364         for _i in $(<[2-])
2365         {
2366         _d = $(_d:R=$(DOTDOT)) ;
2367         }
2369         return $(_d) ;
2370     }
2374 rule FStripCommon
2376     # FStripCommon v1 : v2 ;
2378     # Strip common initial elements of variables v1 and v2.
2379     # Modifies the variable values themselves.
2381     if $($(<)[1]) && $($(<)[1]) = $($(>)[1])
2382     {
2383         $(<) = $($(<)[2-]) ;
2384         $(>) = $($(>)[2-]) ;
2385         FStripCommon $(<) : $(>) ;
2386     }
2390 rule FRelPath
2392     local _l _r ;
2394     # first strip off common parts
2396     _l = $(<) ;
2397     _r = $(>) ;
2399     FStripCommon _l : _r ;
2401     # now make path to root and path down
2403     _l = [ FSubDir $(_l) ] ;
2404     _r = [ FDirName $(_r) ] ;
2406     # Concatenate and save
2408     # XXX This should be better
2410     if $(_r) = $(DOT) {
2411         return $(_l) ;
2412     } else {
2413         return $(_r:R=$(_l)) ;
2414     }
2418 rule FAppendSuffix
2420        # E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;"
2421        # returns (yacc,lex,foo.bat) on Unix and
2422        # (yacc.exe,lex.exe,foo.bat) on NT.
2424     if $(>)
2425     {
2426         local _i _o ;
2428         for _i in $(<)
2429         {
2430         if $(_i:S)
2431         {
2432             _o += $(_i) ;
2433         }
2434         else
2435         {
2436             _o += $(_i:S=$(>)) ;
2437         }
2438         }
2439         return $(_o) ;
2440     }
2441     else
2442     {
2443         return $(<) ;
2444     }
2448 # Operating system specific utility rules
2449 # First, the (generic) UNIX versions
2452 rule FQuote { return "\\\"$(<)\\\"" ; }
2453 rule FDefines { return -D$(<) ; }
2454 rule FIncludes { return -I$(<) ; }
2456 rule FDirName
2458     # Turn individual elements in $(<) into a usable path.
2460     local _i ;
2461     local _s = $(DOT) ;
2463     for _i in $(<)
2464     {
2465         _s = $(_i:R=$(_s)) ;
2466     }
2468     return $(_s) ;
2471 if $(OS2)
2473     rule FQuote { return "\"$(<)\"" ; }
2474     rule FIncludes { return /I$(<) ; }
2476 else if $(NT) && $(JAM_TOOLSET) != MINGW && $(JAM_TOOLSET) != LCC
2478     rule FDefines { return /D$(<) ; }
2479     rule FIncludes { return /I$(<) ; }
2482 else if $(MAC)
2484     rule FQuote { return "\"$(<)\"" ; }
2485     rule FDefines { return "-define '$(<)'" ; }
2486     rule FIncludes { return "\"$(<:J=,)\"" ; }
2489 else if $(VMS)
2491     rule FQuote { return "\"\"\"$(<)\"\"\"" ; }
2492     rule FDefines { return "/define=( $(<:J=,) )" ; }
2493     rule FIncludes { return "/inc=( $(<:J=,) )" ; }
2495     rule FDirName
2496     {
2497         local _s _i ;
2499         # Turn individual elements in $(<) into a usable path.
2501         if ! $(<)
2502         {
2503             _s = $(DOT) ;
2504         }
2505         else
2506         {
2507             # This handles the following cases:
2508             #   a -> [.a]
2509             #   a b c -> [.a.b.c]
2510             #   x: -> x:
2511             #   x: a -> x:[a]
2512             #   x:[a] b -> x:[a.b]
2514             switch $(<[1])
2515             {
2516                 case *:* :     _s = $(<[1]) ;
2517                 case \\[*\\] : _s = $(<[1]) ;
2518                 case * :       _s = [.$(<[1])] ;
2519             }
2521             for _i in [.$(<[2-])]
2522             {
2523                 _s = $(_i:R=$(_s)) ;
2524             }
2525         }
2527         return $(_s) ;
2528     }
2532 # Actions
2536 # First the defaults
2539 actions updated together piecemeal Archive
2541     $(AR) $(<) $(>)
2544 actions As
2546     $(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>)
2549 actions C++
2551     $(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2554 actions Cc
2556     $(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2559 actions Dc
2561     $(DC) -c -of$(<) $(DCFLAGS) $(DOPTIM) $(>)
2564 actions Chgrp
2566     $(CHGRP) $(GROUP) $(<)
2569 actions Chmod1
2571     $(CHMOD) $(MODE) $(<)
2574 actions Chown
2576     $(CHOWN) $(OWNER) $(<)
2579 actions piecemeal together existing Clean
2581     $(RM) $(>)
2584 actions File
2586     $(CP) $(>) $(<)
2589 actions GenFile1
2591     $(>[1]) $(<) $(>[2-])
2594 actions Fortran
2596     $(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>)
2599 actions HardLink
2601     $(RM) $(<) && $(LN) $(>) $(<)
2604 actions Install
2606     $(CP) $(>) $(<)
2609 actions Lex
2611     $(LEX) $(>)
2614 actions LexMv
2616     $(MV) lex.yy.c $(<)
2619 actions Link bind NEEDLIBS
2621     $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2624 actions MkDir1
2626     $(MKDIR) $(<)
2629 actions together Ranlib
2631     $(RANLIB) $(<)
2634 actions quietly updated piecemeal together RmTemps
2636     $(RM) $(>)
2639 actions Shell
2641     $(AWK) '
2642         NR == 1 { print "$(SHELLHEADER)" }
2643         NR == 1 && /^[#:]/ { next }
2644         /^##/ { next }
2645         { print }
2646     ' < $(>) > $(<)
2649 actions SoftLink
2651     $(RM) $(<) && $(LN) -s $(>) $(<)
2654 actions Yacc1
2656     $(YACC) $(YACCFLAGS) $(>)
2659 actions YaccMv
2661     $(MV) $(YACCFILES).c $(<[1])
2662     $(MV) $(YACCFILES).h $(<[2])
2666 # RELOCATE - for compilers with broken -o flags
2669 if $(RELOCATE)
2671     actions C++
2672     {
2673     $(C++) -c $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2674     }
2676     actions Cc
2677     {
2678     $(CC) -c $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2679     }
2681     actions ignore CcMv
2682     {
2683     [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)
2684     }
2688 # NOARUPDATE - can't update an archive
2691 if $(NOARUPDATE)
2693     actions Archive
2694     {
2695         $(AR) $(<) $(>)
2696     }
2700 # UNIX specific actions
2703 if $(UNIX)
2705     actions GenFile1
2706     {
2707     PATH="$PATH:."
2708     $(>[1]) $(<) $(>[2-])
2709     }
2713 # NT specific actions
2716 if $(NT)
2718     if $(JAM_TOOLSET) = VISUALC || $(JAM_TOOLSET) = INTELC
2719     {
2720         actions updated together piecemeal Archive
2721         {
2722             if exist $(<) set _$(<:B)_=$(<)
2723             $(AR) /out:$(<) %_$(<:B)_% $(>)
2724         }
2726         actions As
2727         {
2728             $(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul;
2729         }
2731         actions Cc
2732         {
2733             $(CC) /c /Fo$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) $(>)
2734         }
2736         actions C++
2737         {
2738             $(C++) /c /Fo$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /I$(STDHDRS) /Tp$(>)
2739         }
2741         actions Link bind NEEDLIBS
2742         {
2743             $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2744         }
2746         actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME
2747         {
2748             $(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2749         }
2750     }
2751     else if $(JAM_TOOLSET) = VISUALC16
2752     {
2753         actions updated together piecemeal Archive
2754         {
2755             $(AR) $(<) -+$(>)
2756         }
2758         actions Cc
2759         {
2760             $(CC) /c /Fo$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2761         }
2763         actions C++
2764         {
2765             $(C++) /c /Fo$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Tp$(>)
2766         }
2768         actions Link bind NEEDLIBS
2769         {
2770             $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2771         }
2773         actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME
2774         {
2775             $(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2776         }
2777     }
2778     else if $(JAM_TOOLSET) = BORLANDC
2779     {
2780         actions updated together piecemeal Archive
2781         {
2782             $(AR) $(<) -+$(>)
2783         }
2785         actions Link bind NEEDLIBS
2786         {
2787             $(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>)
2788         }
2790         actions DllLink bind NEEDLIBS DEFFILENAME
2791         {
2792             $(ILINK) $(LINKFLAGS) $(>) , $(<) ,, $(LINKLIBS:E) $(NEEDLIBS:E) , $(DEFFILENAME)
2793         }
2795         actions DllImplib bind DEFFILENAME
2796         {
2797             $(IMPLIB) -a $(<) $(>) $(DEFFILENAME)
2798         }
2800         actions C++
2801         {
2802             $(C++) -c -o$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2803         }
2805         actions Cc
2806         {
2807             $(CC) -c -o$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2808         }
2809     }
2810     else if $(JAM_TOOLSET) = MINGW
2811     {
2812         actions together piecemeal Archive
2813         {
2814             $(AR) $(<) $(>:T)
2815         }
2817         actions Cc
2818         {
2819             $(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>)
2820         }
2822         actions C++
2823         {
2824             $(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>)
2825         }
2827         actions DllLink bind DEFFILENAME IMPLIBNAME
2828         {
2829             $(LINK) $(LINKFLAGS) -shared -o $(<) $(>) $(DEFFILENAME) -Wl,--out-implib,$(IMPLIBNAME)
2830         }
2831     }
2832     else if $(JAM_TOOLSET) = WATCOM
2833     {
2834         actions together piecemeal Archive
2835         {
2836             $(AR) -q $(<) +-$(>)
2837         }
2839         actions Cc
2840         {
2841             $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Fo=$(<) -I$(STDHDRS) $(>)
2842         }
2844         actions C++
2845         {
2846             $(C++) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) /Fo=$(<) -I$(STDHDRS) $(>)
2847         }
2849         actions Link bind NEEDLIBS
2850         {
2851             $(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2852         }
2854         actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME
2855         {
2856             $(LINK) $(LINKFLAGS) -l=NT_DLL -"export=$(DEFFILENAME) option implib=$(IMPLIBNAME)" /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2857         }
2859         actions Shell
2860         {
2861             $(CP) $(>) $(<)
2862         }
2863     }
2864     else if $(JAM_TOOLSET) = LCC
2865     {
2866         actions together piecemeal Archive
2867         {
2868             $(AR) /out:$(<) $(>)
2869         }
2871         actions Cc
2872         {
2873             $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -Fo$(<) -I$(STDHDRS) $(>)
2874         }
2876         actions Link bind NEEDLIBS
2877         {
2878             $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2879         }
2881         actions DllLink bind NEEDLIBS DEFFILENAME
2882         {
2883             $(LINK) $(LINKFLAGS) -DLL -o $(<) $(UNDEFS) $(>) $(DEFFILENAME) $(NEEDLIBS) $(LINKLIBS)
2884         }
2886         actions ignore DllLinkMv
2887         {
2888             $(MV) $(2) $(1)
2889         }
2891         actions Shell
2892         {
2893             $(CP) $(>) $(<)
2894         }
2895     }
2896     else if $(JAM_TOOLSET) = DIGITALMARS
2897     {
2898         actions together piecemeal Archive
2899         {
2900             $(AR) $(<) $(>)
2901         }
2903         actions Cc
2904         {
2905             $(CC) -c $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -o$(<) -I$(STDHDRS) $(>)
2906         }
2908         actions C++
2909         {
2910             $(C++) -c $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -o$(<) -I$(STDHDRS) $(>)
2911         }
2913         # note: we don't generate MAP files here !
2914         actions Link bind NEEDLIBS
2915         {
2916             $(LINK) $(LINKFLAGS) $(>),$(<),NUL, $(NEEDLIBS) $(LINKLIBS)
2917         }
2919         # note: we don't generate MAP files here !
2920         actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME
2921         {
2922             $(LINK) $(LINKFLAGS) /IMPLIB:$(IMPLIBNAME) $(>) , $(<) ,NUL, $(LINKLIBS:E) $(NEEDLIBS:E) , $(DEFFILENAME)
2923         }
2925         actions Shell
2926         {
2927             $(CP) $(>) $(<)
2928         }
2929     }
2930     else if $(JAM_TOOLSET) = PELLESC
2931     {
2932         actions together piecemeal Archive
2933         {
2934             $(AR) /OUT:$(<) $(>)
2935         }
2937         actions Cc
2938         {
2939             $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS)   /Fo $(<) -I$(STDHDRS)  $(>)
2940         }
2942         actions Link bind NEEDLIBS
2943         {
2944             $(LINK) $(LINKFLAGS) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS)
2945         }
2947         actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME
2948         {
2949             $(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS)
2950         }
2952         actions Shell
2953         {
2954             $(CP) $(>) $(<)
2955         }
2956     }
2960 # OS2 specific actions
2963 else if $(OS2)
2965     if $(JAM_TOOLSET) = WATCOM
2966     {
2967         actions together piecemeal Archive
2968         {
2969             $(AR) -q $(<) +-$(>)
2970         }
2972         actions Cc
2973         {
2974             $(CC) /Fo=$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2975         }
2977         actions C++
2978         {
2979             $(C++) /Fo=$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2980         }
2982         actions Link bind NEEDLIBS
2983         {
2984             $(LINK) -q $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2985         }
2987         actions Shell
2988         {
2989             $(CP) $(>) $(<)
2990         }
2991     }
2992     else if $(JAM_TOOLSET) = EMX
2993     {
2994         actions together piecemeal Archive
2995         {
2996           $(AR) $(<) $(>:T)
2997         }
2999         actions Cc
3000         {
3001             $(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
3002         }
3004         actions C++
3005         {
3006             $(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
3007         }
3008     }
3012 # VMS specific actions
3015 else if $(VMS)
3017     actions updated together piecemeal Archive
3018     {
3019         lib/replace $(<) $(>[1]) ,$(>[2-])
3020     }
3022     actions Cc
3023     {
3024         $(CC)/obj=$(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
3025     }
3027     actions C++
3028     {
3029         $(C++)/obj=$(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
3030     }
3032     actions piecemeal together existing Clean
3033     {
3034         $(RM) $(>[1]);* ,$(>[2-]);*
3035     }
3037     actions together quietly CreLib
3038     {
3039         if f$search("$(<)") .eqs. "" then lib/create $(<)
3040     }
3042     actions GenFile1
3043     {
3044         mcr $(>[1]) $(<) $(>[2-])
3045     }
3047     actions Link bind NEEDLIBS
3048     {
3049         $(LINK)/exe=$(<) $(LINKFLAGS) $(>:J=,) ,$(NEEDLIBS)/lib ,$(LINKLIBS)
3050     }
3052     actions quietly updated piecemeal together RmTemps
3053     {
3054         $(RM) $(>[1]);* ,$(>[2-]);*
3055     }
3057     actions Shell
3058     {
3059         $(CP) $(>) $(<)
3060     }
3064 # Mac specifc actions
3067 else if $(MAC)
3069     actions together Archive
3070     {
3071         $(LINK) -library -o $(<) $(>)
3072     }
3074     actions Cc
3075     {
3076         set -e MWCincludes $(CCHDRS)
3077         $(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(>)
3078     }
3080     actions C++
3081     {
3082         set -e MWCincludes $(CCHDRS)
3083         $(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(>)
3084     }
3086     actions Link bind NEEDLIBS
3087     {
3088         $(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) "$(LINKLIBS)"
3089     }
3092 if $(WIN98)
3094     actions existing Clean
3095     {
3096         del $(>)
3097     }
3101 # Backwards compatibility with jam 1, where rules were uppercased.
3104 rule BULK { Bulk $(<) : $(>) ; }
3105 rule FILE { File $(<) : $(>) ; }
3106 rule HDRRULE { HdrRule $(<) : $(>) ; }
3107 rule INSTALL { Install $(<) : $(>) ; }
3108 rule LIBRARY { Library $(<) : $(>) ; }
3109 rule LIBS { LinkLibraries $(<) : $(>) ; }
3110 rule LINK { Link $(<) : $(>) ; }
3111 rule MAIN { Main $(<) : $(>) ; }
3112 rule SETUID { Setuid $(<) ; }
3113 rule SHELL { Shell $(<) : $(>) ; }
3114 rule UNDEFINES { Undefines $(<) : $(>) ; }
3116 # Old INSTALL* didn't take dest directory.
3118 rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; }
3119 rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; }
3120 rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; }
3122 # Compatibility with jam 2.2.
3124 rule addDirName { $(<) += [ FDirName $(>) ] ; }
3125 rule makeCommon { FStripCommon $(<) : $(>) ; }
3126 rule _makeCommon { FStripCommon $(<) : $(>) ; }
3127 rule makeDirName { $(<) = [ FDirName $(>) ] ; }
3128 rule makeGrist { $(<) = [ FGrist $(>) ] ; }
3129 rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; }
3130 rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; }
3131 rule makeString { $(<) = $(>:J) ; }
3132 rule makeSubDir { $(<) = [ FSubDir $(>) ] ; }
3133 rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; }
3137 # special package-management rules
3139 # check that the package root directory is set
3140 # otherwise, set it to $HOME/packages by default
3143 # $(1)   : list variable identifier
3144 # $(2)   : new list
3146 rule _PkgAppend
3148   local result = $($(1)) ;
3149   local i ;
3151   for i in $(2)
3152   {
3153     if ! $(i) in $(result)
3154     {
3155       result += $(i) ;
3156     }
3157   }
3158   $(1) = $(result) ;
3162 # $(1)   : list variable identifier
3163 # $(2)   : new list
3165 rule _PkgPrepend
3167   local result = $($(1)) ;
3168   local i ;
3170   for i in $(2)
3171   {
3172     if ! $(i) in $(result)
3173     {
3174       result = $(i) $(result) ;
3175     }
3176   }
3177   $(1) = $(result) ;
3181 # $(1) : Package Name
3182 # $(2) : optional top-level installation directory
3184 rule PkgBegin
3186   if $(_PKG_NAME)
3187   {
3188     Echo "nested package declarations are not allowed. please use"
3189     Exit "PkgEnd to finish" $(_PKG_NAME)"'s declaration" ;
3190   }
3192   if ! $(PACKAGE_ROOT)
3193   {
3194     PACKAGE_ROOT = [ FDirName  $(HOME) packages ] ;
3195     Echo "PACKAGE_ROOT  variable not set, using" $(PACKAGE_ROOT) "directory" ;
3196   }
3198   _PKG_NAME = $(1[1]) ;
3199   _PKG_DESC = [ FDirName $(PACKAGE_ROOT) $(_PKG_NAME).pc ] ;
3200   _PKG_TOP  = $(2) ;
3201   if ! $(_PKG_TOP)
3202   {
3203     _PKG_TOP = [ FDirName $(PACKAGE_ROOT) $(_PKG_NAME) ] ;
3204   }
3206   _PKG_ORG_HDRS       = $(HDRS) ;
3207   _PKG_ORG_DEFINES    = $(DEFINES) ;
3208   _PKG_ORG_LINKLIBS   = $(LINKLIBS) ;
3209   _PKG_ORG_SUBDIRHDRS = $(SUBDIRHDRS) ;
3211    pkg-$(_PKG_NAME)-top = $(_PKG_TOP) ;
3213   _PKG_USES = ;
3214   _PKG_DEFINES = ;
3215   _PKG_INCLUDES = ;
3216   _PKG_LIBS = ;
3217   _PKG_DO_INSTALL = ;
3219   _PKG_ALL_USES = ;
3221   _PkgUpdate ;
3225 rule PkgEnd
3227   if $(_PKG_DO_INSTALL)
3228   {
3229     _PkgGeneratePc $(_PKG_DESC) ;
3230     PKG on $(_PKG_DESC) = $(_PKG_NAME) ;
3231   }
3233   HDRS     = $(_PKG_ORG_HDRS) ;
3234   DEFINES  = $(_PKG_ORG_DEFINES) ;
3235   LINKLIBS = $(_PKG_ORG_LINKLIBS) ;
3237   SUBDIRHDRS = $(_PKG_ORG_SUBDIRHDRS) ;
3239   _PKG_NAME = ;
3240   _PKG_DO_INSTALL = ;
3245 rule _PkgReverse
3247   local p ;
3249   result = $(1[1]) ;
3251   for p in $(1[2-])
3252   {
3253     result = $(p) $(result) ;
3254   }
3255   return $(result) ;
3258 # $(1) : package descriptor file path
3260 rule _PkgGeneratePc
3262   MkDir $(PACKAGE_ROOT) ;
3263   Depends $(1) : $(PACKAGE_ROOT) ;
3264   Depends install : $(1) ;
3265   Clean uninstall : $(1) ;
3266   Always $(1) ;   # always re-install, overwrite old version
3269 if $(UNIX)
3271   actions _PkgGeneratePc
3272   {
3273     echo "# this file was generated automatically - do not edit" > $(1)
3274     echo "pkg-$(PKG)-uses     = $(pkg-$(PKG)-uses) ;" >> $(1)
3275     echo "pkg-$(PKG)-libs     = $(pkg-$(PKG)-libs:Q) ;" >> $(1)
3276     echo "pkg-$(PKG)-defines  = $(pkg-$(PKG)-defines) ;" >> $(1)
3277     echo "pkg-$(PKG)-includes = $(pkg-$(PKG)-includes:Q) ;" >> $(1)
3278     echo "pkg-$(PKG)-ok       = 1 ;" >> $(1)
3279   }
3281 else
3283   actions _PkgGeneratePc
3284   {
3285     echo # this file was generated automatically - do not edit > $(1)
3286     echo pkg-$(PKG)-uses     = $(pkg-$(PKG)-uses) ; >> $(1)
3287     echo pkg-$(PKG)-libs     = $(pkg-$(PKG)-libs:Q) ; >> $(1)
3288     echo pkg-$(PKG)-defines  = $(pkg-$(PKG)-defines) ; >> $(1)
3289     echo pkg-$(PKG)-includes = $(pkg-$(PKG)-includes:Q) ; >> $(1)
3290     echo pkg-$(PKG)-ok       = 1 ; >> $(1)
3291   }
3294 rule PkgInstallPc
3296   # nothing, this is now handled automatically by PkgEnd
3299 # recomputes current package's settings whenever needed
3301 # no arguments
3303 rule _PkgUpdate
3305   local p z ;
3307   _PKG_ALL_DEFINES  = ;
3308   _PKG_ALL_INCLUDES = ;
3309   _PKG_ALL_LIBS     = ;
3310   _PKG_USE_LIBS     = ;
3312   for p in $(_PKG_ALL_USES)
3313   {
3314     _PkgAppend  _PKG_ALL_DEFINES  : $(pkg-$(p)-defines) ;
3315     _PkgAppend  _PKG_ALL_INCLUDES : $(pkg-$(p)-includes)    ;
3316   }
3318   for p in [ _PkgReverse  $(_PKG_ALL_USES) ]
3319   {
3320     local  thelibs = $(pkg-$(p)-libs) ;
3322     _PKG_ALL_LIBS += $(thelibs) ;
3323     _PKG_USE_LIBS += $(thelibs[1]) ;
3324   }
3326   _PkgAppend _PKG_ALL_DEFINES  : $(_PKG_DEFINES) ;
3327   _PkgAppend _PKG_ALL_INCLUDES : $(_PKG_INCLUDES) ;
3329   HDRS     = $(_PKG_ORG_HDRS)     $(_PKG_ALL_INCLUDES) ;
3330   DEFINES  = $(_PKG_ORG_DEFINES)  $(_PKG_ALL_DEFINES) ;
3331   LINKLIBS = $(_PKG_ORG_LINKLIBS) $(_PKG_ALL_LIBS) ;
3333   pkg-$(_PKG_NAME)-includes = $(_PKG_INCLUDES) ;
3334   pkg-$(_PKG_NAME)-defines  = $(_PKG_DEFINES) ;
3335   pkg-$(_PKG_NAME)-uses     = $(_PKG_USES) ;
3336   pkg-$(_PKG_NAME)-libs     = $(_PKG_LIBS) ;
3340 # $(1) : list of packages to use
3341 # $(2) : name of missing packages variable
3343 rule _PkgUses
3345   local p ;
3347   for p in $(1)
3348   {
3349     if ! $(p) in $(_PKG_ALL_USES)
3350     {
3351       local  pcfile = [ FDirName $(PACKAGE_ROOT) $(p).pc ] ;
3353       NoCare $(pcfile) ;
3354       include $(pcfile) ;
3356       if ! $(pkg-$(p)-ok)
3357       {
3358         $(2) += $(p) ;
3359       }
3360       else if $(pkg-$(p)-uses)
3361       {
3362         _PkgUses $(pkg-$(p)-uses) ;
3363       }
3364       _PKG_ALL_USES  +=  $(p) ;
3365     }
3366   }
3370 # $(1) : Package name list
3372 rule PkgUses
3374   local  pkg-missing = ;
3376   _PkgUses $(1) : pkg-missing ;
3378   if $(pkg-missing)
3379   {
3380     Exit "Please install the following required packages:" $(pkg-missing) ;
3381   }
3383   _PkgPrepend _PKG_USES : $(1) ;
3385   _PkgUpdate ;
3389 # $(1) : target directory
3390 # $(2) : list of sources relative to $(3)
3391 # $(3) : top source directory
3393 rule _PkgMakeLocate
3395   local  top = $(3:E=$(DOT)) ;
3396   local  dir file ss ;
3397   local  dirs ;
3399     for ss in $(2)
3400     {
3401     file = [ FDirName $(top) $(ss:G="") ] ;
3402     dir  = $(1) ;
3404     if $(ss:D)
3405     {
3406       dir = [ FDirName $(dir) $(ss:D) ] ;
3407     }
3409       LOCATE on $(ss) = $(1) ;
3410       Depends $(ss) : $(dir) ;
3412     if ! $(dir) in $(dirs)
3413     {
3414       dirs += $(dir) ;
3415     }
3416   }
3418   MkDir $(dirs) ;
3421 # $(1) : target directory
3422 # $(2) : list of source files relative to $(3)
3423 # $(3) : top source directory
3425 rule _PkgInstallInto
3427   # InstallInto dir : sources ;
3428   local sources = $(2) ;
3429   local targets = $(sources:G=$(INSTALLGRIST)) ;
3431   # Arrange for jam install
3432   # Arrange for jam uninstall
3433   # sources are in SEARCH_SOURCE
3434   # targets are in dir
3436   Depends  install : $(targets) ;
3437   Clean uninstall : $(targets) ;
3439   _PkgMakeLocate $(1) : $(targets) : $(3) ;
3441   # For each source, make gristed target name
3442   # and Install, Chmod, Chown, and Chgrp
3444   for s in $(sources)
3445   {
3446     local t = $(s:G=$(INSTALLGRIST)) ;
3448     Depends $(t) : $(s) ;
3450     SEARCH on $(s) = $(3) ;
3452     Install $(t) : $(s) ;
3453     Chmod $(t) ;
3455     if $(OWNER) && $(CHOWN)
3456     {
3457       Chown $(t) ;
3458       OWNER on $(t) = $(OWNER) ;
3459     }
3461     if $(GROUP) && $(CHGRP)
3462     {
3463       Chgrp $(t) ;
3464       GROUP on $(t) = $(GROUP) ;
3465     }
3466   }
3469 # $(1) : target directory
3470 # $(2) : list of source binaries
3471 # $(3) : top source directory
3473 rule _PkgInstallBin
3475   local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;
3477   _PkgInstallInto $(<) : $(_t) : $(3) ;
3478   MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ;
3482 # $(1) : target directory
3483 # $(2) : list of source shells
3484 # $(3) : top source directory
3486 rule _PkgInstallShell
3488   _PkgInstallInto $(1) : $(2) : $(3) ;
3489   MODE on $(2:G=$(INSTALLGRIST)) = $(SHELLMODE) ;
3493 # $(1) : target directory
3494 # $(2) : list of source files
3495 # $(3) : top source directory
3497 rule _PkgInstallFile
3499   _PkgInstallInto $(1) : $(2) : $(3) ;
3500   MODE on $(2:G=$(INSTALLGRIST)) = $(FILEMODE) ;
3503 # $(1) : list of include paths
3505 rule PkgIncludes
3507   _PKG_INCLUDES += $(1) ;
3508   _PkgUpdate ;
3511 rule PkgDefines
3513   _PKG_DEFINES += $(1) ;
3514   _PkgUpdate ;
3517 # $(1) : list of header files
3518 # $(2) : top-level source directory
3519 # $(3) : optional directory suffix
3521 rule PkgInstallHeader
3523   local  dir = [ FDirName $(_PKG_TOP) include ] ;
3525   _PKG_DO_INSTALL = 1 ;
3527   _PkgInstallFile  [ FDirName $(dir) $(3) ] : $(1) : $(2)   ;
3528   _PkgAppend _PKG_INCLUDES : $(dir) ;
3529   _PkgUpdate ;
3532 # $(1) : library name
3534 rule PkgInstallLib
3536   local  lib = $(1:S=$(SUFLIB)) ;
3537   local  dir = [ FDirName $(_PKG_TOP) lib ] ;
3539   _PKG_DO_INSTALL = 1 ;
3541   _PkgInstallFile  $(dir) : $(lib) : $(DOT) ;
3542   _PkgPrepend _PKG_LIBS : [ FDirName $(dir) $(lib) ] ;
3543   _PkgUpdate ;
3547 # $(1) : required library names or link flags
3549 rule PkgNeedLib
3551   _PkgAppend _PKG_LIBS : $(1) ;
3552   _PkgUpdate ;
3556 rule PkgMain
3558     MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
3559     Objects $(>) ;
3560     LINKLIBS on $(<:S=$(SUFEXE)) += $(LINKLIBS) ;
3561     Depends $(<:S=$(SUFEXE)) : $(_PKG_USE_LIBS) ;
3565 # $(1) : list of directories relative to $(2)
3566 # $(2) : top search directory
3567 # $(3) : pattern
3569 rule PkgGlob
3571   local files dir ;
3572   files = [ GLOB [ FDirName $(2) $(1) ] : $(3) ] ;
3573   dir   = [ FDirName $(1) ] ;
3575   return  $(files:D=$(dir)) ;
3579 # Now include the user's Jamfile.
3582 include $(JAMFILE) ;