got rid of tabs in Jambase
[k8jam.git] / defaults / Jambase
blobcbd13a724bdc80b167b5d5267a86facccbb4489c
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 #Ketmar's changelog:
42 # [*] windoze support shortened (fuck it! %-)
43 # [-] OS/2 support removed (we'll cry for you...)
44 # [-] VMS support removed (nobody cares)
45 # [-] MAC support removed (should be rewritten!)
46 # [-] BEOS support removed (dead should be dead)
47 # [-] fortran support removed (who need that shit anyway?!)
48 # [+] C++ files will be compiled by g++, not gcc
49 # [+] MainC++ & MainC++FromObjects rules added (g++ linker instead of gcc)
50 # [+] LINKC++, LINKC++FLAGS, LINKC++LIBS, C++OPTIM variables added
51 # [+] LOCATE_BIN variable added (for Main rule)
52 # [+] PATH_SEPARATOR variable added
53 # [+] LOCATE_LIB and LOCATE_LIBSO variables added
54 # [+] xxxC++ renamed to C++xxx
55 # [+] SubIncludeOnce varname : TOP ... ;
56 # [-] xxxC++ rules removed (no need to keep obsolete crap)
57 # [-] aliases for compatibility with jam 2.2 removed
58 # [-] comented out all libtool crap
59 # [+] added rules: LinkFlagsOn, C++LinkFlagsOn, ObjCLinkFlagsOn
61 # Special targets defined in this file:
63 # all       - parent of first, shell, files, lib, exe
64 # first     - first dependent of 'all', for potential initialization
65 # shell     - parent of all Shell targets
66 # files     - parent of all File targets
67 # lib       - parent of all Library targets
68 # exe       - parent of all Main targets
69 # dirs      - parent of all MkDir targets
70 # clean     - removes all Shell, File, Library, and Main targets
71 # uninstall - removes all Install targets
74 # Rules defined by this file:
76 # as obj.o : source.s ;                  .s -> .o
77 # Bulk dir : files ;                     populate directory with many files
78 # Cc obj.o : source.c ;                  .c -> .o
79 # C++ obj.o : source.cc ;                .cc -> .o
80 # Clean clean : sources ;                remove sources with 'jam clean'
81 # File dest : source ;                   copy file
82 # GenFile source.c : program args ;      make custom file
83 # HardLink target : source ;             make link from source to target
84 # HdrRule source : headers ;             handle #includes
85 # InstallInto dir : sources ;            install any files
86 # InstallBin dir : sources ;             install binaries
87 # InstallLib dir : sources ;             install files
88 # InstallFile dir : sources ;            install files
89 # InstallMan dir : sources ;             install man pages
90 # InstallShell dir : sources ;           install shell scripts
91 # Lex source.c : source.l ;              .l -> .c
92 # Library lib : source ;                 archive library from compiled sources
93 # LibraryFromObjects lib : objects ;     archive library from objects
94 # LinkLibraries images : libraries ;     bag libraries onto Mains
95 # Main image : source ;                  link executable from compiled sources
96 # C++Main image : source ;               link c++ executable from compiled sources
97 # ObjC-Main image : source ;             link obj-c executable from compiled sources
98 # MainFromObjects image : objects ;      link executable from objects
99 # C++MainFromObjects image : objects ;   link c++ executable from objects
100 # ObjC-MainFromObjects image : objects ; link obj-c executable from objects
101 # MkDir dir ;                            make a directory, if not there
102 # Object object : source ;               compile object from source
103 # ObjectCcFlags source : flags ;         add compiler flags for object
104 # ObjectC++Flags source : flags ;        add compiler flags for object
105 # ObjectObjCFlags source : flags ;       add compiler flags for object
106 # ObjectHdrs source : dirs ;             add include directories for object
107 # Objects sources ;                      compile sources
108 # RmTemps target : sources ;             remove temp sources after target made
109 # Setuid images ;                        mark executables Setuid
110 # SoftLink target : source ;             make symlink from source to target
111 # SubDir TOP d1 d2 ... ;                 start a subdirectory Jamfile
112 # SubDirCcFlags flags ;                  add compiler flags until next SubDir
113 # SubDirC++Flags flags ;                 add compiler flags until next SubDir
114 # SubDirHdrs d1 d2 ... ;                 add include dir until next SubDir
115 # SubInclude TOP d1 d2 ... ;             include a subdirectory Jamfile
116 # Shell exe : source ;                   make a shell executable
117 # Undefines images : symbols ;           save undef's for linking
118 # UserObject object : source ;           handle unknown suffixes for Object
119 # Yacc source.c : source.y ;             .y -> .c
121 # Utility rules that have no side effects (not supported):
123 # FAppendSuffix f1 f2 ... : $(SUF) ;     return $(<) with suffixes
124 # FDirName d1 d2 ... ;                   return path from root to dir
125 # FGrist d1 d2 ... ;                     return d1!d2!...
126 # FGristFiles value ;                    return $(value:G=$(SOURCE_GRIST))
127 # FGristSourceFiles value ;              return $(value:G=$(SOURCE_GRIST))
128 # FStripCommon v1 : v2 ;                 strip common initial parts of v1 v2
129 # FReverse a1 a2 ... ;                   return ... a2 a1
130 # FRelPath d1 : d2 ;                     return rel path from d1 to d2
131 # FSubDir d1 d2 ... ;                    return path to root
135 # Brief review of the jam language:
137 # Statements:
138 #   rule RULE - statements to process a rule
139 #   actions RULE - system commands to carry out target update
141 # Modifiers on actions:
142 #   together - multiple instances of same rule on target get executed
143 #          once with their sources ($(>)) concatenated
144 #   updated - refers to updated sources ($(>)) only
145 #   ignore - ignore return status of command
146 #   quietly - don't trace its execution unless verbose
147 #   piecemeal - iterate command each time with a small subset of $(>)
148 #   existing - refers to currently existing sources ($(>)) only
149 #   bind vars - subject to binding before expanding in actions
151 # Special rules:
152 #   Always - always build a target
153 #   Depends - builds the dependency graph
154 #   Echo - blurt out targets on stdout
155 #   Exit - blurt out targets and exit
156 #   Includes - marks sources as headers for target (a codependency)
157 #   NoCare - don't panic if the target can't be built
158 #   NoUpdate - create the target if needed but never update it
159 #   NotFile - ignore the timestamp of the target (it's not a file)
160 #   Temporary - target need not be present if sources haven't changed
162 # Special variables set by jam:
163 #   $(<) - targets of a rule (to the left of the :)
164 #   $(>) - sources of a rule (to the right of the :)
165 #   $(xxx) - true on xxx (UNIX, VMS, NT, OS2, MAC)
166 #   $(OS) - name of OS - varies wildly
167 #   $(JAMVERSION) - version number (2.5)
169 # Special variables used by jam:
170 #   SEARCH - where to find something (used during binding and actions)
171 #   LOCATE - where to plop something not found with SEARCH
172 #   HDRRULE - rule to call to handle include files
173 #   HDRSCAN - egrep regex to extract include files
175 # Special targets:
176 #   all - default if none given on command line
179 # for perforce use -- jambase version
181 #JAMBASEDATE = 2004.10.07 ;
183 #THIS_IS_KJAM = "tan" ; # we are using kjam; removed as obsolete
184 THIS_IS_K8JAM = "tan" ; # we are using k8jam
186 # set to 'tan' for old 'libtool' behavior
187 #!LIBTOOL!#K8_USE_LIBTOOL = ;
190 # Initialize variables
193 ###############################################################################
194 # special values
195 ###############################################################################
197 OPTIM_SPEED = -O3 -march=pentium3 -mtune=pentium3 -mfpmath=sse ;
198 #OPTIM_SPEED = -O3 -march=prescott -mtune=prescott -mfpmath=sse ;
199 LINKFLAGS_SPEED = -s ;
201 OPTIM_SIZE = -Os -march=i586 ;
202 LINKFLAGS_SIZE = -s ;
204 OPTIM_DEBUG = -O0 -g ;
205 LINKFLAGS_DEBUG = -g ;
207 OPTIM_NOALIAS = -fno-strict-aliasing ;
211 # OS specific variable settings
214 ###############################################################################
215 # Windoze
216 ###############################################################################
217 if $(NT) {
218   PATH_SEPARATOR = "\\" ;
219   local SUPPORTED_TOOLSETS =
220     MINGW
221     LCC
222     PELLESC
223   ;
225   # if the JAM_TOOLSET environment variable is defined, check that it is
226   # one of our supported values
227   #
228   if $(JAM_TOOLSET) {
229     if ! $(JAM_TOOLSET) in $(SUPPORTED_TOOLSETS) {
230       Echo "The JAM_TOOLSET environment variable is defined but its value" ;
231       Echo "is invalid, please use one of the following:" ;
232       Echo ;
233       for t in $(SUPPORTED_TOOLSETS) { Echo "  " $(t) ; }
234       Exit ;
235     }
236   }
238   if ! $(JAM_TOOLSET) {
239     Echo "The JAM_TOOLSET environment variable is not defined, defaults to MINGW" ;
240     JAM_TOOLSET = MINGW ;
241     MINGW = "c:\\mingw\\" ;
242   }
244   MV        ?= move /y ;
245   CP        ?= copy ;
246   RM        ?= del /f/q ;
247   RMDIR     ?= rmdir /s/q ;
248   SLASH     ?= \\ ;
249   SUFLIB    ?= .lib ;
250   SUFOBJ    ?= .obj ;
251   SUFEXE    ?= .exe ;
252   SUFLIBSHR ?= .dll ;
254   if $(JAM_TOOLSET) = MINGW {
255     Echo "Compiler is GCC with MinGW" ;
256     AR           ?= ar -ru ;
257     RANLIB       ?= ranlib ;
258     CC           ?= mingw-gcc ;
259     CCFLAGS      ?= "" ;
260     C++          ?= mingw-g++ ;
261     C++FLAGS     ?= $(CCFLAGS) ;
262     LINK         ?= $(CC) ;
263     LINKFLAGS    ?= "" ;
264     LINKLIBS     ?= -lkernel32 ;
265     OPTIM        ?= ;
266     SUFOBJ        = .o ;
267     SUFLIB        = .a ;
268     SLASH         = / ;
269     # MinGW-specific thingy
270     MINGW_GUI     = "-Wl,-subsystem,windows" ;
271     MINGW_THREADS = "-mthreads" ;
272     # k8
273     C++OPTIM     ?= $(OPTIM) ;
274     C++LINK      ?= $(C++) ;
275     C++LINKFLAGS ?= $(LINKFLAGS) ;
276     C++LINKLIBS  ?= $(LINKLIBS) ;
277     #NOARSCAN     ?= true ;
278     # set path if any
279     if $(MINGW) {
280       CC = "$(MINGW)$(CC:J= )" ;
281       C++ = "$(MINGW)$(C++:J= )" ;
282       LINK = "$(MINGW)$(LINK:J= )" ;
283       C++LINK = "$(MINGW)$(C++LINK:J= )" ;
284       AR = "$(MINGW)$(AR:J= )" ;
285       RANLIB = "$(MINGW)$(RANLIB:J= )" ;
286     }
287   } else if $(JAM_TOOLSET) = LCC {
288     Echo "Compiler is Win32-LCC" ;
289     AR        ?= lcclib ;
290     CC        ?= lcc ;
291     CCFLAGS   ?= "" ;
292     C++       ?= "error" ;
293     LINK      ?= lcclnk ;
294     LINKFLAGS ?= "" ;
295     LINKLIBS  ?= "" ;
296     OPTIM     ?= ;
297     NOARSCAN   = true ;
298     # k8
299     C++LINK    = "error" ;
300   } else if $(JAM_TOOLSET) = PELLESC {
301     Echo "Compiler is PellesC" ;
302     AR        ?= polib ;
303     CC        ?= pocc ;
304     CCFLAGS   ?= "" ;
305     C++       ?= "error" ;
306     LINK      ?= polink ;
307     LINKFLAGS ?= ;
308     LINKLIBS  ?= ;
309     OPTIM     ?= ;
310     NOARSCAN   = true ;
311     LINKLIBS  ?= crt.lib oldnames.lib Win\\kernel32.lib ;
312     # k8
313     C++LINK    = "error" ;
314   } else {
315     # XXX: We need better comments here !!
316     Exit "On NT, set MINGW to the root of the MinGW dir (but it won't help you anyway)" ;
317   }
318   STDHRS ?= "" ;
319   PICFLAGS = ;
321 ###############################################################################
322 # UNIX
323 ###############################################################################
324 else if $(UNIX) {
325   PATH_SEPARATOR = "/" ;
326   switch $(OS) {
327     case CYGWIN :
328       CC       ?= gcc ;
329       CCFLAGS  += -D__cygwin__ ;
330       LEX      ?= flex ;
331       JAMSHELL ?= sh -c ;
332       RANLIB   ?= "" ;
333       SUFEXE   ?= .exe ;
334       YACC     ?= bison -y ;
335     }
337     # UNIX defaults
338     CC        ?= gcc ;
339     C++       ?= g++ ;
340     OBJCC     ?= gcc ;
341     CCFLAGS   ?= ;
342     OBJCFLAGS ?= $(CCFLAGS) ;
343     C++FLAGS  ?= $(CCFLAGS) ;
344     CHMOD     ?= chmod ;
345     CHGRP     ?= chgrp ;
346     CHOWN     ?= chown ;
347     LEX       ?= flex ;
348     LINKFLAGS ?= $(CCFLAGS) ;
349     LINKLIBS  ?= ;
350     OPTIM     ?= ;
351     RANLIB    ?= ranlib ;
352     YACC      ?= bison ;
353     YACCGEN   ?= .c ;
354     YACCFILES ?= y.tab ;
355     YACCFLAGS ?= -ld ;
356 #!LIBTOOL!#    if $(K8_USE_LIBTOOL) {
357 #!LIBTOOL!#      SUFOBJSHR ?= .lo ;
358 #!LIBTOOL!#      SUFLIBSHR ?= .la ;
359 #!LIBTOOL!#    } else {
360 #!LIBTOOL!#      SUFOBJSHR ?= .o ;
361 #!LIBTOOL!#      SUFLIBSHR ?= .so ;
362 #!LIBTOOL!#    }
363     SUFOBJSHR ?= .o ;
364     SUFLIBSHR ?= .so ;
365 #!LIBTOOL!#
366     PICFLAGS  ?= -fpic ;
367     STDHDRS   ?= /usr/include ;
369   if $(WINDOZE) {
370     PICFLAGS = ;
371     SUFLIBSHR = .dll ;
372     #WINDOZE_THREADS = -mthreads ;
373     #WINDOZE_THREADS = ;
374     WINE ?= "wine" ;
375     MGPATH ?= "c:\\\\mingw\\\\bin\\\\" ;
376     MGCC ?= "mingw32-gcc.exe" ;
377     MG++ ?= "mingw32-g++.exe -static-libgcc" ;
378     CC = "$(WINE)" $(MGPATH)$(MGCC) ;
379     LINK = "$(WINE)" $(MGPATH)$(MGCC) -Wl,--enable-auto-import ;
380     AR = "$(WINE)" $(MGPATH)ar.exe -ru ;
381     RANLIB = "$(WINE)" $(MGPATH)ranlib.exe ;
382     C++ = "$(WINE)" $(MGPATH)$(MG++) ;
383     C++LINK = "$(WINE)" $(MGPATH)$(MG++) -Wl,--enable-auto-import ;
384     #LINKLIBS += -lkernel32 ;
385     #LINKLIBS += -luser32 ;
386     #LINKLIBS += -ladvapi32 ;
387     #LINKLIBS += -lws2_32 ;
388     #WINSUBSYS = "windows" ;
389     #WINSUBSYS = "console" ;
390     SUFEXE = .exe ;
391     #LINKFLAGS += "-Wl,-subsystem,$(WINSUBSYS)" ;
392   }
395 # shared library object file suffix. We assume that it is identical
396 # than the normal one
397 SUFOBJSHR ?= $(SUFOBJ) ;
398 SUFLIBSHR ?= $(SUFLIB) ;
401 # the D compiler
402 DC ?= dmd ;
405 # General defaults; a lot like UNIX
407 PATH_SEPARATOR ?= "/" ;
408 AR          ?= ar ru ;
409 AS          ?= as ;
410 ASFLAGS     ?= ;
411 AWK         ?= awk ;
412 BINDIR      ?= /usr/local/bin ;
413 C++         ?= g++ ;  # k8: was cc
414 C++FLAGS    ?= ;
415 CC          ?= gcc ;  # k8: was cc
416 CCFLAGS     ?= ;
417 CP          ?= cp -f ;
418 CRELIB      ?= ;
419 DOT         ?= . ;
420 DOTDOT      ?= .. ;
421 EXEMODE     ?= 755 ;
422 FILEMODE    ?= 644 ;
423 HDRS        ?= ;
424 INSTALLGRIST    ?= installed ;
425 JAMFILE     ?= Jamfile ;
426 JAMRULES    ?= Jamrules ;
427 LEX         ?= ;
428 LIBDIR      ?= /usr/local/lib ;
429 LINK        ?= $(CC) ;
430 LINKFLAGS   ?= ;
431 LINKLIBS    ?= ;
432 LN          ?= ln ;
433 MANDIR      ?= /usr/local/man ;
434 MKDIR       ?= mkdir ;
435 MV          ?= mv -f ;
436 OPTIM       ?= ;
437 RCP         ?= rcp ;
438 RM          ?= rm -f ;
439 RMDIR       ?= $(RM) ;
440 RSH         ?= rsh ;
441 SED         ?= sed ;
442 SHELLHEADER ?= "#!/bin/sh" ;
443 SHELLMODE   ?= 755 ;
444 SLASH       ?= / ;
445 SUBDIRRULES ?= ;
446 SUBDIRRESET ?= ASFLAGS HDRS C++FLAGS CCFLAGS ;
447 SUFEXE      ?= "" ;
448 SUFLIB      ?= .a ;
449 SUFOBJ      ?= .o ;
450 UNDEFFLAG   ?= "-u _" ;
451 YACC        ?= ;
452 YACCGEN     ?= ;
453 YACCFILES   ?= ;
454 YACCFLAGS   ?= ;
456 HDRPATTERN = "^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]*)[\">].*$" ;
458 OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;
460 # k8
461 C++OPTIM     ?= $(OPTIM) ;
462 C++LINK      ?= $(C++) ;
463 C++LINKFLAGS ?= $(LINKFLAGS) ;
464 C++LINKLIBS  ?= $(LINKLIBS) ;
466 OBJCOPTIM     ?= $(OPTIM) ;
467 OBJCLINK      ?= $(CC) ;
468 OBJCLINKFLAGS ?= $(LINKFLAGS) ;
469 OBJCLINKLIBS  ?= $(LINKLIBS) ;
470 OBJCLINKLIBS  += -lobjc ;
472 if $(OS) = "LINUX" {
473   if ( "gcc" in $(CC) ) && ! ( "-pipe" in $(CC) ) { CC += -pipe ; }
474   if ( "g++" in $(C++) ) && ! ( "-pipe" in $(C++) ) { C++ += -pipe ; }
477 #Echo "OS:" $(OS) ;
478 #Echo "OSFULL:" $(OSFULL) ;
479 #Echo "UNIX:" $(UNIX) ;
484 # Base dependencies - first for "bootstrap" kinds of rules
486 Depends all : shell files lib exe obj ;
487 Depends all shell files lib exe obj : first ;
488 NotFile all first shell files lib exe obj dirs clean uninstall ;
489 Always  clean uninstall ;
492 # Rules
495 # /As object : source ;
497 # Assemble the file _source_, called by the @Object rule.
499 # Do not call this rule directly, since _object_ and _source_ may have
500 # have platform-specific file extensions
502 rule As {
503   Depends $(<) : $(>) ;
504   ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;
505   ASHDRS on $(<) = [ FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
508 # /Bulk  directory : sources ;
510 # Copies _sources_ into _directory_
512 rule Bulk {
513   local i ;
515   for i in $(>) {
516     File $(i:D=$(<)) : $(i) ;
517   }
521 # /Dc object : source ;
523 # Compile the file source into object, usin the D compiler $(DC), its
524 # flags $(DCFLAGS) and $(DOPTIM)
525 # Called by the @Object rule
527 # Do not call this rule directly, since _object_ and _source_ may have
528 # have platform-specific file extensions
530 rule Dc {
531   Depends $(<) : $(>) ;
532   # Just to clarify here: this sets the per-target DCFLAGS to
533   # be the current value of (global) DCFLAGS and SUBDIRDCFLAGS.
534   DCFLAGS on $(<) += $(DCFLAGS) $(SUBDIRDCFLAGS) ;
538 # /Cc object : source ;
540 # Compile the file source into object, using the C compiler $(CC), its
541 # flags $(CCFLAGS) and $(OPTIM), and the header file directories $(HDRS).
542 # Called by the @Object rule
544 # Do not call this rule directly, since _object_ and _source_ may have
545 # have platform-specific file extensions
547 rule Cc {
548   Depends $(<) : $(>) ;
550   # If the compiler's -o flag doesn't work, relocate the .o
551   if $(RELOCATE) { CcMv $(<) : $(>) ; }
553   # Just to clarify here: this sets the per-target CCFLAGS to
554   # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
555   # CCHDRS and CCDEFS must be reformatted each time for some
556   # compiles (VMS, NT) that malign multiple -D or -I flags.
557   CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ;
558   CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
559   CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
563 # /C++ object : source ;
565 # Compile the C++ source file _source_. Similar to @CC, called by @Object
567 # Do not call this rule directly, since _object_ and _source_ may have
568 # have platform-specific file extensions
570 rule C++ {
571   local ktmp ;
573   Depends $(<) : $(>) ;
575   if $(RELOCATE) { CcMv $(<) : $(>) ; }
577   # Just to clarify here: this sets the per-target CCFLAGS to
578   # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
579   # CCHDRS and CCDEFS must be reformatted each time for some
580   # compiles (VMS, NT) that malign multiple -D or -I flags.
581   ktmp = $(C++FLAGS) ;
582   if ! $(ktmp) { ktmp = $(CCFLAGS) ; }
583   C++FLAGS on $(<) += $(ktmp) $(SUBDIRC++FLAGS) ;
585   ktmp = $(C++OPTIM) ;
586   if ! $(ktmp) { ktmp = $(OPTIM) ; }
587   C++OPTIM on $(<) += $(ktmp) ;
589   CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
590   CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
594 # /ObjC object : source ;
596 # Compile the ObjC source file _source_. Similar to @CC, called by @Object
598 # Do not call this rule directly, since _object_ and _source_ may have
599 # have platform-specific file extensions
601 rule ObjC {
602   local ktmp ;
604   Depends $(<) : $(>) ;
606   if $(RELOCATE) { CcMv $(<) : $(>) ; }
608   # Just to clarify here: this sets the per-target CCFLAGS to
609   # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
610   # CCHDRS and CCDEFS must be reformatted each time for some
611   # compiles (VMS, NT) that malign multiple -D or -I flags.
612   ktmp = $(OBJCFLAGS) ;
613   if ! $(ktmp) { ktmp = $(CCFLAGS) ; }
614   OBJCFLAGS on $(<) += $(ktmp) $(SUBDIROBJCFLAGS) ;
616   ktmp = $(OBJCOPTIM) ;
617   if ! $(ktmp) { ktmp = $(OBJCOPTIM) ; }
618   OBJCOPTIM on $(<) += $(ktmp) ;
620   CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
621   CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
625 # /Chmod target ;
627 # (Unix and VMS only). Change file permissions on _target_ to target-specific
628 # $(MODE) value set by @Link, @File, @Install* and @Shell rules
630 rule Chmod {
631   if $(CHMOD) { Chmod1 $(<) ; }
634 # /Clean  clean : targets ;
636 # Removes existing _targets_ when _clean_ is built. clean is not a dependency
637 # of all, and must be built explicitely for targets to be removed
641 # /File target : source ;
643 # Copies _source_ into _target_
645 rule File {
646   Depends files : $(<) ;
647   Depends $(<) : $(>) ;
648   SEARCH on $(>) = $(SEARCH_SOURCE) ;
649   MODE on $(<) = $(FILEMODE) ;
650   Chmod $(<) ;
654 # /GenFile target : image sources ;
656 # Runs the command "_image_ _target_ _sources_" to create _target_ from
657 # _sources_ and _image_ (where _image_ is an executable built by the
658 # @Main rule)
660 rule GenFile {
661   local _t = [ FGristSourceFiles $(<) ] ;
662   local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;
663   Depends $(_t) : $(_s) $(>[2-]) ;
664   GenFile1 $(_t) : $(_s) $(>[2-]) ;
665   Clean clean : $(_t) ;
668 rule GenFile1 {
669   MakeLocate $(<) : $(LOCATE_SOURCE) ;
670   SEARCH on $(>) = $(SEARCH_SOURCE) ;
674 # /HardLink target : source ;
676 # Makes _target_ a hard link to _source_, if it isn't one already
677 # (Unix only)
679 rule HardLink {
680   Depends files : $(<) ;
681   Depends $(<) : $(>) ;
682   SEARCH on $(>) = $(SEARCH_SOURCE) ;
686 # /HdrMacroFile
688 # this rule is specific to FT-Jam. It is used to indicate that a given file
689 # contains definitions for filename macros (e.g. "#define MYFILE_H <myfile>.h")
690 # that can later be used in #include statements in the rest of the source
692 # these files must be parsed before any make is tried.
694 rule HdrMacroFile {
695   HDRMACRO $(<) ;
699 # /HdrRule source : headers ;
701 # Arranges the proper dependencies when the file _source_ includes the files
702 # _headers_ through the #include C preprocessor directive
704 # this rule is not intendend to be called explicitely. It is called
705 # automatically during header scanning on sources handled by the @Object
706 # rule (e.g. sources in @Main or @Library rules)
708 rule HdrRule {
709   # HdrRule source : headers ;
711   # N.B.  This rule is called during binding, potentially after
712   # the fate of many targets has been determined, and must be
713   # used with caution: don't add dependencies to unrelated
714   # targets, and don't set variables on $(<).
716   # Tell Jam that anything depending on $(<) also depends on $(>),
717   # set SEARCH so Jam can find the headers, but then say we don't
718   # care if we can't actually find the headers (they may have been
719   # within ifdefs),
721   local s = $(>:G=$(HDRGRIST:E)) ;
723   Includes $(<) : $(s) ;
724   SEARCH on $(s) = $(HDRSEARCH) ;
725   NoCare $(s) ;
727   # Propagate on $(<) to $(>)
729   HDRSEARCH on $(s) = $(HDRSEARCH) ;
730   HDRSCAN on $(s) = $(HDRSCAN) ;
731   HDRRULE on $(s) = $(HDRRULE) ;
732   HDRGRIST on $(s) = $(HDRGRIST) ;
736 # /Lex source.c : source.l ;
738 # Process the lex source file _source.l_ and rename the lex.yy.c
739 # to _source.c_ . Called by the @Object rule
741 rule Lex {
742   LexMv $(<) : $(>) ;
743   Depends $(<) : $(>) ;
744   MakeLocate $(<) : $(LOCATE_SOURCE) ;
745   Clean clean : $(<) ;
749 # /Library  library : sources ;
751 #  Compiles _sources_ and archives them into _library_. The intermediate
752 #  objects are deleted. Calles @Object and @LibraryFromObjects
754 #  If @Library is invoked with no suffix on _library_, the $(SUFLIB)
755 #  suffix is used
757 rule Library {
758   LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
759   Objects $(>) ;
763 # /SharedLibrary  library : sources : def : import ;
765 # Compiles _sources_ and generates a shared _library_ (i.e. DLL on Windows,
766 # or shared object on Unix). Calls @SharedObjects and @SharedLibraryFromObjects
768 # If @SharedLibrary is invoked with no suffix on _library_, then
769 # $(SUFLIBSHR) suffix is used
771 # _def_ is the name of the corresponding definition file used to generate
772 # the library on Windows and OS/2 (ignored otherwise). If undefined, it
773 # will default to _library_ with the .def suffix
775 # _import_ is the name of the corresponding import library for Windows
776 # and OS/2 platforms (ignored otherwise). If undefined, it will default
777 # to _library_ with the .dll.lib suffix.
779 rule SharedLibrary {
780   #Echo "SharedLibrary: $(<)" ; #dbg
781   #Echo "SharedLibrary: $(>:S=$(SUFOBJSHR))" ; #dbg
782   #Echo "SharedLibrary: $(3)" ; #dbg
783   #Echo "SharedLibrary: $(4)" ; #dbg
784   SharedLibraryFromObjects $(<) : $(>:S=$(SUFOBJSHR)) : $(3) : $(4) ;
785   SharedObjects $(>) ;
788 ######################################################
789 # k8: REWORK!
790 ######################################################
791 #!LIBTOOL!#if $(UNIX) {
792 #!LIBTOOL!#  # this rule is used to find the 'libtool' script in the current
793 #!LIBTOOL!#  # path, this is required when compiling shared objects on Unix
794 #!LIBTOOL!#  rule LibToolFind {
795 #!LIBTOOL!#    if $(LIBTOOL) { return $(LIBTOOL) ; }
796 #!LIBTOOL!#    local matches = [ Glob $(PATH) : libtool ] ;
797 #!LIBTOOL!#    if ! $(matches) { Exit "could not find 'libtool' program in current path. Aborting !" ; }
798 #!LIBTOOL!#    LIBTOOL = $(matches[1]) ;
799 #!LIBTOOL!#    return $(LIBTOOL) ;
800 #!LIBTOOL!#  }
801 #!LIBTOOL!#}
804 # /LibraryFromObjects library : objects ;
806 # Archives _objects_ into _library_. The _objects_ are then deleted
808 # If _library_ has no suffix, the $(SUFLIB) suffix is used
810 # Called by @Library rule. Most people should never call this rule
811 # directly.
813 rule LibraryFromObjects {
814   local _i _l _s ;
816   # Add grist to file names
817   _s = [ FGristFiles $(>) ] ;
818   _l = $(<:S=$(SUFLIB)) ;
820   # library depends on its member objects
821   if $(KEEPOBJS) {
822     Depends obj : $(_s) ;
823   } else {
824     Depends lib : $(_l) ;
825   }
827   # Set LOCATE for the library and its contents.  The bound
828   # value shows up as $(NEEDLIBS) on the Link actions.
829   # For compatibility, we only do this if the library doesn't
830   # already have a path.
831   if ! $(_l:D) {
832     #!!MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;
833     MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_LIB) ;
834   }
836   if $(NOARSCAN) {
837     # If we can't scan the library to timestamp its contents,
838     # we have to just make the library depend directly on the
839     # on-disk object files.
840     Depends $(_l) : $(_s) ;
841   } else {
842     # If we can scan the library, we make the library depend
843     # on its members and each member depend on the on-disk
844     # object file.
845     Depends $(_l) : $(_l)($(_s:BS)) ;
846     for _i in $(_s) {
847       Depends $(_l)($(_i:BS)) : $(_i) ;
848     }
849   }
851   Clean clean : $(_l) ;
853   if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
855   Archive $(_l) : $(_s) ;
857   if $(RANLIB) { Ranlib $(_l) ; }
859   # If we can't scan the library, we have to leave the .o's around.
860   if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; }
864 # /SharedLibraryFromObjects  library : objects : def : import ;
866 # Equivalent of @LibraryFromObjects for shared libraries.
868 # Called by @SharedLibrary. Most people shouldn't call this rule
869 # directly
871 rule SharedLibraryFromObjects {
872   local _i _l _s ;
874   # Add grist to file names
875   _s = [ FGristFiles $(>) ] ;
876   _l = $(<:S=$(SUFLIBSHR)) ;
878   #Echo "Library is $(_l)"    ;
879   # library depends on its member objects
880   if $(KEEPOBJS) {
881     Depends obj : $(_s) ;
882   } else {
883     Depends lib : $(_l) ;
884   }
886   # Set LOCATE for the library and its contents.  The bound
887   # value shows up as $(NEEDLIBS) on the Link actions.
888   # For compatibility, we only do this if the library doesn't
889   # already have a path.
890   if ! $(_l:D) {
891     #!!MakeLocate $(_l) : $(LOCATE_TARGET) ;
892     MakeLocate $(_l) : $(LOCATE_LIBSO) ;
893   }
895   #Echo "SharedLibraryFromObjects: _s = $(_s)" ; #dbg
896   #Echo "SharedLibraryFromObjects: _l = $(_l)" ; #dbg
898   # we never scan shared libraries for member objects
899   Depends $(_l) : $(_s) ;
901   Clean clean : $(_l) ;
903   # I don't know if VMS supports shared libraries, so I prefer
904   # to disable the following right now
905   #
906   #if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
908   # creating the library is so much fun on Unix :-)
909   if $(UNIX) {
910 #!LIBTOOL!#    if $(K8_USE_LIBTOOL) {
911 #!LIBTOOL!#      local libtool = [ LibToolFind ] ;  # find the right libtool
912 #!LIBTOOL!#      AR on $(_l) = "$(libtool) --mode=link $(AR:J= )" ;
913 #!LIBTOOL!#    } else {
914       LINKFLAGS on $(_l) += "-shared" ;
915       C++LINKFLAGS on $(_l) += "-shared" ;
916       LinkUnixLibrary $(_l) : $(_s) ;
917 #!LIBTOOL!#    }
918   } else if $(NT) {
919     local _implib = $(4) ;
920     local _def    = $(3) ;
922     _implib ?= $(_l:S=$(SUFLIBSHR)$(SUFLIB)) ;
923     _def    ?= $(_l:S=.def) ;
925     Clean    clean : $(_implib) ;
926     Depends  lib   : $(_implib) $(_def) ;
928     Depends $(_implib) : $(_def) $(_l) ;
929     Depends $(_l)      : $(_def) ;
931     DEFFILENAME on $(_l) = $(_def) ;
932     IMPLIBNAME  on $(_l) = $(_implib) ;
934     #!!MakeLocate $(_implib)        : $(LOCATE_TARGET) ;
935     #!!MakeLocate $(_implib:S=.exp) : $(LOCATE_TARGET) ;
936     MakeLocate $(_implib)        : $(LOCATE_LIBSO) ;
937     MakeLocate $(_implib:S=.exp) : $(LOCATE_LIBSO) ;
939     if $(JAM_TOOLSET) in VISUALC BORLANDC LCC WATCOM DIGITALMARS {
940       SharedLink-$(JAM_TOOLSET) $(_l) : $(_s) : $(_implib) : $(_def) ;
941     }
942     DllLink $(_l) : $(_s) ;
943   } else {
944     Echo "Sorry, I don't know how to make a shared library on your system" ;
945     Exit "Please *DON'T* contact the K8Jam maintainer for help" ;
946   }
950 # Since building shared libraries is so different depending on the
951 # compiler being used, I've broken this task into compiler-specific
952 # ones
954 rule SharedLink-LCC {
955   Echo "Sorry, but generating DLLs with LCC is not supported. That's" ;
956   Echo "because the 'lcclnk' tool that comes with this compiler is" ;
957   Echo "unreliable and doesn't work as expected." ;
958   Exit ;
960   # the 'lcclnk' tool is absolutely broken:
961   #   - its -o flag doesn't work when there is a LIBRARY statement
962   #     in the .def file.
963   #
964   #   - it uses the LIBRARY name in the .def file to determine
965   #     the name of the dll and its import library, and always
966   #     places them in the current directory !!
967   #
968   #   - if there is no LIBRARY statement, the -o flag is only
969   #     used to determine where the DLL is placed, the import
970   #     library will always be placed in the current directory !!
971   #
973   # clean the .exp file too, don't know how to get rid of it
974   Clean clean : $(4:S=.exp) ;
978 # /Link  image : objects ;
980 # Links _image_ from _objects_ and sets permissions on _image_ to
981 # $(EXEMODE). _image_ must be an actual filename; suffix is not
982 # supplied.
984 # Called by @Main, shouldn't be called by most people
986 rule Link {
987   MODE on $(<) = $(EXEMODE) ;
988   Chmod $(<) ;
992 # /C++Link  image : objects ;
994 # Links _image_ from _objects_ and sets permissions on _image_ to
995 # $(EXEMODE). _image_ must be an actual filename; suffix is not
996 # supplied.
998 # Called by @Main, shouldn't be called by most people
1000 rule C++Link {
1001   MODE on $(<) = $(EXEMODE) ;
1002   Chmod $(<) ;
1005 rule ObjC-Link {
1006   MODE on $(<) = $(EXEMODE) ;
1007   Chmod $(<) ;
1011 # /LinkLibraries image : libraries ;
1013 # Makes _image_ depend on _libraries_ and includes them during linking
1015 # _image_ may be referenced without a suffix in this rule invocation.
1016 # @LinkLibraries supplies the suffix
1018 # You should only use this rule with libraries created through the
1019 # @Library rule. For external libraries, use something else (XXX)
1021 rule LinkLibraries {
1022   # make library dependencies of target
1023   # set NEEDLIBS variable used by 'actions Main'
1024   local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1026   Depends $(_t) : $(>:S=$(SUFLIB)) ;
1027   NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ;
1031 # /LinkSharedLibraries image : libraries :
1033 # Same as @LinkLibraries, but to link _image_ with shared libraries
1034 # generated through the @SharedLibrary rule
1036 rule LinkSharedLibraries {
1037   # make library dependencies of target
1038   # set NEEDLIBS variable used by 'actions Main'
1039   local _t   = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1040   local _ext = $(SUFLIBSHR) ;
1042   if $(NT) {
1043     # on NT, we need to link agains the import library, not the DLL itself !!
1044     _ext = $(SUFLIBSHR)$(SUFLIB) ;
1045   }
1046   Depends $(_t) : $(>:S=$(_ext))  ;
1047   NEEDLIBS on $(_t) += $(>:S=$(_ext)) ;
1051 # /Main image : sources ;
1053 # Compiles _sources_ and links them into _image_. Calls @Objects and
1054 # @MainFromObjects.
1056 # _image_ may be supplied without suffix.
1058 rule Main {
1059   MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
1060   Objects $(>) ;
1064 # /C++Main image : sources ;
1066 # Compiles _sources_ and links them into _image_. Calls @Objects and
1067 # @C++MainFromObjects.
1069 # _image_ may be supplied without suffix.
1071 rule C++Main {
1072   C++MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
1073   Objects $(>) ;
1076 rule ObjC-Main {
1077   ObjC-MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
1078   Objects $(>) ;
1082 # /MainFromObjects image : objects ;
1084 # Links _objects_ into _image_. Dependency of exe.
1085 # @MainFromObjects provides a default suffix for _image_
1087 rule MainFromObjects {
1088   local _s _t ;
1090   # Add grist to file names
1091   # Add suffix to exe
1092   _s = [ FGristFiles $(>) ] ;
1093   _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1094   # so 'jam foo' works when it's really foo.exe
1096   if $(_t) != $(<) {
1097     Depends $(<) : $(_t) ;
1098     NotFile $(<) ;
1099   }
1101   # make compiled sources a dependency of target
1102   Depends exe : $(_t) ;
1103   Depends $(_t) : $(_s) ;
1104   #k8:MakeLocate $(_t) : $(LOCATE_TARGET) ;
1105   MakeLocate $(_t) : $(LOCATE_BIN) ;
1106   Clean clean : $(_t) ;
1108   # special case for stupid Borland C++, which always generates a
1109   # .tds file for executables, even when no debug information is needed
1110   #
1111   #if $(JAM_TOOLSET) = BORLANDC {
1112   #  MakeLocate $(_t:S=.tds) : $(LOCATE_TARGET) ;
1113   #  Clean  clean : $(_t:S=.tds) ;
1114   #}
1116   Link $(_t) : $(_s) ;
1120 # /C++MainFromObjects image : objects ;
1122 # Links _objects_ into _image_. Dependency of exe.
1123 # @MainFromObjects provides a default suffix for _image_
1125 rule C++MainFromObjects {
1126   local _s _t ;
1128   # Add grist to file names
1129   # Add suffix to exe
1130   _s = [ FGristFiles $(>) ] ;
1131   _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1132   # so 'jam foo' works when it's really foo.exe
1134   if $(_t) != $(<) {
1135     Depends $(<) : $(_t) ;
1136     NotFile $(<) ;
1137   }
1139   # make compiled sources a dependency of target
1140   Depends exe : $(_t) ;
1141   Depends $(_t) : $(_s) ;
1142   #k8:MakeLocate $(_t) : $(LOCATE_TARGET) ;
1143   MakeLocate $(_t) : $(LOCATE_BIN) ;
1144   Clean clean : $(_t) ;
1146   # special case for stupid Borland C++, which always generates a
1147   # .tds file for executables, even when no debug information is needed
1148   #
1149   #if $(JAM_TOOLSET) = BORLANDC {
1150   #  MakeLocate $(_t:S=.tds) : $(LOCATE_TARGET) ;
1151   #  Clean  clean : $(_t:S=.tds) ;
1152   #}
1154   C++Link $(_t) : $(_s) ;  ###k8:FIXME
1158 rule ObjC-MainFromObjects {
1159   local _s _t ;
1161   # Add grist to file names
1162   # Add suffix to exe
1163   _s = [ FGristFiles $(>) ] ;
1164   _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1165   # so 'jam foo' works when it's really foo.exe
1167   if $(_t) != $(<) {
1168     Depends $(<) : $(_t) ;
1169     NotFile $(<) ;
1170   }
1172   # make compiled sources a dependency of target
1173   Depends exe : $(_t) ;
1174   Depends $(_t) : $(_s) ;
1175   #k8:MakeLocate $(_t) : $(LOCATE_TARGET) ;
1176   MakeLocate $(_t) : $(LOCATE_BIN) ;
1177   Clean clean : $(_t) ;
1179   ObjC-Link $(_t) : $(_s) ;  ###k8:FIXME
1183 # /MakeLocate  targets : directory
1185 # Creates _dir_ and causes _target_ to be built into _dir_
1187 # This is done by setting the target-specific variable LOCATE
1188 # on _targets_, and arranges with @MkDir to create the target
1189 # directory
1191 rule MakeLocate {
1192   # Note we grist the directory name with 'dir',
1193   # so that directory path components and other
1194   # targets don't conflict.
1195   local srcname = $(<[1]:G=) ;
1196   local srcdir = $(srcname:D) ;
1197   local outdir = $(>[1]:G=dir) ;
1198   local odir ;
1199   if $(srcdir) {
1200     odir = $(outdir)$(PATH_SEPARATOR)$(srcdir) ;
1201   } else {
1202     odir = $(outdir) ;
1203   }
1204   #Echo "MakeLocate:" "$(<)" "|" "$(>)" ;
1205   #Echo "srcname:" "$(srcname)" ;
1206   #Echo "srcdir :" "$(srcdir)" ;
1207   #Echo "outdir :" "$(outdir)" ;
1208   #Echo "odir   :" "$(odir)" ;
1209   if $(>) {
1210     LOCATE on $(<) = $(>) ;
1211     Depends $(<) : $(odir) ;
1212     MkDir $(odir) ;
1213   }
1217 # /MkDir  dir ;
1219 # Creates _dir_ and its parent directories
1221 rule MkDir {
1222   # Ignore timestamps on directories: we only care if they exist.
1223   NoUpdate $(<) ;
1225   # Don't create . or any directory already created.
1226   if $(<:G=) != $(DOT) && ! $($(<)-mkdir) {
1227     # Cheesy gate to prevent multiple invocations on same dir
1228     # Arrange for jam dirs
1229     # MkDir1 has the actions
1230     $(<)-mkdir = true ;
1231     Depends dirs : $(<) ;
1232     MkDir1 $(<) ;
1234     # Recursively make parent directories.
1235     # $(<:P) = $(<)'s parent, & we recurse until root
1236     local s = $(<:P) ;
1238     # Don't try to create A: or A:\ on windows
1239     if $(NT) {
1240       switch $(s) {
1241         case *:   : s = ;
1242         case *:\\ : s = ;
1243       }
1244     }
1245     # handle "C:", "C:/", "/cygdrive" and "/cygdrive/" in Cygwin
1246     if $(UNIX) && $(OS) = CYGWIN {
1247       switch $(s) {
1248         case ?:   : s = ;
1249         case ?:/  : s = ;
1250         case <dir>/cygdrive   : s = ;
1251         case <dir>/cygdrive/  : s = ;
1252       }
1253     }
1255     if $(s) = $(<) {
1256       # The parent is the same as the dir.
1257       # We're at the root, which some OS's can't stat, so we mark
1258       # it as NotFile.
1259       NotFile $(s) ;
1260     } else if $(s:G=) {
1261       # There's a parent; recurse.
1262       Depends $(<) : $(s) ;
1263       MkDir $(s) ;
1264     }
1265   }
1269 # /Object object : source ;
1271 # Compile s a single _source_ file into _object_. The @Main and @Library
1272 # rules use it to compile sources.
1274 # Causes _source_ to be scanned for #include directives and calls @HdrRule
1275 # to make all included files dependencies of _object_.
1277 # Calls one of the following rules depending on the suffix to do the
1278 # actual compilation:
1280 rule Object {
1281   # locate object and search for source, if wanted
1283   Clean clean : $(<) ;
1284   MakeLocate $(<) : $(LOCATE_TARGET) ;
1285   SEARCH on $(>) = $(SEARCH_SOURCE) ;
1287   # Save HDRS for -I$(HDRS) on compile.
1288   # We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers
1289   # in the .c file's directory, but generated .c files (from
1290   # yacc, lex, etc) are located in $(LOCATE_TARGET), possibly
1291   # different from $(SEARCH_SOURCE).
1292   HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;
1294   # handle #includes for source: Jam scans for headers with
1295   # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
1296   # with the scanned file as the target and the found headers
1297   # as the sources.  HDRSEARCH is the value of SEARCH used for
1298   # the found header files.  Finally, if jam must deal with
1299   # header files of the same name in different directories,
1300   # they can be distinguished with HDRGRIST.
1302   # $(SEARCH_SOURCE:E) is where cc first looks for #include
1303   # "foo.h" files.  If the source file is in a distant directory,
1304   # look there.  Else, look in "" (the current directory).
1306   HDRRULE on $(>) = HdrRule ;
1307   HDRSCAN on $(>) = $(HDRPATTERN) ;
1308   HDRSEARCH on $(>) = $(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ;
1309   HDRGRIST on $(>) = $(HDRGRIST) ;
1311   # propagate target specific-defines
1312   DEFINES on $(<) += $(DEFINES) ;
1314   if $(WINDOZE) && $(>:S) = ".rc" {
1315     WindozeResourceCompiler $(<) : $(>) ;
1316   } else if $(WINDOZE) && $(>:S) = ".o" {
1317     # do nothing
1318   } else {
1319     # if source is not .c, generate .c with specific rule
1320     switch $(>:S) {
1321       case .asm : As $(<) : $(>) ;
1322       case .c :   Cc $(<) : $(>) ;
1323       case .C :   C++ $(<) : $(>) ;
1324       case .cc :  C++ $(<) : $(>) ;
1325       case .cpp : C++ $(<) : $(>) ;
1326       case .cxx : C++ $(<) : $(>) ;
1327       case .c++ : C++ $(<) : $(>) ;
1328       case .C++ : C++ $(<) : $(>) ;
1329       case .m :   ObjC $(<) : $(>) ;
1330       case .d :   Dc $(<) : $(>) ;
1331       case .l :   Cc $(<) : $(<:S=.c) ;
1332                   Lex $(<:S=.c) : $(>) ;
1333       case .s :   As $(<) : $(>) ;
1334       case .y :   Cc $(<) : $(<:S=$(YACCGEN)) ;
1335                   Yacc $(<:S=$(YACCGEN)) : $(>) ;
1336       case * :    UserObject $(<) : $(>) ;
1337     }
1338   }
1342 # /ObjectCcFlags  sources : flags ;
1344 # this rule is used to add compiler flags to the compilation of
1345 # specific C sources files.
1347 rule ObjectCcFlags {
1348   CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1352 # /ObjectC++Flags  sources : flags ;
1354 # this rule is used to add compiler flags to the compilation of
1355 # specific C++ source files
1357 rule ObjectC++Flags {
1358   C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1362 rule ObjectObjCFlags {
1363   OBJCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1367 # /LinkFlagsOn  mains : flags ;
1369 # this rule is used to add compiler flags to the compilation of
1370 # specific C sources files.
1372 rule LinkFlagsOn {
1373   LINKFLAGS on [ FGristFiles $(<) ] += $(>) ;
1377 # /C++LinkFlagsOn  mains : flags ;
1379 # this rule is used to add compiler flags to the compilation of
1380 # specific C++ source files
1382 rule C++LinkFlagsOn {
1383   C++LINKFLAGS on [ FGristFiles $(<) ] += $(>) ;
1387 rule ObjCLinkFlagsOn {
1388   OBJCLINKFLAGS on [ FGristFiles $(<) ] += $(>) ;
1392 # /ObjectDefines  objects : macros ;
1394 # this rule is used to add macro defines to the compilation of
1395 # specific C and C++ source files
1397 rule ObjectDefines {
1398   # must reformat CCDEFS according to current defines
1399   local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;
1401   DEFINES on $(s) += $(>) ;
1402   CCDEFS on $(s) = [ on $(s) FDefines $(DEFINES) ] ;
1406 # /ObjectHdrs  sources : paths ;
1408 # this rule is used to add include paths to the compilation of
1409 # specific C and C++ source files
1411 rule ObjectHdrs {
1412   # Add to HDRS for HdrScan's benefit.
1413   # must reformat CCHDRS according to headers
1414   local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;
1416   HDRS on $(s) += $(>) ;
1417   CCHDRS on $(s) = [ on $(s) FIncludes $(HDRS) ] ;
1421 # /Objects sources ;
1423 # this rule is used to compile one or more sources into object files.
1424 # do not call it directly, it is used by the Main and Library rules
1425 # automatically
1427 rule Objects {
1428   local _i ;
1430   for _i in [ FGristFiles $(<) ] {
1431     Object $(_i:S=$(SUFOBJ)) : $(_i) ;
1432     Depends obj : $(_i:S=$(SUFOBJ)) ;
1433   }
1437 # /SharedObjects
1439 # this rule is used to compile one or more sources into 'shared object
1440 # files'. This means object files used to build either DLLs or Unix shared
1441 # libraries.
1443 # do not call this rule directly, it is called by SharedLibrary automatically
1445 rule SharedObjects {
1446   # temporarily override SUFOBJ with $(SUFOBJSHR) to
1447   local SUFOBJ = $(SUFOBJSHR) ;
1449   # call the normal Objects rule
1450   Objects $(<) ;
1452   # add the compiler-specific position-independent-code flag  where needed
1453   ObjectCcFlags $(<) : $(PICFLAGS) ;
1455   # change the compiler invokation for all these objects
1456   # to use Libtool on Unix systems. We explicitely disable the
1457   # generation of static objects here
1458 #!LIBTOOL!#  if $(UNIX) {
1459 #!LIBTOOL!#    #libtool on $(<:S=$(SUFOBJ)) = [ LibToolFind ] ;
1460 #!LIBTOOL!#    if $(K8_USE_LIBTOOL) {
1461 #!LIBTOOL!#      local libtool = [ LibToolFind ] ;
1462 #!LIBTOOL!#      CC on $(<:S=$(SUFOBJ)) = "$(libtool) --mode=compile $(CC:J= ) -dynamic" ;
1463 #!LIBTOOL!#      C++ on $(<:S=$(SUFOBJ)) = "$(libtool) --mode=compile $(C++:J= ) -dynamic" ; #k8:?
1464 #!LIBTOOL!#    }
1465 #!LIBTOOL!#  }
1469 rule RmTemps {
1470   Temporary $(>) ;
1474 rule Setuid {
1475   MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ;
1479 rule Shell {
1480   Depends shell : $(<) ;
1481   Depends $(<) : $(>) ;
1482   SEARCH on $(>) = $(SEARCH_SOURCE) ;
1483   MODE on $(<) = $(SHELLMODE) ;
1484   Clean clean : $(<) ;
1485   Chmod $(<) ;
1489 rule SoftLink {
1490   Depends files : $(<) ;
1491   Depends $(<) : $(>) ;
1492   SEARCH on $(>) = $(SEARCH_SOURCE) ;
1493   Clean clean : $(<) ;
1497 rule SubDir {
1498   #
1499   # SubDir TOP d1 d2 ... ;
1500   #
1501   # Support for a project tree spanning multiple directories.
1502   #
1503   # SubDir declares a Jamfile's location in a project tree, setting
1504   # Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source
1505   # files can be found.
1506   #
1507   # TOP is a user-select variable name for root of the tree, and
1508   # d1 d2 ...  are the directory elements that lead from the root
1509   # of the tree to the directory of the Jamfile.
1510   #
1511   # TOP can be set externally, but normally the first SubDir call
1512   # computes TOP as the path up from the current directory; the
1513   # path contains one ../ for each of d1 d2 ...
1514   #
1515   # SubDir reads once the project-specific rules file Jamrules
1516   # in the TOP directory, if present.  This can be overridden
1517   # with the variable TOPRULES.
1518   #
1519   # SubDir supports multiple, overlaid project trees:  SubDir
1520   # invocations with different TOPs can appear in the same Jamfile.
1521   # The location established by the first SubDir call is used set
1522   # the TOPs for the subsequent SubDir calls.
1523   #
1524   # SubDir's public variables:
1525   #
1526   #   $(TOP) = path from CWD to root.
1527   #   $(SUBDIR) = path from CWD to the directory SubDir names.
1528   #   $(SUBDIR_TOKENS) = path from $(TOP) to $(SUBDIR) as dir names
1529   #   $(SEARCH_SOURCE) = $(SUBDIR)
1530   #   $(LOCATE_SOURCE) = $(ALL_LOCATE_TARGET) $(SUBDIR)
1531   #   $(LOCATE_TARGET) = $(ALL_LOCATE_TARGET) $(SUBDIR)
1532   #   $(LOCATE_BIN) = $(ALL_LOCATE_BIN) $(ALL_LOCATE_TARGET) $(SUBDIR)
1533   #   $(LOCATE_LIB) = $(ALL_LOCATE_LIB) $(ALL_LOCATE_TARGET) $(SUBDIR)
1534   #   $(LOCATE_LIBSO) = $(ALL_LOCATE_LIBSO) $(ALL_LOCATE_LIB) $(ALL_LOCATE_TARGET) $(SUBDIR)
1535   #   $(SOURCE_GRIST) = $(SUBDIR_TOKENS) with !'s
1536   #
1537   local _top = $(<[1]) ;
1538   local _tokens = $(<[2-]) ;
1540   local ktmp ;
1542   # First time through sets up relative root and includes Jamrules.
1543   if ! $(_top) { Exit SubDir syntax error ; }
1545   if ! $($(_top)-SET) {
1546     $(_top)-SET = true ;
1547     # First time we've seen this TOP.
1548     # We'll initialize a number of internal variables:
1549     #
1550     #   $(TOP-UP) = directories from ROOT to a common point
1551     #   $(TOP-DOWN) = directories from common point to TOP
1552     #   $(TOP-ROOT) = root directory for UP/DOWN -- normally CWD
1553     #   $(SUBDIR_UP) = current value of $(TOP-UP)
1554     #   $(SUBDIR_DOWN) = current value of $(TOP-DOWN)
1555     #   $(SUBDIR_ROOT) = current value of $(TOP-ROOT)
1556     #
1557     if $($(_top)) {
1558       # TOP externally set.
1559       # We'll ignore the relative (UP/DOWN) path that
1560       # got us here, and instead remember the hard ROOT.
1561       $(_top)-UP = ;
1562       $(_top)-DOWN = ;
1563       $(_top)-ROOT = $($(_top)) ;
1564     } else {
1565       # TOP not preset.
1567       # Establishing a new TOP.  In the simplest case,
1568       # (SUBDIR_UP/SUBDIR_DOWN/SUBDIR_ROOT unset), it's
1569       # merely a certain number of directories down from
1570       # the current directory, and FSubDirPath will set
1571       # TOP to a path consisting of ../ for each of the
1572       # elements of _tokens, because that represents how
1573       # far below TOP the current directory sits.
1574       #
1575       # In the more complicated case, the starting directory
1576       # isn't the directory of jam's invocation but an
1577       # location established by previous SubDir call.  The
1578       # starting directory is SUBDIR_UP directories up from
1579       # SUBDIR_ROOT, and then SUBDIR_DOWN directories down
1580       # from that.   If SUBDIR_ROOT is not set, that means
1581       # SUBDIR_DOWN and SUBDIR_UP represent the path from
1582       # the directory of jam's invocation.
1583       #
1584       # In the most complicated case, the _tokens also
1585       # represents directories down, because TOP is being
1586       # estalished in a directory other than TOP's root.
1587       # Hopefully, _tokens and SUBDIR_DOWN represent the
1588       # same final directory, relative to the new TOP and
1589       # the previous SubDIr's TOP.  To find the new TOP,
1590       # we have to chop off any common directories from
1591       # then ends of _tokens and SUBDIR_DOWN.  To do so,
1592       # we reverse each of them, call FStripCommon to
1593       # remove the initial common elements, and then
1594       # reverse them again.  After this process, if
1595       # both _tokens and SUBDIR_DOWN have elements, it
1596       # means the directory names estalished by the two
1597       # SubDir calls don't match, and a warning is issued.
1598       # All hell will likely break loose at this point,
1599       # since the whole SubDir scheme relies on the SubDir
1600       # calls accurately naming the current directory.
1602       # Strip common trailing elements of _tokens and SUBDIR_DOWN.
1603       _tokens = [ FReverse $(_tokens) ] ;
1604       SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
1605       FStripCommon _tokens : SUBDIR_DOWN ;
1606       SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
1607       _tokens = [ FReverse $(_tokens) ] ;
1609       if $(SUBDIR_DOWN) && $(_tokens) { Echo Warning: SubDir $(<) misplaced! ; }
1611       # We'll remember the relative (UP/DOWN) path that
1612       # got us here, plus any hard ROOT starting point
1613       # for the UP/DOWN.  If TOP is never set externally,
1614       # ROOT will always be "" (directory of jam's invocation).
1615       $(_top)-UP = $(SUBDIR_UP) $(_tokens) ;
1616       $(_top)-DOWN = $(SUBDIR_DOWN) ;
1617       $(_top)-ROOT = $(SUBDIR_ROOT:E="") ;
1618       $(_top) = [ FSubDirPath $(_top) ] ;
1619     }
1621     # Set subdir vars for the inclusion of the Jamrules,
1622     # just in case they have SubDir rules of their own.
1623     # Note that SUBDIR_DOWN is empty: it's all the way
1624     # up where the Jamrules live.  These gets overrided
1625     # just after the inclusion.
1626     SUBDIR_UP = $($(_top)-UP) ;
1627     SUBDIR_DOWN = ;
1628     SUBDIR_ROOT = $($(_top)-ROOT) ;
1630     # Include $(TOPRULES) or $(TOP)/Jamrules.
1631     # Include $(TOPRULES) if set.
1632     # Otherwise include $(TOP)/Jamrules if present.
1633     if $($(_top)RULES) {
1634       include $($(_top)RULES) ;
1635     } else {
1636       NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ;
1637       include $(JAMRULES:R=$($(_top)):G=$(_top)) ;
1638     }
1639   }
1641   # Get path from $(TOP) to named directory.
1642   # Save dir tokens for other potential uses.
1643   SUBDIR_UP = $($(_top)-UP) ;
1644   SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ;
1645   SUBDIR_ROOT = $($(_top)-ROOT) ;
1646   SUBDIR_TOKENS = $(SUBDIR_DOWN) ;
1648   SUBDIR = [ FSubDirPath $(<) ] ;
1650   # Now set up SEARCH_SOURCE, LOCATE_TARGET, LOCATE_BIN, SOURCE_GRIST
1651   # These can be reset if needed.  For example, if the source
1652   # directory should not hold object files, LOCATE_TARGET can
1653   # subsequently be redefined.
1654   SEARCH_SOURCE = $(SUBDIR) ;
1655   LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
1656   LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
1658   ktmp = $(ALL_LOCATE_BIN) ;
1659   if ! $(ktmp) { ktmp = $(ALL_LOCATE_TARGET) ; }
1660   LOCATE_BIN = $(ktmp) $(SUBDIR) ;
1662   ktmp = $(ALL_LOCATE_LIB) ;
1663   if ! $(ktmp) { ktmp = $(ALL_LOCATE_TARGET) ; }
1664   LOCATE_LIB = $(ktmp) $(SUBDIR) ;
1666   ktmp = $(ALL_LOCATE_LIBSO) ;
1667   if ! $(ktmp) { ktmp = $(ALL_LOCATE_LIB) ; }
1668   if ! $(ktmp) { ktmp = $(ALL_LOCATE_TARGET) ; }
1669   LOCATE_LIBSO = $(ktmp) $(SUBDIR) ;
1671   SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ;
1672   #if ! $(LOCATE_BIN) { LOCATE_BIN = $(LOCATE_TARGET) ; }
1674   # Reset per-directory ccflags, hdrs, etc,
1675   # listed in SUBDIRRESET.
1676   # Note use of variable expanded assignment var
1677   SUBDIR$(SUBDIRRESET) = ;
1679   # Invoke user-specific SubDir extensions,
1680   # rule names listed in SUBDIRRULES.
1681   # Note use of variable expanded rule invocation
1682   $(SUBDIRRULES) $(<) ;
1686 rule FSubDirPath {
1687   # FSubDirPath TOP d1 ... ;
1689   # Returns path to named directory.
1691   # If jam is invoked in a subdirectory of the TOP, then we
1692   # need to prepend a ../ for every level we must climb up
1693   # (TOP-UP), and then append the directory names we must
1694   # climb down (TOP-DOWN), plus the named directories d1 ...
1695   # If TOP was set externally, or computed from another TOP
1696   # that was, we'll have to reroot the whole thing at TOP-ROOT.
1697   local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ;
1699   return $(_r:R=$($(<[1])-ROOT)) ;
1703 rule SubDirDcFlags {
1704   SUBDIRDCFLAGS += $(<) ;
1708 rule SubDirCcFlags {
1709   SUBDIRCCFLAGS += $(<) ;
1713 rule SubDirC++Flags {
1714   SUBDIRC++FLAGS += $(<) ;
1718 rule SubDirObjCFlags {
1719   SUBDIROBJCFLAGS += $(<) ;
1723 rule SubDirHdrs {
1724   SUBDIRHDRS += [ FDirName $(<) ] ;
1728 rule SubIncludeMany {
1729   # SubIncludeMany TOP d1 ... ;
1730   #
1731   # Include a subdirectory's Jamfile.
1733   # We use SubDir to get there, in case the included Jamfile
1734   # either doesn't have its own SubDir (naughty) or is a subtree
1735   # with its own TOP.
1736   #Echo "including " $(<) " : " $(>) ;
1738   if ! $($(<[1])) { Exit SubIncludeMany $(<[1]) without prior SubDir $(<[1]) ; }
1739   SubDir $(<) ;
1740   include $(JAMFILE:D=$(SUBDIR)) ;
1744 rule SubIncludeOnce {
1745   # SubIncludeOnce varname : TOP d1 ... ;
1746   #
1747   # Include a subdirectory's Jamfile.
1749   local _vn = $(<[1]) ;
1750   if ! $($(_vn)) {
1751     #Echo "processing $(_vn)" ;
1752     #Echo "$(>)" ;
1753     $(_vn) = tan ;
1754     SubIncludeMany $(>) ;
1755   #} else {
1756   #  Echo "skiped $(_vn) -- $($(_vn))" ;
1757   #  Echo "$(>)" ;
1758   }
1762 rule SubInclude {
1763   # SubInclude TOP d1 ... ;
1764   #
1765   # Include a subdirectory's Jamfile.
1766   if ! $($(<[1])) { Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ; }
1767   local _sbiguard = _K8JAM_SUB_GUARD_$(<:J=_) ;
1768   SubIncludeOnce $(_sbiguard) : $(<) ;
1772 rule SubRules {
1773   # SubRules TOP d1 ... : Other-TOP ;
1774   #
1775   # Read another tree's Jamrules, by giving it's path according
1776   # to this tree and it's own name.
1777   if ! $($(<[1])) { Exit SubRules $(<[1]) without prior SubDir $(<[1]) ; }
1778   SubDir $(<) ;
1779   SubDir $(>) ;
1783 rule Undefines {
1784   UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ;
1788 rule UserObject {
1789   Exit "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ;
1793 rule Yacc {
1794   local _h ;
1796   _h = $(<:BS=.h) ;
1798   # Some places don't have a yacc.
1799   MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;
1800   #MakeLocate $(>) $(_h) : $(LOCATE_SOURCE) ;
1802   if $(YACC) {
1803     #local tmp ;
1804     #tmp = $(<:G=:D) ;
1805     #if $(tmp) { tmp = $(PATH_SEPARATOR)$(tmp) ; }
1806     #tmp = $(LOCATE_SOURCE[1])$(tmp) ;
1807     #CCFLAGS on $(<:S=$(SUFOBJ)) += -I$(tmp) ;
1808     #C++FLAGS on $(<:S=$(SUFOBJ)) += -I$(tmp) ;
1809     #OBJCFLAGS on $(<:S=$(SUFOBJ)) += -I$(tmp) ;
1810     #Echo "-------------------------" ;
1811     #Echo "LS:" "$(LOCATE_SOURCE)" ;
1812     #Echo "tmp:" "$(tmp)" ;
1813     #Echo "out:" "$(<)" ;
1814     #Echo "in :" "$(>)" ;
1815     #Echo "_h :" "$(_h)" ;
1816     #Echo "=========================" ;
1817     #
1818     Depends $(<) $(_h) : $(>) ;
1819     Yacc1 $(<) : $(>) ;
1820     #Yacc1 $(<) $(_h) : $(>) ;
1821     #YaccMv $(<) $(_h) : $(>) ;
1822     Clean clean : $(<) $(_h) ;
1823   }
1825   # make sure someone includes $(_h) else it will be
1826   # a deadly independent target
1827   Includes $(<) : $(_h) ;
1832 # Utility rules; no side effects on these
1836 # /FGrist path to file ;
1838 # Returns a single string that is used as grist
1840 rule FGrist {
1841   return $(<:J=!) ;
1845 rule FGristFiles {
1846   return $(<:G=$(SOURCE_GRIST:E)) ;
1850 rule FGristSourceFiles {
1851   # Produce source file name name with grist in it,
1852   # if SOURCE_GRIST is set.
1854   # Leave header files alone, because they have a global
1855   # visibility.
1856   if ! $(SOURCE_GRIST) {
1857     return $(<) ;
1858   } else {
1859     local _i _o ;
1861     for _i in $(<) {
1862       switch $(_i) {
1863         case *.h : _o += $(_i) ;
1864         case * :   _o += $(_i:G=$(SOURCE_GRIST)) ;
1865       }
1866     }
1867     return $(_o) ;
1868   }
1872 rule FReverse {
1873   if $(1) { return [ FReverse $(1[2-]) ] $(1[1]) ; }
1877 rule FSubDir {
1878   # If $(>) is the path to the current directory, compute the
1879   # path (using ../../ etc) back to that root directory.
1880   # Sets result in $(<)
1881   if ! $(<[1]) {
1882     return $(DOT) ;
1883   } else {
1884     local _i _d ;
1886     _d = $(DOTDOT) ;
1887     for _i in $(<[2-]) { _d = $(_d:R=$(DOTDOT)) ; }
1888     return $(_d) ;
1889   }
1893 rule FStripCommon {
1894   # FStripCommon v1 : v2 ;
1896   # Strip common initial elements of variables v1 and v2.
1897   # Modifies the variable values themselves.
1898   if $($(<)[1]) && $($(<)[1]) = $($(>)[1]) {
1899     $(<) = $($(<)[2-]) ;
1900     $(>) = $($(>)[2-]) ;
1901     FStripCommon $(<) : $(>) ;
1902   }
1906 rule FRelPath {
1907   local _l _r ;
1909   # first strip off common parts
1910   _l = $(<) ;
1911   _r = $(>) ;
1912   FStripCommon _l : _r ;
1914   # now make path to root and path down
1915   _l = [ FSubDir $(_l) ] ;
1916   _r = [ FDirName $(_r) ] ;
1918   # Concatenate and save
1919   # XXX This should be better
1920   if $(_r) = $(DOT) { return $(_l) ; } else { return $(_r:R=$(_l)) ; }
1924 rule FAppendSuffix {
1925   # E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;"
1926   # returns (yacc,lex,foo.bat) on Unix and
1927   # (yacc.exe,lex.exe,foo.bat) on NT.
1928   if $(>) {
1929     local _i _o ;
1931     for _i in $(<) {
1932       if $(_i:S) { _o += $(_i) ; } else { _o += $(_i:S=$(>)) ; }
1933     }
1934     return $(_o) ;
1935   } else {
1936     return $(<) ;
1937   }
1942 # Operating system specific utility rules
1943 # First, the (generic) UNIX versions
1946 rule FQuote { return "\\\"$(<)\\\"" ; }
1947 rule FDefines { return -D$(<) ; }
1948 rule FIncludes { return -I$(<) ; }
1950 rule FDirName {
1951   # Turn individual elements in $(<) into a usable path.
1952   local _i ;
1953   local _s = $(DOT) ;
1955   for _i in $(<) { _s = $(_i:R=$(_s)) ; }
1956   return $(_s) ;
1960 if $(NT) && $(JAM_TOOLSET) != MINGW && $(JAM_TOOLSET) != LCC {
1961   rule FDefines { return /D$(<) ; }
1962   rule FIncludes { return /I$(<) ; }
1967 # various install rules
1970 rule InstallInto {
1971   # InstallInto dir : sources ;
1973   local i t ;
1975   t = $(>:G=$(INSTALLGRIST)) ;
1977   # Arrange for jam install
1978   # Arrange for jam uninstall
1979   # sources are in SEARCH_SOURCE
1980   # targets are in dir
1982   Depends install : $(t) ;
1983   Clean uninstall : $(t) ;
1984   SEARCH on $(>) = $(SEARCH_SOURCE) ;
1985   MakeLocate $(t) : $(<) ;
1987   # For each source, make gristed target name
1988   # and Install, Chmod, Chown, and Chgrp
1989   for i in $(>) {
1990     local tt = $(i:G=$(INSTALLGRIST)) ;
1992     Depends $(tt) : $(i) ;
1993     Install $(tt) : $(i) ;
1994     Chmod $(tt) ;
1996     if $(OWNER) && $(CHOWN) {
1997       Chown $(tt) ;
1998       OWNER on $(tt) = $(OWNER) ;
1999     }
2000     if $(GROUP) && $(CHGRP) {
2001       Chgrp $(tt) ;
2002       GROUP on $(tt) = $(GROUP) ;
2003     }
2004   }
2008 # /InstallBin dir : sources ;
2010 # Copy _sources_ into _dir_ with mode $(EXEMODE)
2012 rule InstallBin {
2013   local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;
2015   InstallInto $(<) : $(_t) ;
2016   MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ;
2020 # /InstallFile dir : sources ;
2022 # Copy _sources_ into _dir_ with mode $(FILEMODE)
2024 rule InstallFile {
2025   InstallInto $(<) : $(>) ;
2026   MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
2030 # /InstallLib dir : sources ;
2032 # Copy _sources_ into _dir_ with mode $(FILEMODE)
2034 rule InstallLib {
2035   InstallInto $(<) : $(>) ;
2036   MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
2040 # /InstallMan dir : sources ;
2042 #  Copy _sources_ into the appropriate subdirectory of _dir_ with mode
2043 #  $(FILEMODE). The subdirectory is manS, where S is the suffix of each of
2044 #  sources.
2046 rule InstallMan {
2047   # Really this just strips the . from the suffix
2048   local i s d ;
2050   for i in $(>) {
2051     switch $(i:S) {
2052       case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;
2053       case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;
2054       case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;
2055       case .n : s = n ; case .man : s = 1 ;
2056     }
2057     d = man$(s) ;
2058     InstallInto $(d:R=$(<)) : $(i) ;
2059   }
2060   MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
2064 # /InstallShell dir : sources ;
2066 # Copy _sources_ into _dir_ with mode $(SHELLMODE)
2068 rule InstallShell {
2069   InstallInto $(<) : $(>) ;
2070   MODE on $(>:G=$(INSTALLGRIST)) = $(SHELLMODE) ;
2074 rule WindozeResourceCompiler {
2075   DEPENDS $(<) : $(>) ;
2076   Clean clean : $(<) ;
2079 rule windoze-fix {
2080   if $(WINDOZE) {
2081     if $(WINDOZE_THREADS) {
2082       CC += -mthreads ;
2083       CC++ += -mthreads ;
2084     }
2085     local ss = $(WINSUBSYS) ;
2086     if ! $(ss) { ss = "console" ; }
2087     LINK += "-Wl,-subsystem,$(ss)" ;
2088     C++LINK += "-Wl,-subsystem,$(ss)" ;
2089     if $(WINLIBS) { LINKLIBS += $(WINLIBS) ; } else { LINKLIBS += -lkernel32 ; }
2090   }
2095 # Actions
2097 actions WindozeResourceCompiler {
2098   "$(WINE)" $(MGPATH)windres.exe -i $(>) -o $(<)
2102 # First the defaults
2104 actions updated together piecemeal Archive {
2105   $(AR) $(<) $(>)
2109 actions As {
2110   $(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>)
2114 actions C++ {
2115   $(C++) -c -o $(<) $(C++FLAGS) $(C++OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2119 actions Cc {
2120   $(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2124 actions ObjC {
2125   $(OBJCC) -c -o $(<) $(OBJCFLAGS) $(OBJCOPTIM) $(CCDEFS) $(CCHDRS) $(>)
2129 actions Dc {
2130   $(DC) -c -of$(<) $(DCFLAGS) $(DOPTIM) $(>)
2134 actions Chgrp {
2135   $(CHGRP) $(GROUP) $(<)
2139 actions Chmod1 {
2140   $(CHMOD) $(MODE) $(<)
2144 actions Chown {
2145   $(CHOWN) $(OWNER) $(<)
2149 actions piecemeal together existing Clean {
2150   $(RM) $(>)
2154 actions File {
2155   $(CP) $(>) $(<)
2159 actions GenFile1 {
2160   $(>[1]) $(<) $(>[2-])
2164 actions HardLink {
2165   $(RM) $(<) && $(LN) $(>) $(<)
2169 actions Install {
2170   $(CP) $(>) $(<)
2174 actions Lex {
2175   $(LEX) $(>)
2179 actions LexMv {
2180   $(MV) lex.yy.c $(<)
2184 actions Link bind NEEDLIBS {
2185   $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2188 actions C++Link bind NEEDLIBS {
2189   $(C++LINK) $(C++LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(C++LINKLIBS)
2192 actions ObjC-Link bind NEEDLIBS {
2193   $(OBJCLINK) $(OBJCLINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(OBJCLINKLIBS)
2197 actions updated together piecemeal LinkUnixLibrary bind NEEDLIBS {
2198   $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2201 actions updated together piecemeal C++LinkUnixLibrary bind NEEDLIBS {
2202   $(C++LINK) $(C++LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(C++LINKLIBS)
2206 actions MkDir1 {
2207   $(MKDIR) $(<)
2211 actions together Ranlib {
2212   $(RANLIB) $(<)
2216 actions quietly updated piecemeal together RmTemps {
2217   $(RM) $(>)
2221 actions Shell {
2222 #DONT_TOUCH
2223   $(AWK) '
2224     NR == 1 { print "$(SHELLHEADER)" }
2225     NR == 1 && /^[#:]/ { next }
2226     /^##/ { next }
2227     { print }
2228   ' < $(>) > $(<)
2229 #DONT_TOUCH
2233 actions SoftLink {
2234   $(RM) $(<) && $(LN) -s $(>) $(<)
2238 actions Yacc1 {
2239   $(YACC) $(YACCFLAGS) $(>) -o $(<)
2243 actions YaccMv {
2244   #$(MV) $(YACCFILES).c $(<[1])
2245   #$(MV) $(YACCFILES).h $(<[2])
2250 # RELOCATE - for compilers with broken -o flags
2252 if $(RELOCATE) {
2253   actions C++ {
2254     $(C++) -c $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2255   }
2256   actions Cc {
2257     $(CC) -c $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2258   }
2259   actions ignore CcMv {
2260     [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)
2261   }
2266 # NOARUPDATE - can't update an archive
2268 if $(NOARUPDATE) {
2269   actions Archive {
2270     $(AR) $(<) $(>)
2271   }
2276 # UNIX specific actions
2278 if $(UNIX) {
2279   actions GenFile1 {
2280     PATH="$PATH:."
2281     $(>[1]) $(<) $(>[2-])
2282   }
2287 # NT specific actions
2289 if $(NT) {
2290   if $(JAM_TOOLSET) = MINGW {
2291     actions together piecemeal Archive {
2292       $(AR) $(<) $(>:T)
2293     }
2294     actions Cc {
2295       $(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>)
2296     }
2297     actions C++ {
2298       $(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>)
2299     }
2300     actions DllLink bind DEFFILENAME IMPLIBNAME {
2301       $(LINK) $(LINKFLAGS) -shared -o $(<) $(>) $(DEFFILENAME) -Wl,--out-implib,$(IMPLIBNAME)
2302     }
2303   } else if $(JAM_TOOLSET) = LCC {
2304     actions together piecemeal Archive {
2305       $(AR) /out:$(<) $(>)
2306     }
2307     actions Cc {
2308       $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -Fo$(<) -I$(STDHDRS) $(>)
2309     }
2310     actions Link bind NEEDLIBS {
2311       $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2312     }
2313     actions DllLink bind NEEDLIBS DEFFILENAME {
2314       $(LINK) $(LINKFLAGS) -DLL -o $(<) $(UNDEFS) $(>) $(DEFFILENAME) $(NEEDLIBS) $(LINKLIBS)
2315     }
2316     actions ignore DllLinkMv {
2317       $(MV) $(2) $(1)
2318     }
2319     actions Shell {
2320       $(CP) $(>) $(<)
2321     }
2322   } else if $(JAM_TOOLSET) = PELLESC {
2323     actions together piecemeal Archive {
2324       $(AR) /OUT:$(<) $(>)
2325     }
2326     actions Cc {
2327       $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS)   /Fo $(<) -I$(STDHDRS)  $(>)
2328     }
2329     actions Link bind NEEDLIBS {
2330       $(LINK) $(LINKFLAGS) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS)
2331     }
2332     actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME {
2333       $(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS)
2334     }
2335     actions Shell {
2336       $(CP) $(>) $(<)
2337     }
2338   }
2343 # Ketmar's additions
2346 rule CheckGCC42Plus {
2347   local t gccv ;
2349   t = [ Match "(gcc)" : "$(CC)" ] ;
2350   if $(t) != "gcc" { return "ona" ; }
2351   gccv = [ Command "gcc --version | line 1" ] ;
2353   t = [ Match "[\t\r\n ]+([0-9]+\\.)[0-9]+\\." : "$(gccv)" ] ;
2354   if $(t) != "4." { return "ona" ; }
2356   t = [ Match "[\t\r\n ]+[0-9]+\\.([0-9]+\\.)" : "$(gccv)" ] ;
2357   if $(t) = "0." { return "ona" ; }
2358   if $(t) = "1." { return "ona" ; }
2360   return "tan" ;
2364 rule SetCPUFlags {
2365   local t flg f skiping seting ;
2367   if $(OS) != "LINUX" {
2368     DETECTED_CPU = "i486" ;
2369     OPTIM_SPEED = -O3 -march=i486 -mtune=i486 ;
2370     return ;
2371   }
2373   t = [ CheckGCC42Plus ] ;
2374   if $(t) = "tan" {
2375     DETECTED_CPU = native ;
2376     OPTIM_SPEED = -O3 -march=native -mtune=native ;
2377     return ;
2378   }
2380   OPTIM_SPEED = ;
2381   # regexp, flags, empty
2382   flg =
2383     "([Ii]ntel.*[Cc]ore.*[Dd]uo)"
2384     "prescott"
2385     -O3 -march=prescott -mtune=prescott -mfpmath=sse
2386     ""
2387     "([Pp]entium.*III)"
2388     "pentium3"
2389     -O3 -march=pentium3 -mtune=pentium3 -mfpmath=sse
2390     ""
2391     "([Pp]entium.*II)"
2392     "pentium2"
2393     -O3 -march=pentium2 -mtune=pentium2
2394     ""
2395     "([Pp]entium)"
2396     "pentium"
2397     -O3 -march=pentium -mtune=pentium
2398     ""
2399   ;
2400   DETECTED_CPU = [ Command "uname -p" ] ;
2401   for f in $(flg) {
2402     if $(skiping) {
2403       if ! $(f) { skiping = ; }
2404     } else if $(seting) {
2405       if ! $(f) { return ; }
2406       if $(seting) = "first" {
2407         DETECTED_CPU = "$(f)" ;
2408         seting = tan ;
2409       } else {
2410         OPTIM_SPEED += "$(f)" ;
2411       }
2412     } else {
2413       t = [ Match "$(f)" : "$(DETECTED_CPU)" ] ;
2414       if $(t) { seting = first ; } else { skiping = tan ; }
2415     }
2416   }
2420 # VAR = [ RemoveOpt options-to-remove : options-list ] ;
2421 # remove options from list
2422 rule RemoveOpt {
2423   local oname = $(1) ;
2424   local str = $(2) ;
2425   local res = ;
2426   local f ;
2427   local oo ;
2428   #Echo "removing " $(oname) " from " $(str) ;
2429   for f in $(str) {
2430     if ! $(f) in $(oname) {
2431       res += $(f) ;
2432     }
2433   }
2434   return $(res) ;
2438 # VAR = [ RemoveOptWild regexp-options-to-remove : options-list ] ;
2439 # remove options from list with egrep-like regexps
2440 rule RemoveOptWild {
2441   local oname = $(1) ;
2442   local str = $(2) ;
2443   local res = ;
2444   local f ;
2445   local t ;
2446   #Echo "removing " $(oname) " from " $(str) ;
2447   for f in $(str) {
2448     t = [ Match $(oname) : $(f) ] ;
2449     #Echo $(f) ": " $(t) ;
2450     if $(t[1]) = "" {
2451       #Echo "include: " $(f) ;
2452       res += $(f) ;
2453     }
2454   }
2455   return $(res) ;
2459 # profile "name" ;
2460 # set compile flags for profile; works only for gcc/g++
2461 # available profiles:
2462 #  none, default: don't change
2463 #  empty: remove optimisation flags
2464 #  speed: optimise for speed and pIII
2465 #  size: optimise for size
2466 #  debug: don't optimize, add debug info
2467 #  standard: -O2
2468 rule profile {
2469   local orm = "(^\\-march\\=)" "(^\\-mtune\\=)" "(^\\-mfpmath\\=)" "(^\\-O.$)" ;
2470   local ormff = "(^\\-f[^n][^o])" ;
2471   local t ;
2473   local isGCC = "ona" ;
2474   local isG++ = "ona" ;
2475   if ( "gcc" in $(CC) ) || ( $(JAM_TOOLSET) = MINGW ) { isGCC = "tan" ; }
2476   if ( "g++" in $(C++) ) || ( $(JAM_TOOLSET) = MINGW ) { isG++ = "tan" ; }
2477   if $(JAM_FORCE_GCC_OPTIONS) { isGCC = "tan" ; isG++ = "tan" ; }
2479   if $(isGCC) = "tan" { OPTIM = [ RemoveOptWild $(orm) $(ormff) : $(OPTIM) ] ; }
2480   if $(isG++) = "tan" { C++OPTIM = [ RemoveOptWild $(orm) $(ormff) : $(C++OPTIM) ] ; }
2481   OBJCOPTIM = [ RemoveOptWild $(orm) $(ormff) : $(OBJCOPTIM) ] ;
2482   if ( "gcc" in $(LINK) ) || ( $(JAM_FORCE_GCC_OPTIONS) ) { LINKFLAGS -= "-g" "-s" ; }
2483   if $(isG++) = "tan" { C++LINKFLAGS -= "-g" "-s" ; }
2484   OBJCLINKFLAGS -= "-g" "-s" ;
2486   switch $(1) {
2487     case "none" :
2488       Echo "MSG: default profile" ;
2489       OPT_PROFILE = ;
2490     case "default" :
2491       Echo "MSG: default profile" ;
2492       OPT_PROFILE = "default" ;
2493     case "empty" :
2494       Echo "MSG: removing default optimization flags" ;
2495       LINKFLAGS += -s ;
2496       if $(isG++) = "tan" { C++LINKFLAGS += -s ; }
2497       OBJCLINKFLAGS += -s ;
2498       SLACK_PKG_ARCH = "i486" ;
2499       OPT_PROFILE = "empty" ;
2500     case "speed" :
2501       SetCPUFlags ;
2502       Echo "MSG: optimizing for speed; CPU: $(DETECTED_CPU)" ;
2503       if $(isGCC) = "tan" { OPTIM += $(OPTIM_SPEED) ; }
2504       if $(isG++) = "tan" { C++OPTIM += $(OPTIM_SPEED) ; }
2505       OBJCOPTIM += $(OPTIM_SPEED) ;
2506       if $(isGCC) = "tan" { LINKFLAGS += $(LINKFLAGS_SPEED) ; }
2507       if $(isG++) = "tan" { C++LINKFLAGS += $(LINKFLAGS_SPEED) ; }
2508       OBJCLINKFLAGS += $(LINKFLAGS_SPEED) ;
2509       SLACK_PKG_ARCH = "i686" ;
2510       OPT_PROFILE = "speed" ;
2511     case "size" :
2512       Echo "MSG: optimizing for size" ;
2513       if $(isGCC) = "tan" { OPTIM += $(OPTIM_SIZE) ; }
2514       if $(isG++) = "tan" { C++OPTIM += $(OPTIM_SIZE) ; }
2515       OBJCOPTIM += $(OPTIM_SIZE) ;
2516       if $(isGCC) = "tan" { LINKFLAGS += $(LINKFLAGS_SIZE) ; }
2517       if $(isG++) = "tan" { C++LINKFLAGS += $(LINKFLAGS_SIZE) ; }
2518       OBJCLINKFLAGS += $(LINKFLAGS_SIZE) ;
2519       SLACK_PKG_ARCH = "i686" ;
2520       OPT_PROFILE = "size" ;
2521     case "debug" :
2522       Echo "MSG: debug build" ;
2523       if $(isGCC) = "tan" { OPTIM += $(OPTIM_DEBUG) ; }
2524       if $(isG++) = "tan" { C++OPTIM += $(OPTIM_DEBUG) ; }
2525       OBJCOPTIM += $(OPTIM_DEBUG) ;
2526       if $(isGCC) = "tan" { LINKFLAGS += $(LINKFLAGS_DEBUG) ; }
2527       if $(isG++) = "tan" { C++LINKFLAGS += $(LINKFLAGS_DEBUG) ; }
2528       OBJCLINKFLAGS += $(LINKFLAGS_DEBUG) ;
2529       SLACK_PKG_ARCH = "i486" ;
2530       OPT_PROFILE = "debug" ;
2531     case "standard" :
2532       Echo "MSG: standard build" ;
2533       if $(isGCC) = "tan" { OPTIM += -O2 ; }
2534       if $(isG++) = "tan" { C++OPTIM += -O2 ; }
2535       OBJCOPTIM += -O2 ;
2536       if $(isGCC) = "tan" { LINKFLAGS += -s ; }
2537       if $(isG++) = "tan" { C++LINKFLAGS += -s ; }
2538       OBJCLINKFLAGS += -s ;
2539       SLACK_PKG_ARCH = "i486" ;
2540       OPT_PROFILE = "standard" ;
2541     case "*" :
2542       Exit "unknown profile; possible values are: default; empty; speed; size; debug; standard" ;
2543   }
2545 SLACK_PKG_ARCH ?= "i486" ;
2548 # selects 'debug', 'standard', 'speed' or 'size' profile according to vars:
2549 #  DEBUG = 1 : debug
2550 #  OPT_SIZE = 1 : size
2551 #  OPT_SPEED = 1 : speed
2552 #  default: standard
2553 rule set-profile {
2554   if $(DEBUG) {
2555     profile "debug" ;
2556   } else if $(OPT_SIZE) {
2557     profile "size" ;
2558   } else if $(OPT_SPEED) {
2559     profile "speed" ;
2560   } else {
2561     profile "standard" ;
2562   }
2563   if $(VALGRIND) {
2564     LINKFLAGS -= "-g" "-s" ;
2565     C++LINKFLAGS -= "-g" "-s" ;
2566     OPTIM += -g ;
2567     C++OPTIM += -g ;
2568     LINKFLAGS += -g ;
2569     C++LINKFLAGS += -g ;
2570   }
2571   if ! $(NO_WARNINGS) {
2572     OPTIM += -Wall ;
2573     C++OPTIM += -Wall ;
2574   }
2578 # set default 'locate' vars -- _build/, etc
2579 rule set-default-subdir-locates {
2580   ALL_LOCATE_BIN = $(TOP) ;
2581   ALL_LOCATE_LIBSO = $(TOP) ;
2582   if $(WINDOZE) {
2583     ALL_LOCATE_TARGET = $(TOP)$(PATH_SEPARATOR)_wbuild ;
2584     ALL_LOCATE_LIB = $(TOP)$(PATH_SEPARATOR)_wbuild$(PATH_SEPARATOR)lib ;
2585   } else {
2586     ALL_LOCATE_TARGET = $(TOP)$(PATH_SEPARATOR)_build ;
2587     ALL_LOCATE_LIB = $(TOP)$(PATH_SEPARATOR)_build$(PATH_SEPARATOR)lib ;
2588   }
2592 rule set-default-target-locations {
2593   set-default-subdir-locates ;
2596 rule set-default-locations {
2597   set-default-subdir-locates ;
2601 # ObjectNoAliasing filelist ;
2602 # turn off aliasing optimization for specified files
2603 # works only for gcc/g++
2604 rule ObjectNoAliasing {
2605   local isGCC = "ona" ;
2606   local isG++ = "ona" ;
2607   if ( "gcc" in $(CC) ) || ( $(JAM_TOOLSET) = MINGW ) { isGCC = "tan" ; }
2608   if ( "g++" in $(C++) ) || ( $(JAM_TOOLSET) = MINGW ) { isG++ = "tan" ; }
2609   if $(JAM_FORCE_GCC_OPTIONS) { isGCC = "tan" ; isG++ = "tan" ; }
2611   if $(isGCC) = "tan" { CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(OPTIM_NOALIAS) ; }
2612   if $(isG++) = "tan" { C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(OPTIM_NOALIAS) ; }
2613   OBJCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(OPTIM_NOALIAS) ;
2617 # call $(1)
2618 # add output to var $(2)
2619 # return resulting (non-empty) string if library is present
2620 # if $(2) = "" -- don't add flags, just return
2621 # [ lib-config-ex "pkg-config sdl --cflags" : "CFLAGS" ]
2622 rule lib-config-ex {
2623   local cf lf res ;
2624   cf = [ Command "$(1) 2>/dev/null" : parse-output exit-code code-first ] ;
2625   if $(cf[1]) = "0" && $(cf[2]) {
2626     res = $(cf[2-]) ;
2627     if $(2) {
2628       $(2) += $(cf[2-]) ;
2629     }
2630   } else {
2631     res = ;
2632   }
2633   return $(res) ;
2637 # call $(1) --cflags and $(1) --libs (many libs provides such configurators)
2638 # add necessary flags to compiler and linker vars
2639 # return "tan" (non-empty string) if library is present
2640 # if $(2) != "" -- don't add flags, just check
2641 # [ lib-config "pkg-config sdl" ]
2642 rule lib-config {
2643   local cf lf hasit ;
2645   cf = [ Command "$(1) --cflags 2>/dev/null" : parse-output exit-code code-first ] ;
2646   #Echo "cf:" $(cf) ;
2647   if $(cf[1]) = "0" && $(cf[2]) {
2648     hasit = "tan" ;
2649     #Echo "flags:" $(cf[2-]) ;
2650     if ! $(2) {
2651       CCFLAGS += $(cf[2-]) ;
2652       C++FLAGS += $(cf[2-]) ;
2653       OBJCFLAGS += $(cf[2-]) ;
2654     }
2655   }
2657   lf = [ Command "$(1) --libs 2>/dev/null" : parse-output exit-code code-first ] ;
2658   #Echo "lf:" $(lf) ;
2659   if $(lf[1]) = "0" && $(lf[2]) {
2660     hasit = "tan" ;
2661     #Echo "flags:" $(lf[2-]) ;
2662     if ! $(2) {
2663       LINKFLAGS += $(lf[2-]) ;
2664       C++LINKFLAGS += $(lf[2-]) ;
2665       OBJCLINKFLAGS += $(lf[2-]) ;
2666     }
2667   }
2669   return $(hasit) ;
2672 rule pkg-config {
2673   local res ;
2674   res = [ lib-config "pkg-config $(1)" ] ;
2675   return $(res) ;
2679 rule pkg-config-has {
2680   local res ;
2681   res = [ lib-config-ex "pkg-config $(1) --cflags --libs" ] ;
2682   return $(res) ;
2687 # Objective C vars
2690 OBJC_GNUSTEP_BASE_LIB = gnustep-base ;
2691 OBJC_GNUSTEP_GUI_LIB = gnustep-gui ;
2694 # Objective C rules
2696 rule ObjCUseGNUstepBase {
2697   if ! $(K8_INTERNAL_GNUSTEP_BASE) {
2698     #Echo "-l$(OBJC_GNUSTEP_BASE_LIB)" ;
2699     OBJCLINKLIBS += "-l$(OBJC_GNUSTEP_BASE_LIB)" ;
2700     K8_INTERNAL_GNUSTEP_BASE = tan ;
2701   }
2704 rule ObjCUseGNUstepGui {
2705   ObjCUseGNUstepBase ;
2706   if ! $(K8_INTERNAL_GNUSTEP_GUI) {
2707     K8_INTERNAL_GNUSTEP_GUI = tan ;
2708     #Echo "-l$(OBJC_GNUSTEP_GUI_LIB)" ;
2709     OBJCLINKLIBS += "-l$(OBJC_GNUSTEP_GUI_LIB)" ;
2710   }
2713 rule ObjCUseGNUstep {
2714   ObjCUseGNUstepBase ;
2715   ObjCUseGNUstepGui ;
2720 # Now include the user's Jamfile.
2722 include $(JAMFILE) ;