cosmetics in help target
[k8jam.git] / defaults / Jambase
blob1183d755cbca91ad0803b228ec7ce8c39c7293e7
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
60 # [+] added rule: gcc-suggest-attrs
62 # Special targets defined in this file:
64 # all       - parent of first, shell, files, lib, exe
65 # first     - first dependent of 'all', for potential initialization
66 # shell     - parent of all Shell targets
67 # files     - parent of all File targets
68 # lib       - parent of all Library targets
69 # exe       - parent of all Main targets
70 # dirs      - parent of all MkDir targets
71 # clean     - removes all Shell, File, Library, and Main targets
72 # uninstall - removes all Install targets
75 # Rules defined by this file:
77 # as obj.o : source.s ;                  .s -> .o
78 # Bulk dir : files ;                     populate directory with many files
79 # Cc obj.o : source.c ;                  .c -> .o
80 # C++ obj.o : source.cc ;                .cc -> .o
81 # Clean clean : sources ;                remove sources with 'jam clean'
82 # File dest : source ;                   copy file
83 # GenFile source.c : program args ;      make custom file
84 # HardLink target : source ;             make link from source to target
85 # HdrRule source : headers ;             handle #includes
86 # InstallInto dir : sources ;            install any files
87 # InstallBin dir : sources ;             install binaries
88 # InstallLib dir : sources ;             install files
89 # InstallFile dir : sources ;            install files
90 # InstallMan dir : sources ;             install man pages
91 # InstallShell dir : sources ;           install shell scripts
92 # Lex source.c : source.l ;              .l -> .c
93 # Library lib : source ;                 archive library from compiled sources
94 # LibraryFromObjects lib : objects ;     archive library from objects
95 # LinkLibraries images : libraries ;     bag libraries onto Mains
96 # Main image : source ;                  link executable from compiled sources
97 # C++Main image : source ;               link c++ executable from compiled sources
98 # ObjC-Main image : source ;             link obj-c executable from compiled sources
99 # MainFromObjects image : objects ;      link executable from objects
100 # C++MainFromObjects image : objects ;   link c++ executable from objects
101 # ObjC-MainFromObjects image : objects ; link obj-c executable from objects
102 # MkDir dir ;                            make a directory, if not there
103 # Object object : source ;               compile object from source
104 # ObjectCcFlags source : flags ;         add compiler flags for object
105 # ObjectC++Flags source : flags ;        add compiler flags for object
106 # ObjectObjCFlags source : flags ;       add compiler flags for object
107 # ObjectHdrs source : dirs ;             add include directories for object
108 # Objects sources ;                      compile sources
109 # RmTemps target : sources ;             remove temp sources after target made
110 # Setuid images ;                        mark executables Setuid
111 # SoftLink target : source ;             make symlink from source to target
112 # SubDir TOP d1 d2 ... ;                 start a subdirectory Jamfile
113 # SubDirCcFlags flags ;                  add compiler flags until next SubDir
114 # SubDirC++Flags flags ;                 add compiler flags until next SubDir
115 # SubDirHdrs d1 d2 ... ;                 add include dir until next SubDir
116 # SubInclude TOP d1 d2 ... ;             include a subdirectory Jamfile
117 # Shell exe : source ;                   make a shell executable
118 # Undefines images : symbols ;           save undef's for linking
119 # UserObject object : source ;           handle unknown suffixes for Object
120 # Yacc source.c : source.y ;             .y -> .c
122 # Utility rules that have no side effects (not supported):
124 # FAppendSuffix f1 f2 ... : $(SUF) ;     return $(<) with suffixes
125 # FDirName d1 d2 ... ;                   return path from root to dir
126 # FGrist d1 d2 ... ;                     return d1!d2!...
127 # FGristFiles value ;                    return $(value:G=$(SOURCE_GRIST))
128 # FGristSourceFiles value ;              return $(value:G=$(SOURCE_GRIST))
129 # FStripCommon v1 : v2 ;                 strip common initial parts of v1 v2
130 # FReverse a1 a2 ... ;                   return ... a2 a1
131 # FRelPath d1 : d2 ;                     return rel path from d1 to d2
132 # FSubDir d1 d2 ... ;                    return path to root
136 # Brief review of the jam language:
138 # Statements:
139 #   rule RULE - statements to process a rule
140 #   actions RULE - system commands to carry out target update
142 # Modifiers on actions:
143 #   together - multiple instances of same rule on target get executed
144 #          once with their sources ($(>)) concatenated
145 #   updated - refers to updated sources ($(>)) only
146 #   ignore - ignore return status of command
147 #   quietly - don't trace its execution unless verbose
148 #   piecemeal - iterate command each time with a small subset of $(>)
149 #   existing - refers to currently existing sources ($(>)) only
150 #   bind vars - subject to binding before expanding in actions
152 # Special rules:
153 #   Always - always build a target
154 #   Depends - builds the dependency graph
155 #   Echo - blurt out targets on stdout
156 #   Exit - blurt out targets and exit
157 #   Includes - marks sources as headers for target (a codependency)
158 #   NoCare - don't panic if the target can't be built
159 #   NoUpdate - create the target if needed but never update it
160 #   NotFile - ignore the timestamp of the target (it's not a file)
161 #   Temporary - target need not be present if sources haven't changed
163 # Special variables set by jam:
164 #   $(<) - targets of a rule (to the left of the :)
165 #   $(>) - sources of a rule (to the right of the :)
166 #   $(xxx) - true on xxx (UNIX, VMS, NT, OS2, MAC)
167 #   $(OS) - name of OS - varies wildly
168 #   $(JAMVERSION) - version number (2.5)
170 # Special variables used by jam:
171 #   SEARCH - where to find something (used during binding and actions)
172 #   LOCATE - where to plop something not found with SEARCH
173 #   HDRRULE - rule to call to handle include files
174 #   HDRSCAN - egrep regex to extract include files
176 # Special targets:
177 #   all - default if none given on command line
180 # for perforce use -- jambase version
182 #JAMBASEDATE = 2004.10.07 ;
184 #THIS_IS_KJAM = "tan" ; # we are using kjam; removed as obsolete
185 THIS_IS_K8JAM = "tan" ; # we are using k8jam
187 # set to 'tan' for old 'libtool' behavior
188 #!LIBTOOL!#K8_USE_LIBTOOL = ;
191 # Initialize variables
194 ###############################################################################
195 # special values
196 ###############################################################################
198 OPTIM_SPEED = -O3 -march=native -mtune=native -mfpmath=sse ;
199 LINKFLAGS_SPEED = -s ;
201 OPTIM_SIZE = -Os -march=native -mtune=native ;
202 LINKFLAGS_SIZE = -s ;
204 OPTIM_STANDARD = -O2 -march=native -mtune=native ;
205 LINKFLAGS_STANDARD = -s ;
207 OPTIM_DEBUG = -O0 -g ;
208 LINKFLAGS_DEBUG = -g ;
210 OPTIM_NOALIAS = -fno-strict-aliasing ;
214 # OS specific variable settings
217 ###############################################################################
218 # Windoze
219 ###############################################################################
220 if $(NT) {
221   PATH_SEPARATOR = "\\" ;
222   local SUPPORTED_TOOLSETS =
223     MINGW
224     LCC
225     PELLESC
226   ;
228   # if the JAM_TOOLSET environment variable is defined, check that it is
229   # one of our supported values
230   #
231   if $(JAM_TOOLSET) {
232     if ! $(JAM_TOOLSET) in $(SUPPORTED_TOOLSETS) {
233       Echo "The JAM_TOOLSET environment variable is defined but its value" ;
234       Echo "is invalid, please use one of the following:" ;
235       Echo ;
236       for t in $(SUPPORTED_TOOLSETS) { Echo "  " $(t) ; }
237       Exit ;
238     }
239   }
241   if ! $(JAM_TOOLSET) {
242     Echo "The JAM_TOOLSET environment variable is not defined, defaults to MINGW" ;
243     JAM_TOOLSET = MINGW ;
244     MINGW = "c:\\mingw\\" ;
245   }
247   MV        ?= move /y ;
248   CP        ?= copy ;
249   RM        ?= del /f/q ;
250   RMDIR     ?= rmdir /s/q ;
251   SLASH     ?= \\ ;
252   SUFLIB    ?= .lib ;
253   SUFOBJ    ?= .obj ;
254   SUFEXE    ?= .exe ;
255   SUFLIBSHR ?= .dll ;
257   if $(JAM_TOOLSET) = MINGW {
258     Echo "Compiler is GCC with MinGW" ;
259     AR           ?= ar -ru ;
260     RANLIB       ?= ranlib ;
261     CC           ?= mingw-gcc ;
262     CCFLAGS      ?= "" ;
263     C++          ?= mingw-g++ ;
264     C++FLAGS     ?= $(CCFLAGS) ;
265     LINK         ?= $(CC) ;
266     LINKFLAGS    ?= "" ;
267     LINKLIBS     ?= -lkernel32 ;
268     OPTIM        ?= ;
269     SUFOBJ        = .o ;
270     SUFLIB        = .a ;
271     SLASH         = / ;
272     # MinGW-specific thingy
273     MINGW_GUI     = "-Wl,-subsystem,windows" ;
274     MINGW_THREADS = "-mthreads" ;
275     # k8
276     C++OPTIM     ?= $(OPTIM) ;
277     C++LINK      ?= $(C++) ;
278     C++LINKFLAGS ?= $(LINKFLAGS) ;
279     C++LINKLIBS  ?= $(LINKLIBS) ;
280     #NOARSCAN     ?= true ;
281     # set path if any
282     if $(MINGW) {
283       CC = "$(MINGW)$(CC:J= )" ;
284       C++ = "$(MINGW)$(C++:J= )" ;
285       LINK = "$(MINGW)$(LINK:J= )" ;
286       C++LINK = "$(MINGW)$(C++LINK:J= )" ;
287       AR = "$(MINGW)$(AR:J= )" ;
288       RANLIB = "$(MINGW)$(RANLIB:J= )" ;
289     }
290   } else if $(JAM_TOOLSET) = LCC {
291     Echo "Compiler is Win32-LCC" ;
292     AR        ?= lcclib ;
293     CC        ?= lcc ;
294     CCFLAGS   ?= "" ;
295     C++       ?= "error" ;
296     LINK      ?= lcclnk ;
297     LINKFLAGS ?= "" ;
298     LINKLIBS  ?= "" ;
299     OPTIM     ?= ;
300     NOARSCAN   = true ;
301     # k8
302     C++LINK    = "error" ;
303   } else if $(JAM_TOOLSET) = PELLESC {
304     Echo "Compiler is PellesC" ;
305     AR        ?= polib ;
306     CC        ?= pocc ;
307     CCFLAGS   ?= "" ;
308     C++       ?= "error" ;
309     LINK      ?= polink ;
310     LINKFLAGS ?= ;
311     LINKLIBS  ?= ;
312     OPTIM     ?= ;
313     NOARSCAN   = true ;
314     LINKLIBS  ?= crt.lib oldnames.lib Win\\kernel32.lib ;
315     # k8
316     C++LINK    = "error" ;
317   } else {
318     # XXX: We need better comments here !!
319     Exit "On NT, set MINGW to the root of the MinGW dir (but it won't help you anyway)" ;
320   }
321   STDHRS ?= "" ;
322   PICFLAGS = ;
324 ###############################################################################
325 # UNIX
326 ###############################################################################
327 else if $(UNIX) {
328   PATH_SEPARATOR = "/" ;
329   switch $(OS) {
330     case CYGWIN :
331       CC       ?= gcc ;
332       CCFLAGS  += -D__cygwin__ ;
333       LEX      ?= flex ;
334       JAMSHELL ?= sh -c ;
335       RANLIB   ?= "" ;
336       SUFEXE   ?= .exe ;
337       YACC     ?= bison -y ;
338     }
340     # UNIX defaults
341     CC        ?= gcc ;
342     C++       ?= g++ ;
343     OBJCC     ?= gcc ;
344     CCFLAGS   ?= ;
345     OBJCFLAGS ?= $(CCFLAGS) ;
346     C++FLAGS  ?= $(CCFLAGS) ;
347     CHMOD     ?= chmod ;
348     CHGRP     ?= chgrp ;
349     CHOWN     ?= chown ;
350     LEX       ?= flex ;
351     LINKFLAGS ?= $(CCFLAGS) ;
352     LINKLIBS  ?= ;
353     OPTIM     ?= ;
354     RANLIB    ?= ranlib ;
355     YACC      ?= bison ;
356     YACCGEN   ?= .c ;
357     YACCFILES ?= y.tab ;
358     YACCFLAGS ?= -ld ;
359 #!LIBTOOL!#    if $(K8_USE_LIBTOOL) {
360 #!LIBTOOL!#      SUFOBJSHR ?= .lo ;
361 #!LIBTOOL!#      SUFLIBSHR ?= .la ;
362 #!LIBTOOL!#    } else {
363 #!LIBTOOL!#      SUFOBJSHR ?= .o ;
364 #!LIBTOOL!#      SUFLIBSHR ?= .so ;
365 #!LIBTOOL!#    }
366     SUFOBJSHR ?= .o ;
367     SUFLIBSHR ?= .so ;
368 #!LIBTOOL!#
369     PICFLAGS  ?= -fpic ;
370     STDHDRS   ?= /usr/include ;
373 # shared library object file suffix. We assume that it is identical
374 # than the normal one
375 SUFOBJSHR ?= $(SUFOBJ) ;
376 SUFLIBSHR ?= $(SUFLIB) ;
379 # the D compiler
380 DC ?= dmd ;
383 # General defaults; a lot like UNIX
385 PATH_SEPARATOR ?= "/" ;
386 AR          ?= ar ru ;
387 AS          ?= as ;
388 ASFLAGS     ?= ;
389 AWK         ?= awk ;
390 BINDIR      ?= /usr/local/bin ;
391 C++         ?= g++ ;  # k8: was cc
392 C++FLAGS    ?= ;
393 CC          ?= gcc ;  # k8: was cc
394 CCFLAGS     ?= ;
395 CP          ?= cp -f ;
396 CRELIB      ?= ;
397 DOT         ?= . ;
398 DOTDOT      ?= .. ;
399 EXEMODE     ?= 755 ;
400 FILEMODE    ?= 644 ;
401 HDRS        ?= ;
402 INSTALLGRIST    ?= installed ;
403 JAMFILE     ?= Jamfile ;
404 JAMRULES    ?= Jamrules ;
405 LEX         ?= ;
406 LIBDIR      ?= /usr/local/lib ;
407 LINK        ?= $(CC) ;
408 LINKFLAGS   ?= ;
409 LINKLIBS    ?= ;
410 LN          ?= ln ;
411 MANDIR      ?= /usr/local/man ;
412 MKDIR       ?= mkdir ;
413 MV          ?= mv -f ;
414 OPTIM       ?= ;
415 RCP         ?= rcp ;
416 RM          ?= rm -f ;
417 RMDIR       ?= $(RM) ;
418 RSH         ?= rsh ;
419 SED         ?= sed ;
420 SHELLHEADER ?= "#!/bin/sh" ;
421 SHELLMODE   ?= 755 ;
422 SLASH       ?= / ;
423 SUBDIRRULES ?= ;
424 SUBDIRRESET ?= ASFLAGS HDRS C++FLAGS CCFLAGS ;
425 SUFEXE      ?= "" ;
426 SUFLIB      ?= .a ;
427 SUFOBJ      ?= .o ;
428 UNDEFFLAG   ?= "-u _" ;
429 YACC        ?= ;
430 YACCGEN     ?= ;
431 YACCFILES   ?= ;
432 YACCFLAGS   ?= ;
434 HDRPATTERN = "^[[:space:]]*#[[:space:]]*include[[:space:]]*[<\"]([^\">]*)[\">].*$" ;
436 OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;
438 # k8
439 C++OPTIM     ?= $(OPTIM) ;
440 C++LINK      ?= $(C++) ;
441 C++LINKFLAGS ?= $(LINKFLAGS) ;
442 C++LINKLIBS  ?= $(LINKLIBS) ;
444 OBJCOPTIM     ?= $(OPTIM) ;
445 OBJCLINK      ?= $(CC) ;
446 OBJCLINKFLAGS ?= $(LINKFLAGS) ;
447 OBJCLINKLIBS  ?= $(LINKLIBS) ;
448 OBJCLINKLIBS  += -lobjc ;
450 if $(OS) = "LINUX" {
451   if ( "gcc" in $(CC) ) && ! ( "-pipe" in $(CC) ) { CC += -pipe ; }
452   if ( "g++" in $(C++) ) && ! ( "-pipe" in $(C++) ) { C++ += -pipe ; }
455 #Echo "OS:" $(OS) ;
456 #Echo "OSFULL:" $(OSFULL) ;
457 #Echo "UNIX:" $(UNIX) ;
462 # Base dependencies - first for "bootstrap" kinds of rules
464 Depends all : shell files lib exe obj ;
465 Depends all shell files lib exe obj : first ;
466 NotFile all first shell files lib exe obj dirs clean uninstall ;
467 Always  clean uninstall ;
470 # Rules
473 # /As object : source ;
475 # Assemble the file _source_, called by the @Object rule.
477 # Do not call this rule directly, since _object_ and _source_ may have
478 # have platform-specific file extensions
480 rule As {
481   Depends $(<) : $(>) ;
482   ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;
483   ASHDRS on $(<) = [ FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
486 # /Bulk  directory : sources ;
488 # Copies _sources_ into _directory_
490 rule Bulk {
491   local i ;
493   for i in $(>) {
494     File $(i:D=$(<)) : $(i) ;
495   }
499 # /Dc object : source ;
501 # Compile the file source into object, usin the D compiler $(DC), its
502 # flags $(DCFLAGS) and $(DOPTIM)
503 # Called by the @Object rule
505 # Do not call this rule directly, since _object_ and _source_ may have
506 # have platform-specific file extensions
508 rule Dc {
509   Depends $(<) : $(>) ;
510   # Just to clarify here: this sets the per-target DCFLAGS to
511   # be the current value of (global) DCFLAGS and SUBDIRDCFLAGS.
512   DCFLAGS on $(<) += $(DCFLAGS) $(SUBDIRDCFLAGS) ;
516 # /Cc object : source ;
518 # Compile the file source into object, using the C compiler $(CC), its
519 # flags $(CCFLAGS) and $(OPTIM), and the header file directories $(HDRS).
520 # Called by the @Object rule
522 # Do not call this rule directly, since _object_ and _source_ may have
523 # have platform-specific file extensions
525 rule Cc {
526   Depends $(<) : $(>) ;
528   # If the compiler's -o flag doesn't work, relocate the .o
529   if $(RELOCATE) { CcMv $(<) : $(>) ; }
531   # Just to clarify here: this sets the per-target CCFLAGS to
532   # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
533   # CCHDRS and CCDEFS must be reformatted each time for some
534   # compiles (VMS, NT) that malign multiple -D or -I flags.
535   CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ;
536   CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
537   CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
541 rule remove-std99-flags {
542   local orm = "^(\\-std=c99)" "^(\\-std=gnu99)" ;
543   local res = [ RemoveOptWild $(orm) : $(<) ] ;
544   return $(res) ;
548 # /C++ object : source ;
550 # Compile the C++ source file _source_. Similar to @CC, called by @Object
552 # Do not call this rule directly, since _object_ and _source_ may have
553 # have platform-specific file extensions
555 rule C++ {
556   local ktmp ;
558   Depends $(<) : $(>) ;
560   if $(RELOCATE) { CcMv $(<) : $(>) ; }
562   # Just to clarify here: this sets the per-target CCFLAGS to
563   # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
564   # CCHDRS and CCDEFS must be reformatted each time for some
565   # compiles (VMS, NT) that malign multiple -D or -I flags.
566   ktmp = $(C++FLAGS) ;
567   if ! $(ktmp) { ktmp = $(CCFLAGS) ; }
568   C++FLAGS on $(<) += $(ktmp) $(SUBDIRC++FLAGS) ;
570   ktmp = [ remove-std99-flags $(C++OPTIM) ] ;
571   if ! $(ktmp) { ktmp = [ remove-std99-flags $(OPTIM) ] ; }
572   C++OPTIM on $(<) += $(ktmp) ;
574   CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
575   CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
579 # /ObjC object : source ;
581 # Compile the ObjC source file _source_. Similar to @CC, called by @Object
583 # Do not call this rule directly, since _object_ and _source_ may have
584 # have platform-specific file extensions
586 rule ObjC {
587   local ktmp ;
589   Depends $(<) : $(>) ;
591   if $(RELOCATE) { CcMv $(<) : $(>) ; }
593   # Just to clarify here: this sets the per-target CCFLAGS to
594   # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
595   # CCHDRS and CCDEFS must be reformatted each time for some
596   # compiles (VMS, NT) that malign multiple -D or -I flags.
597   ktmp = $(OBJCFLAGS) ;
598   if ! $(ktmp) { ktmp = $(CCFLAGS) ; }
599   OBJCFLAGS on $(<) += $(ktmp) $(SUBDIROBJCFLAGS) ;
601   ktmp = $(OBJCOPTIM) ;
602   if ! $(ktmp) { ktmp = $(OBJCOPTIM) ; }
603   OBJCOPTIM on $(<) += $(ktmp) ;
605   CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
606   CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
610 # /Chmod target ;
612 # (Unix and VMS only). Change file permissions on _target_ to target-specific
613 # $(MODE) value set by @Link, @File, @Install* and @Shell rules
615 rule Chmod {
616   if $(CHMOD) { Chmod1 $(<) ; }
619 # /Clean  clean : targets ;
621 # Removes existing _targets_ when _clean_ is built. clean is not a dependency
622 # of all, and must be built explicitely for targets to be removed
626 # /File target : source ;
628 # Copies _source_ into _target_
630 rule File {
631   Depends files : $(<) ;
632   Depends $(<) : $(>) ;
633   SEARCH on $(>) = $(SEARCH_SOURCE) ;
634   MODE on $(<) = $(FILEMODE) ;
635   Chmod $(<) ;
639 # /GenFile target : image sources ;
641 # Runs the command "_image_ _target_ _sources_" to create _target_ from
642 # _sources_ and _image_ (where _image_ is an executable built by the
643 # @Main rule)
645 rule GenFile {
646   local _t = [ FGristSourceFiles $(<) ] ;
647   local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;
648   Depends $(_t) : $(_s) $(>[2-]) ;
649   GenFile1 $(_t) : $(_s) $(>[2-]) ;
650   Clean clean : $(_t) ;
653 rule GenFile1 {
654   MakeLocate $(<) : $(LOCATE_SOURCE) ;
655   SEARCH on $(>) = $(SEARCH_SOURCE) ;
659 # /HardLink target : source ;
661 # Makes _target_ a hard link to _source_, if it isn't one already
662 # (Unix only)
664 rule HardLink {
665   Depends files : $(<) ;
666   Depends $(<) : $(>) ;
667   SEARCH on $(>) = $(SEARCH_SOURCE) ;
671 # /HdrMacroFile
673 # this rule is specific to FT-Jam. It is used to indicate that a given file
674 # contains definitions for filename macros (e.g. "#define MYFILE_H <myfile>.h")
675 # that can later be used in #include statements in the rest of the source
677 # these files must be parsed before any make is tried.
679 rule HdrMacroFile {
680   HDRMACRO $(<) ;
684 # /HdrRule source : headers ;
686 # Arranges the proper dependencies when the file _source_ includes the files
687 # _headers_ through the #include C preprocessor directive
689 # this rule is not intendend to be called explicitely. It is called
690 # automatically during header scanning on sources handled by the @Object
691 # rule (e.g. sources in @Main or @Library rules)
693 rule HdrRule {
694   # HdrRule source : headers ;
696   # N.B.  This rule is called during binding, potentially after
697   # the fate of many targets has been determined, and must be
698   # used with caution: don't add dependencies to unrelated
699   # targets, and don't set variables on $(<).
701   # Tell Jam that anything depending on $(<) also depends on $(>),
702   # set SEARCH so Jam can find the headers, but then say we don't
703   # care if we can't actually find the headers (they may have been
704   # within ifdefs),
706   local s = $(>:G=$(HDRGRIST:E)) ;
708   Includes $(<) : $(s) ;
709   SEARCH on $(s) = $(HDRSEARCH) ;
710   NoCare $(s) ;
712   # Propagate on $(<) to $(>)
714   HDRSEARCH on $(s) = $(HDRSEARCH) ;
715   HDRSCAN on $(s) = $(HDRSCAN) ;
716   HDRRULE on $(s) = $(HDRRULE) ;
717   HDRGRIST on $(s) = $(HDRGRIST) ;
721 # /Lex source.c : source.l ;
723 # Process the lex source file _source.l_ and rename the lex.yy.c
724 # to _source.c_ . Called by the @Object rule
726 rule Lex {
727   ##LexMv $(<) : $(>) ;
728   Depends $(<) : $(>) ;
729   MakeLocate $(<) : $(LOCATE_SOURCE) ;
730   Clean clean : $(<) ;
734 # /Library  library : sources ;
736 #  Compiles _sources_ and archives them into _library_. The intermediate
737 #  objects are deleted. Calles @Object and @LibraryFromObjects
739 #  If @Library is invoked with no suffix on _library_, the $(SUFLIB)
740 #  suffix is used
742 rule Library {
743   LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
744   Objects $(>) ;
748 # /SharedLibrary  library : sources : def : import ;
750 # Compiles _sources_ and generates a shared _library_ (i.e. DLL on Windows,
751 # or shared object on Unix). Calls @SharedObjects and @SharedLibraryFromObjects
753 # If @SharedLibrary is invoked with no suffix on _library_, then
754 # $(SUFLIBSHR) suffix is used
756 # _def_ is the name of the corresponding definition file used to generate
757 # the library on Windows and OS/2 (ignored otherwise). If undefined, it
758 # will default to _library_ with the .def suffix
760 # _import_ is the name of the corresponding import library for Windows
761 # and OS/2 platforms (ignored otherwise). If undefined, it will default
762 # to _library_ with the .dll.lib suffix.
764 rule SharedLibrary {
765   #Echo "SharedLibrary: $(<)" ; #dbg
766   #Echo "SharedLibrary: $(>:S=$(SUFOBJSHR))" ; #dbg
767   #Echo "SharedLibrary: $(3)" ; #dbg
768   #Echo "SharedLibrary: $(4)" ; #dbg
769   SharedLibraryFromObjects $(<) : $(>:S=$(SUFOBJSHR)) : $(3) : $(4) ;
770   SharedObjects $(>) ;
773 ######################################################
774 # k8: REWORK!
775 ######################################################
776 #!LIBTOOL!#if $(UNIX) {
777 #!LIBTOOL!#  # this rule is used to find the 'libtool' script in the current
778 #!LIBTOOL!#  # path, this is required when compiling shared objects on Unix
779 #!LIBTOOL!#  rule LibToolFind {
780 #!LIBTOOL!#    if $(LIBTOOL) { return $(LIBTOOL) ; }
781 #!LIBTOOL!#    local matches = [ Glob $(PATH) : libtool ] ;
782 #!LIBTOOL!#    if ! $(matches) { Exit "could not find 'libtool' program in current path. Aborting !" ; }
783 #!LIBTOOL!#    LIBTOOL = $(matches[1]) ;
784 #!LIBTOOL!#    return $(LIBTOOL) ;
785 #!LIBTOOL!#  }
786 #!LIBTOOL!#}
789 # /LibraryFromObjects library : objects ;
791 # Archives _objects_ into _library_. The _objects_ are then deleted
793 # If _library_ has no suffix, the $(SUFLIB) suffix is used
795 # Called by @Library rule. Most people should never call this rule
796 # directly.
798 rule LibraryFromObjects {
799   local _i _l _s ;
801   # Add grist to file names
802   _s = [ FGristFiles $(>) ] ;
803   _l = $(<:S=$(SUFLIB)) ;
805   # library depends on its member objects
806   if $(KEEPOBJS) {
807     Depends obj : $(_s) ;
808   } else {
809     Depends lib : $(_l) ;
810   }
812   # Set LOCATE for the library and its contents.  The bound
813   # value shows up as $(NEEDLIBS) on the Link actions.
814   # For compatibility, we only do this if the library doesn't
815   # already have a path.
816   if ! $(_l:D) {
817     #!!MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;
818     MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_LIB) ;
819   }
821   if $(NOARSCAN) {
822     # If we can't scan the library to timestamp its contents,
823     # we have to just make the library depend directly on the
824     # on-disk object files.
825     Depends $(_l) : $(_s) ;
826   } else {
827     # If we can scan the library, we make the library depend
828     # on its members and each member depend on the on-disk
829     # object file.
830     Depends $(_l) : $(_l)($(_s:BS)) ;
831     for _i in $(_s) {
832       Depends $(_l)($(_i:BS)) : $(_i) ;
833     }
834   }
836   Clean clean : $(_l) ;
838   if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
840   Archive $(_l) : $(_s) ;
842   if $(RANLIB) { Ranlib $(_l) ; }
844   # If we can't scan the library, we have to leave the .o's around.
845   if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; }
849 # /SharedLibraryFromObjects  library : objects : def : import ;
851 # Equivalent of @LibraryFromObjects for shared libraries.
853 # Called by @SharedLibrary. Most people shouldn't call this rule
854 # directly
856 rule SharedLibraryFromObjects {
857   local _i _l _s ;
859   # Add grist to file names
860   _s = [ FGristFiles $(>) ] ;
861   _l = $(<:S=$(SUFLIBSHR)) ;
863   #Echo "Library is $(_l)"    ;
864   # library depends on its member objects
865   if $(KEEPOBJS) {
866     Depends obj : $(_s) ;
867   } else {
868     Depends lib : $(_l) ;
869   }
871   # Set LOCATE for the library and its contents.  The bound
872   # value shows up as $(NEEDLIBS) on the Link actions.
873   # For compatibility, we only do this if the library doesn't
874   # already have a path.
875   if ! $(_l:D) {
876     #!!MakeLocate $(_l) : $(LOCATE_TARGET) ;
877     MakeLocate $(_l) : $(LOCATE_LIBSO) ;
878   }
880   #Echo "SharedLibraryFromObjects: _s = $(_s)" ; #dbg
881   #Echo "SharedLibraryFromObjects: _l = $(_l)" ; #dbg
883   # we never scan shared libraries for member objects
884   Depends $(_l) : $(_s) ;
886   Clean clean : $(_l) ;
888   # I don't know if VMS supports shared libraries, so I prefer
889   # to disable the following right now
890   #
891   #if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
893   # creating the library is so much fun on Unix :-)
894   if $(UNIX) {
895 #!LIBTOOL!#    if $(K8_USE_LIBTOOL) {
896 #!LIBTOOL!#      local libtool = [ LibToolFind ] ;  # find the right libtool
897 #!LIBTOOL!#      AR on $(_l) = "$(libtool) --mode=link $(AR:J= )" ;
898 #!LIBTOOL!#    } else {
899       LINKFLAGS on $(_l) += "-shared" ;
900       C++LINKFLAGS on $(_l) += "-shared" ;
901       LinkUnixLibrary $(_l) : $(_s) ;
902 #!LIBTOOL!#    }
903   } else if $(NT) {
904     local _implib = $(4) ;
905     local _def    = $(3) ;
907     _implib ?= $(_l:S=$(SUFLIBSHR)$(SUFLIB)) ;
908     _def    ?= $(_l:S=.def) ;
910     Clean    clean : $(_implib) ;
911     Depends  lib   : $(_implib) $(_def) ;
913     Depends $(_implib) : $(_def) $(_l) ;
914     Depends $(_l)      : $(_def) ;
916     DEFFILENAME on $(_l) = $(_def) ;
917     IMPLIBNAME  on $(_l) = $(_implib) ;
919     #!!MakeLocate $(_implib)        : $(LOCATE_TARGET) ;
920     #!!MakeLocate $(_implib:S=.exp) : $(LOCATE_TARGET) ;
921     MakeLocate $(_implib)        : $(LOCATE_LIBSO) ;
922     MakeLocate $(_implib:S=.exp) : $(LOCATE_LIBSO) ;
924     if $(JAM_TOOLSET) in VISUALC BORLANDC LCC WATCOM DIGITALMARS {
925       SharedLink-$(JAM_TOOLSET) $(_l) : $(_s) : $(_implib) : $(_def) ;
926     }
927     DllLink $(_l) : $(_s) ;
928   } else {
929     Echo "Sorry, I don't know how to make a shared library on your system" ;
930     Exit "Please *DON'T* contact the K8Jam maintainer for help" ;
931   }
935 # Since building shared libraries is so different depending on the
936 # compiler being used, I've broken this task into compiler-specific
937 # ones
939 rule SharedLink-LCC {
940   Echo "Sorry, but generating DLLs with LCC is not supported. That's" ;
941   Echo "because the 'lcclnk' tool that comes with this compiler is" ;
942   Echo "unreliable and doesn't work as expected." ;
943   Exit ;
945   # the 'lcclnk' tool is absolutely broken:
946   #   - its -o flag doesn't work when there is a LIBRARY statement
947   #     in the .def file.
948   #
949   #   - it uses the LIBRARY name in the .def file to determine
950   #     the name of the dll and its import library, and always
951   #     places them in the current directory !!
952   #
953   #   - if there is no LIBRARY statement, the -o flag is only
954   #     used to determine where the DLL is placed, the import
955   #     library will always be placed in the current directory !!
956   #
958   # clean the .exp file too, don't know how to get rid of it
959   Clean clean : $(4:S=.exp) ;
963 # /Link  image : objects ;
965 # Links _image_ from _objects_ and sets permissions on _image_ to
966 # $(EXEMODE). _image_ must be an actual filename; suffix is not
967 # supplied.
969 # Called by @Main, shouldn't be called by most people
971 rule Link {
972   MODE on $(<) = $(EXEMODE) ;
973   Chmod $(<) ;
977 # /C++Link  image : objects ;
979 # Links _image_ from _objects_ and sets permissions on _image_ to
980 # $(EXEMODE). _image_ must be an actual filename; suffix is not
981 # supplied.
983 # Called by @Main, shouldn't be called by most people
985 rule C++Link {
986   MODE on $(<) = $(EXEMODE) ;
987   Chmod $(<) ;
990 rule ObjC-Link {
991   MODE on $(<) = $(EXEMODE) ;
992   Chmod $(<) ;
996 # /LinkLibraries image : libraries ;
998 # Makes _image_ depend on _libraries_ and includes them during linking
1000 # _image_ may be referenced without a suffix in this rule invocation.
1001 # @LinkLibraries supplies the suffix
1003 # You should only use this rule with libraries created through the
1004 # @Library rule. For external libraries, use something else (XXX)
1006 rule LinkLibraries {
1007   # make library dependencies of target
1008   # set NEEDLIBS variable used by 'actions Main'
1009   local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1011   Depends $(_t) : $(>:S=$(SUFLIB)) ;
1012   NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ;
1016 # /LinkSharedLibraries image : libraries :
1018 # Same as @LinkLibraries, but to link _image_ with shared libraries
1019 # generated through the @SharedLibrary rule
1021 rule LinkSharedLibraries {
1022   # make library dependencies of target
1023   # set NEEDLIBS variable used by 'actions Main'
1024   local _t   = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1025   local _ext = $(SUFLIBSHR) ;
1027   if $(NT) {
1028     # on NT, we need to link agains the import library, not the DLL itself !!
1029     _ext = $(SUFLIBSHR)$(SUFLIB) ;
1030   }
1031   Depends $(_t) : $(>:S=$(_ext))  ;
1032   NEEDLIBS on $(_t) += $(>:S=$(_ext)) ;
1036 # /Main image : sources ;
1038 # Compiles _sources_ and links them into _image_. Calls @Objects and
1039 # @MainFromObjects.
1041 # _image_ may be supplied without suffix.
1043 rule Main {
1044   MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
1045   Objects $(>) ;
1049 # /C++Main image : sources ;
1051 # Compiles _sources_ and links them into _image_. Calls @Objects and
1052 # @C++MainFromObjects.
1054 # _image_ may be supplied without suffix.
1056 rule C++Main {
1057   C++MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
1058   Objects $(>) ;
1061 rule ObjC-Main {
1062   ObjC-MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
1063   Objects $(>) ;
1067 # /MainFromObjects image : objects ;
1069 # Links _objects_ into _image_. Dependency of exe.
1070 # @MainFromObjects provides a default suffix for _image_
1072 rule MainFromObjects {
1073   local _s _t ;
1075   # Add grist to file names
1076   # Add suffix to exe
1077   _s = [ FGristFiles $(>) ] ;
1078   _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1079   # so 'jam foo' works when it's really foo.exe
1081   if $(_t) != $(<) {
1082     Depends $(<) : $(_t) ;
1083     NotFile $(<) ;
1084   }
1086   # make compiled sources a dependency of target
1087   Depends exe : $(_t) ;
1088   Depends $(_t) : $(_s) ;
1089   #k8:MakeLocate $(_t) : $(LOCATE_TARGET) ;
1090   MakeLocate $(_t) : $(LOCATE_BIN) ;
1091   Clean clean : $(_t) ;
1093   # special case for stupid Borland C++, which always generates a
1094   # .tds file for executables, even when no debug information is needed
1095   #
1096   #if $(JAM_TOOLSET) = BORLANDC {
1097   #  MakeLocate $(_t:S=.tds) : $(LOCATE_TARGET) ;
1098   #  Clean  clean : $(_t:S=.tds) ;
1099   #}
1101   Link $(_t) : $(_s) ;
1105 # /C++MainFromObjects image : objects ;
1107 # Links _objects_ into _image_. Dependency of exe.
1108 # @MainFromObjects provides a default suffix for _image_
1110 rule C++MainFromObjects {
1111   local _s _t ;
1113   # Add grist to file names
1114   # Add suffix to exe
1115   _s = [ FGristFiles $(>) ] ;
1116   _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1117   # so 'jam foo' works when it's really foo.exe
1119   if $(_t) != $(<) {
1120     Depends $(<) : $(_t) ;
1121     NotFile $(<) ;
1122   }
1124   # make compiled sources a dependency of target
1125   Depends exe : $(_t) ;
1126   Depends $(_t) : $(_s) ;
1127   #k8:MakeLocate $(_t) : $(LOCATE_TARGET) ;
1128   MakeLocate $(_t) : $(LOCATE_BIN) ;
1129   Clean clean : $(_t) ;
1131   # special case for stupid Borland C++, which always generates a
1132   # .tds file for executables, even when no debug information is needed
1133   #
1134   #if $(JAM_TOOLSET) = BORLANDC {
1135   #  MakeLocate $(_t:S=.tds) : $(LOCATE_TARGET) ;
1136   #  Clean  clean : $(_t:S=.tds) ;
1137   #}
1139   C++Link $(_t) : $(_s) ;  ###k8:FIXME
1143 rule ObjC-MainFromObjects {
1144   local _s _t ;
1146   # Add grist to file names
1147   # Add suffix to exe
1148   _s = [ FGristFiles $(>) ] ;
1149   _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1150   # so 'jam foo' works when it's really foo.exe
1152   if $(_t) != $(<) {
1153     Depends $(<) : $(_t) ;
1154     NotFile $(<) ;
1155   }
1157   # make compiled sources a dependency of target
1158   Depends exe : $(_t) ;
1159   Depends $(_t) : $(_s) ;
1160   #k8:MakeLocate $(_t) : $(LOCATE_TARGET) ;
1161   MakeLocate $(_t) : $(LOCATE_BIN) ;
1162   Clean clean : $(_t) ;
1164   ObjC-Link $(_t) : $(_s) ;  ###k8:FIXME
1168 # /MakeLocate  targets : directory
1170 # Creates _dir_ and causes _target_ to be built into _dir_
1172 # This is done by setting the target-specific variable LOCATE
1173 # on _targets_, and arranges with @MkDir to create the target
1174 # directory
1176 rule MakeLocate {
1177   # Note we grist the directory name with 'dir',
1178   # so that directory path components and other
1179   # targets don't conflict.
1180   local srcname = $(<[1]:G=) ;
1181   local srcdir = $(srcname:D) ;
1182   local outdir = $(>[1]:G=dir) ;
1183   local odir ;
1184   if $(srcdir) {
1185     odir = $(outdir)$(PATH_SEPARATOR)$(srcdir) ;
1186   } else {
1187     odir = $(outdir) ;
1188   }
1189   #Echo "MakeLocate:" "$(<)" "|" "$(>)" ;
1190   #Echo "srcname:" "$(srcname)" ;
1191   #Echo "srcdir :" "$(srcdir)" ;
1192   #Echo "outdir :" "$(outdir)" ;
1193   #Echo "odir   :" "$(odir)" ;
1194   if $(>) {
1195     LOCATE on $(<) = $(>) ;
1196     Depends $(<) : $(odir) ;
1197     MkDir $(odir) ;
1198   }
1202 # /MkDir  dir ;
1204 # Creates _dir_ and its parent directories
1206 rule MkDir {
1207   # Ignore timestamps on directories: we only care if they exist.
1208   NoUpdate $(<) ;
1210   # Don't create . or any directory already created.
1211   if $(<:G=) != $(DOT) && ! $($(<)-mkdir) {
1212     # Cheesy gate to prevent multiple invocations on same dir
1213     # Arrange for jam dirs
1214     # MkDir1 has the actions
1215     $(<)-mkdir = true ;
1216     Depends dirs : $(<) ;
1217     MkDir1 $(<) ;
1219     # Recursively make parent directories.
1220     # $(<:P) = $(<)'s parent, & we recurse until root
1221     local s = $(<:P) ;
1223     # Don't try to create A: or A:\ on windows
1224     if $(NT) {
1225       switch $(s) {
1226         case "*:"   : s = ;
1227         case "*:\\" : s = ;
1228       }
1229     }
1230     # handle "C:", "C:/", "/cygdrive" and "/cygdrive/" in Cygwin
1231     if $(UNIX) && $(OS) = CYGWIN {
1232       switch $(s) {
1233         case "?:"   : s = ;
1234         case "?:/"  : s = ;
1235         case "<dir>/cygdrive"   : s = ;
1236         case "<dir>/cygdrive/"  : s = ;
1237       }
1238     }
1240     if $(s) = $(<) {
1241       # The parent is the same as the dir.
1242       # We're at the root, which some OS's can't stat, so we mark
1243       # it as NotFile.
1244       NotFile $(s) ;
1245     } else if $(s:G=) {
1246       # There's a parent; recurse.
1247       Depends $(<) : $(s) ;
1248       MkDir $(s) ;
1249     }
1250   }
1254 # /Object object : source ;
1256 # Compile s a single _source_ file into _object_. The @Main and @Library
1257 # rules use it to compile sources.
1259 # Causes _source_ to be scanned for #include directives and calls @HdrRule
1260 # to make all included files dependencies of _object_.
1262 # Calls one of the following rules depending on the suffix to do the
1263 # actual compilation:
1265 rule Object {
1266   # locate object and search for source, if wanted
1268   Clean clean : $(<) ;
1269   MakeLocate $(<) : $(LOCATE_TARGET) ;
1270   SEARCH on $(>) = $(SEARCH_SOURCE) ;
1272   # Save HDRS for -I$(HDRS) on compile.
1273   # We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers
1274   # in the .c file's directory, but generated .c files (from
1275   # yacc, lex, etc) are located in $(LOCATE_TARGET), possibly
1276   # different from $(SEARCH_SOURCE).
1277   HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;
1279   # handle #includes for source: Jam scans for headers with
1280   # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
1281   # with the scanned file as the target and the found headers
1282   # as the sources.  HDRSEARCH is the value of SEARCH used for
1283   # the found header files.  Finally, if jam must deal with
1284   # header files of the same name in different directories,
1285   # they can be distinguished with HDRGRIST.
1287   # $(SEARCH_SOURCE:E) is where cc first looks for #include
1288   # "foo.h" files.  If the source file is in a distant directory,
1289   # look there.  Else, look in "" (the current directory).
1291   HDRRULE on $(>) = HdrRule ;
1292   HDRSCAN on $(>) = $(HDRPATTERN) ;
1293   HDRSEARCH on $(>) = $(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ;
1294   HDRGRIST on $(>) = $(HDRGRIST) ;
1296   # propagate target specific-defines
1297   DEFINES on $(<) += $(DEFINES) ;
1299   if $(WINDOZE) && $(>:S) = ".rc" {
1300     WindozeResourceCompiler $(<) : $(>) ;
1301   } else if $(WINDOZE) && $(>:S) = ".o" {
1302     # do nothing
1303   } else {
1304     # if source is not .c, generate .c with specific rule
1305     switch $(>:S) {
1306       case .asm : As $(<) : $(>) ;
1307       case .c   : Cc $(<) : $(>) ;
1308       case .C   : C++ $(<) : $(>) ;
1309       case .cc  : C++ $(<) : $(>) ;
1310       case .cpp : C++ $(<) : $(>) ;
1311       case .cxx : C++ $(<) : $(>) ;
1312       case .c++ : C++ $(<) : $(>) ;
1313       case .C++ : C++ $(<) : $(>) ;
1314       case .m   : ObjC $(<) : $(>) ;
1315       case .d   : Dc $(<) : $(>) ;
1316       case .l   : Cc $(<) : $(<:S=.c) ;
1317                   Lex $(<:S=.c) : $(>) ;
1318       case .s   : As $(<) : $(>) ;
1319       case .y   : Cc $(<) : $(<:S=$(YACCGEN)) ;
1320                   Yacc $(<:S=$(YACCGEN)) : $(>) ;
1321       case *    : UserObject $(<) : $(>) ;
1322     }
1323   }
1327 # /ObjectCcFlags  sources : flags ;
1329 # this rule is used to add compiler flags to the compilation of
1330 # specific C sources files.
1332 rule ObjectCcFlags {
1333   CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1337 # /ObjectC++Flags  sources : flags ;
1339 # this rule is used to add compiler flags to the compilation of
1340 # specific C++ source files
1342 rule ObjectC++Flags {
1343   C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1347 rule ObjectObjCFlags {
1348   OBJCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1352 # /LinkFlagsOn  mains : flags ;
1354 # this rule is used to add compiler flags to the compilation of
1355 # specific C sources files.
1357 rule LinkFlagsOn {
1358   LINKFLAGS on [ FGristFiles $(<) ] += $(>) ;
1362 # /C++LinkFlagsOn  mains : flags ;
1364 # this rule is used to add compiler flags to the compilation of
1365 # specific C++ source files
1367 rule C++LinkFlagsOn {
1368   C++LINKFLAGS on [ FGristFiles $(<) ] += $(>) ;
1372 rule ObjCLinkFlagsOn {
1373   OBJCLINKFLAGS on [ FGristFiles $(<) ] += $(>) ;
1377 # /ObjectDefines  objects : macros ;
1379 # this rule is used to add macro defines to the compilation of
1380 # specific C and C++ source files
1382 rule ObjectDefines {
1383   # must reformat CCDEFS according to current defines
1384   local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;
1386   DEFINES on $(s) += $(>) ;
1387   CCDEFS on $(s) = [ on $(s) FDefines $(DEFINES) ] ;
1391 # /ObjectHdrs  sources : paths ;
1393 # this rule is used to add include paths to the compilation of
1394 # specific C and C++ source files
1396 rule ObjectHdrs {
1397   # Add to HDRS for HdrScan's benefit.
1398   # must reformat CCHDRS according to headers
1399   local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;
1401   HDRS on $(s) += $(>) ;
1402   CCHDRS on $(s) = [ on $(s) FIncludes $(HDRS) ] ;
1406 # /Objects sources ;
1408 # this rule is used to compile one or more sources into object files.
1409 # do not call it directly, it is used by the Main and Library rules
1410 # automatically
1412 rule Objects {
1413   local _i ;
1415   for _i in [ FGristFiles $(<) ] {
1416     Object $(_i:S=$(SUFOBJ)) : $(_i) ;
1417     Depends obj : $(_i:S=$(SUFOBJ)) ;
1418   }
1422 # /SharedObjects
1424 # this rule is used to compile one or more sources into 'shared object
1425 # files'. This means object files used to build either DLLs or Unix shared
1426 # libraries.
1428 # do not call this rule directly, it is called by SharedLibrary automatically
1430 rule SharedObjects {
1431   # temporarily override SUFOBJ with $(SUFOBJSHR) to
1432   local SUFOBJ = $(SUFOBJSHR) ;
1434   # call the normal Objects rule
1435   Objects $(<) ;
1437   # add the compiler-specific position-independent-code flag  where needed
1438   ObjectCcFlags $(<) : $(PICFLAGS) ;
1440   # change the compiler invokation for all these objects
1441   # to use Libtool on Unix systems. We explicitely disable the
1442   # generation of static objects here
1443 #!LIBTOOL!#  if $(UNIX) {
1444 #!LIBTOOL!#    #libtool on $(<:S=$(SUFOBJ)) = [ LibToolFind ] ;
1445 #!LIBTOOL!#    if $(K8_USE_LIBTOOL) {
1446 #!LIBTOOL!#      local libtool = [ LibToolFind ] ;
1447 #!LIBTOOL!#      CC on $(<:S=$(SUFOBJ)) = "$(libtool) --mode=compile $(CC:J= ) -dynamic" ;
1448 #!LIBTOOL!#      C++ on $(<:S=$(SUFOBJ)) = "$(libtool) --mode=compile $(C++:J= ) -dynamic" ; #k8:?
1449 #!LIBTOOL!#    }
1450 #!LIBTOOL!#  }
1454 rule RmTemps {
1455   Temporary $(>) ;
1459 rule Setuid {
1460   MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ;
1464 rule Shell {
1465   Depends shell : $(<) ;
1466   Depends $(<) : $(>) ;
1467   SEARCH on $(>) = $(SEARCH_SOURCE) ;
1468   MODE on $(<) = $(SHELLMODE) ;
1469   Clean clean : $(<) ;
1470   Chmod $(<) ;
1474 rule SoftLink {
1475   Depends files : $(<) ;
1476   Depends $(<) : $(>) ;
1477   SEARCH on $(>) = $(SEARCH_SOURCE) ;
1478   Clean clean : $(<) ;
1482 rule SubDir {
1483   #
1484   # SubDir TOP d1 d2 ... ;
1485   #
1486   # Support for a project tree spanning multiple directories.
1487   #
1488   # SubDir declares a Jamfile's location in a project tree, setting
1489   # Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source
1490   # files can be found.
1491   #
1492   # TOP is a user-select variable name for root of the tree, and
1493   # d1 d2 ...  are the directory elements that lead from the root
1494   # of the tree to the directory of the Jamfile.
1495   #
1496   # TOP can be set externally, but normally the first SubDir call
1497   # computes TOP as the path up from the current directory; the
1498   # path contains one ../ for each of d1 d2 ...
1499   #
1500   # SubDir reads once the project-specific rules file Jamrules
1501   # in the TOP directory, if present.  This can be overridden
1502   # with the variable TOPRULES.
1503   #
1504   # SubDir supports multiple, overlaid project trees:  SubDir
1505   # invocations with different TOPs can appear in the same Jamfile.
1506   # The location established by the first SubDir call is used set
1507   # the TOPs for the subsequent SubDir calls.
1508   #
1509   # SubDir's public variables:
1510   #
1511   #   $(TOP) = path from CWD to root.
1512   #   $(SUBDIR) = path from CWD to the directory SubDir names.
1513   #   $(SUBDIR_TOKENS) = path from $(TOP) to $(SUBDIR) as dir names
1514   #   $(SEARCH_SOURCE) = $(SUBDIR)
1515   #   $(LOCATE_SOURCE) = $(ALL_LOCATE_TARGET) $(SUBDIR)
1516   #   $(LOCATE_TARGET) = $(ALL_LOCATE_TARGET) $(SUBDIR)
1517   #   $(LOCATE_BIN) = $(ALL_LOCATE_BIN) $(ALL_LOCATE_TARGET) $(SUBDIR)
1518   #   $(LOCATE_LIB) = $(ALL_LOCATE_LIB) $(ALL_LOCATE_TARGET) $(SUBDIR)
1519   #   $(LOCATE_LIBSO) = $(ALL_LOCATE_LIBSO) $(ALL_LOCATE_LIB) $(ALL_LOCATE_TARGET) $(SUBDIR)
1520   #   $(SOURCE_GRIST) = $(SUBDIR_TOKENS) with !'s
1521   #
1522   local _top = $(<[1]) ;
1523   local _tokens = $(<[2-]) ;
1524   local _xpath = $(_tokens:J=$(PATH_SEPARATOR)) ;
1526   #Echo "$(_tokens)" ;
1527   #Echo "$(_xpath) ";
1528   if $(_xpath) != "" { _xpath = "$(PATH_SEPARATOR)$(_xpath)" ; }
1530   #local sdr ;
1532   # First time through sets up relative root and includes Jamrules.
1533   if ! $(_top) { Exit "SubDir syntax error" ; }
1535   if ! $($(_top)-SET) {
1536     $(_top)-SET = true ;
1537     # First time we've seen this TOP.
1538     # We'll initialize a number of internal variables:
1539     #
1540     #   $(TOP-UP) = directories from ROOT to a common point
1541     #   $(TOP-DOWN) = directories from common point to TOP
1542     #   $(TOP-ROOT) = root directory for UP/DOWN -- normally CWD
1543     #   $(SUBDIR_UP) = current value of $(TOP-UP)
1544     #   $(SUBDIR_DOWN) = current value of $(TOP-DOWN)
1545     #   $(SUBDIR_ROOT) = current value of $(TOP-ROOT)
1546     #
1547     if $($(_top)) {
1548       # TOP externally set.
1549       # We'll ignore the relative (UP/DOWN) path that
1550       # got us here, and instead remember the hard ROOT.
1551       $(_top)-UP = ;
1552       $(_top)-DOWN = ;
1553       $(_top)-ROOT = $($(_top)) ;
1554     } else {
1555       # TOP not preset.
1557       # Establishing a new TOP.  In the simplest case,
1558       # (SUBDIR_UP/SUBDIR_DOWN/SUBDIR_ROOT unset), it's
1559       # merely a certain number of directories down from
1560       # the current directory, and FSubDirPath will set
1561       # TOP to a path consisting of ../ for each of the
1562       # elements of _tokens, because that represents how
1563       # far below TOP the current directory sits.
1564       #
1565       # In the more complicated case, the starting directory
1566       # isn't the directory of jam's invocation but an
1567       # location established by previous SubDir call.  The
1568       # starting directory is SUBDIR_UP directories up from
1569       # SUBDIR_ROOT, and then SUBDIR_DOWN directories down
1570       # from that.   If SUBDIR_ROOT is not set, that means
1571       # SUBDIR_DOWN and SUBDIR_UP represent the path from
1572       # the directory of jam's invocation.
1573       #
1574       # In the most complicated case, the _tokens also
1575       # represents directories down, because TOP is being
1576       # estalished in a directory other than TOP's root.
1577       # Hopefully, _tokens and SUBDIR_DOWN represent the
1578       # same final directory, relative to the new TOP and
1579       # the previous SubDIr's TOP.  To find the new TOP,
1580       # we have to chop off any common directories from
1581       # then ends of _tokens and SUBDIR_DOWN.  To do so,
1582       # we reverse each of them, call FStripCommon to
1583       # remove the initial common elements, and then
1584       # reverse them again.  After this process, if
1585       # both _tokens and SUBDIR_DOWN have elements, it
1586       # means the directory names estalished by the two
1587       # SubDir calls don't match, and a warning is issued.
1588       # All hell will likely break loose at this point,
1589       # since the whole SubDir scheme relies on the SubDir
1590       # calls accurately naming the current directory.
1592       # Strip common trailing elements of _tokens and SUBDIR_DOWN.
1593       _tokens = [ FReverse $(_tokens) ] ;
1594       SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
1595       FStripCommon _tokens : SUBDIR_DOWN ;
1596       SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
1597       _tokens = [ FReverse $(_tokens) ] ;
1599       if $(SUBDIR_DOWN) && $(_tokens) { Echo "Warning:" SubDir $(<) "misplaced!" ; }
1601       # We'll remember the relative (UP/DOWN) path that
1602       # got us here, plus any hard ROOT starting point
1603       # for the UP/DOWN.  If TOP is never set externally,
1604       # ROOT will always be "" (directory of jam's invocation).
1605       $(_top)-UP = $(SUBDIR_UP) $(_tokens) ;
1606       $(_top)-DOWN = $(SUBDIR_DOWN) ;
1607       $(_top)-ROOT = $(SUBDIR_ROOT:E="") ;
1608       $(_top) = [ FSubDirPath $(_top) ] ;
1609     }
1611     # Set subdir vars for the inclusion of the Jamrules,
1612     # just in case they have SubDir rules of their own.
1613     # Note that SUBDIR_DOWN is empty: it's all the way
1614     # up where the Jamrules live.  These gets overrided
1615     # just after the inclusion.
1616     SUBDIR_UP = $($(_top)-UP) ;
1617     SUBDIR_DOWN = ;
1618     SUBDIR_ROOT = $($(_top)-ROOT) ;
1620     # Include $(TOPRULES) or $(TOP)/Jamrules.
1621     # Include $(TOPRULES) if set.
1622     # Otherwise include $(TOP)/Jamrules if present.
1623     if $($(_top)RULES) {
1624       include $($(_top)RULES) ;
1625     } else {
1626       NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ;
1627       include $(JAMRULES:R=$($(_top)):G=$(_top)) ;
1628     }
1629   }
1631   # Get path from $(TOP) to named directory.
1632   # Save dir tokens for other potential uses.
1633   SUBDIR_UP = $($(_top)-UP) ;
1634   SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ;
1635   SUBDIR_ROOT = $($(_top)-ROOT) ;
1636   SUBDIR_TOKENS = $(SUBDIR_DOWN) ;
1638   SUBDIR = [ FSubDirPath $(<) ] ;
1640   # Now set up SEARCH_SOURCE, LOCATE_TARGET, LOCATE_BIN, SOURCE_GRIST
1641   # These can be reset if needed.  For example, if the source
1642   # directory should not hold object files, LOCATE_TARGET can
1643   # subsequently be redefined.
1644   SEARCH_SOURCE = $(SUBDIR) ;
1646   #if $(SUBDIR) = "." { sdr = "" ; } else { sdr = "$(PATH_SEPARATOR)$(SUBDIR)" ; }
1648   if $(ALL_LOCATE_TARGET) {
1649     LOCATE_TARGET = "$(ALL_LOCATE_TARGET)$(_xpath)" ;
1650     LOCATE_SOURCE = "$(ALL_LOCATE_TARGET)$(_xpath)" ;
1651   } else {
1652     LOCATE_TARGET = $(SUBDIR) ;
1653     LOCATE_SOURCE = $(SUBDIR) ;
1654   }
1656   if $(ALL_LOCATE_BIN) {
1657     LOCATE_BIN = $(ALL_LOCATE_BIN) ;
1658   } else {
1659     LOCATE_BIN = $(LOCATE_TARGET) ;
1660   }
1662   if $(ALL_LOCATE_LIB) {
1663     LOCATE_LIB = $(ALL_LOCATE_LIB) ;
1664   } else {
1665     LOCATE_LIB = $(LOCATE_TARGET) ;
1666   }
1668   if $(ALL_LOCATE_LIBSO) {
1669     LOCATE_LIBSO = $(ALL_LOCATE_LIBSO) ;
1670   } else {
1671     LOCATE_LIBSO = $(LOCATE_LIB) ;
1672   }
1674   #Echo "ALL_LOCATE_LIB = $(ALL_LOCATE_LIB)" ;
1675   #Echo "LOCATE_LIB = $(LOCATE_LIB)" ;
1677   SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ;
1678   #if ! $(LOCATE_BIN) { LOCATE_BIN = $(LOCATE_TARGET) ; }
1680   ## OPT_HEADER_CACHE_EXT
1681   # With the header cache, we can grist all files found
1682   # during a header scan without incurring a performance
1683   # penalty.
1684   #
1685   HDRGRIST = $(SOURCE_GRIST) ;
1687   # Reset per-directory ccflags, hdrs, etc,
1688   # listed in SUBDIRRESET.
1689   # Note use of variable expanded assignment var
1690   SUBDIR$(SUBDIRRESET) = ;
1692   # Invoke user-specific SubDir extensions,
1693   # rule names listed in SUBDIRRULES.
1694   # Note use of variable expanded rule invocation
1695   $(SUBDIRRULES) $(<) ;
1699 rule FSubDirPath {
1700   # FSubDirPath TOP d1 ... ;
1702   # Returns path to named directory.
1704   # If jam is invoked in a subdirectory of the TOP, then we
1705   # need to prepend a ../ for every level we must climb up
1706   # (TOP-UP), and then append the directory names we must
1707   # climb down (TOP-DOWN), plus the named directories d1 ...
1708   # If TOP was set externally, or computed from another TOP
1709   # that was, we'll have to reroot the whole thing at TOP-ROOT.
1710   local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ;
1712   return $(_r:R=$($(<[1])-ROOT)) ;
1716 rule SubDirDcFlags {
1717   SUBDIRDCFLAGS += $(<) ;
1721 rule SubDirCcFlags {
1722   SUBDIRCCFLAGS += $(<) ;
1726 rule SubDirC++Flags {
1727   SUBDIRC++FLAGS += $(<) ;
1731 rule SubDirObjCFlags {
1732   SUBDIROBJCFLAGS += $(<) ;
1736 rule SubDirHdrs {
1737   SUBDIRHDRS += [ FDirName $(<) ] ;
1741 rule SubIncludeMany {
1742   # SubIncludeMany TOP d1 ... ;
1743   #
1744   # Include a subdirectory's Jamfile.
1746   # We use SubDir to get there, in case the included Jamfile
1747   # either doesn't have its own SubDir (naughty) or is a subtree
1748   # with its own TOP.
1749   #Echo "including " $(<) " : " $(>) ;
1751   if ! $($(<[1])) { Exit "SubIncludeMany" $(<[1]) "without prior SubDir" $(<[1]) ; }
1752   SubDir $(<) ;
1753   include $(JAMFILE:D=$(SUBDIR)) ;
1757 rule SubIncludeOnce {
1758   # SubIncludeOnce varname : TOP d1 ... ;
1759   #
1760   # Include a subdirectory's Jamfile.
1762   local _vn = $(<[1]) ;
1763   if ! $($(_vn)) {
1764     #Echo "processing $(_vn)" ;
1765     #Echo "$(>)" ;
1766     $(_vn) = tan ;
1767     SubIncludeMany $(>) ;
1768   #} else {
1769   #  Echo "skiped $(_vn) -- $($(_vn))" ;
1770   #  Echo "$(>)" ;
1771   }
1775 rule SubInclude {
1776   # SubInclude TOP d1 ... ;
1777   #
1778   # Include a subdirectory's Jamfile.
1779   if ! $($(<[1])) { Exit "SubInclude" $(<[1]) "without prior SubDir" $(<[1]) ; }
1780   local _sbiguard = _K8JAM_SUB_GUARD_$(<:J=_) ;
1781   SubIncludeOnce $(_sbiguard) : $(<) ;
1785 rule SubRules {
1786   # SubRules TOP d1 ... : Other-TOP ;
1787   #
1788   # Read another tree's Jamrules, by giving it's path according
1789   # to this tree and it's own name.
1790   if ! $($(<[1])) { Exit "SubRules" $(<[1]) "without prior SubDir" $(<[1]) ; }
1791   SubDir $(<) ;
1792   SubDir $(>) ;
1796 rule Undefines {
1797   UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ;
1801 rule UserObject {
1802   Exit "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ;
1806 rule Yacc {
1807   local _h ;
1809   _h = $(<:BS=.h) ;
1811   # Some places don't have a yacc.
1812   MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;
1813   #MakeLocate $(>) $(_h) : $(LOCATE_SOURCE) ;
1815   if $(YACC) {
1816     #local tmp ;
1817     #tmp = $(<:G=:D) ;
1818     #if $(tmp) { tmp = $(PATH_SEPARATOR)$(tmp) ; }
1819     #tmp = $(LOCATE_SOURCE[1])$(tmp) ;
1820     #CCFLAGS on $(<:S=$(SUFOBJ)) += -I$(tmp) ;
1821     #C++FLAGS on $(<:S=$(SUFOBJ)) += -I$(tmp) ;
1822     #OBJCFLAGS on $(<:S=$(SUFOBJ)) += -I$(tmp) ;
1823     #Echo "-------------------------" ;
1824     #Echo "LS:" "$(LOCATE_SOURCE)" ;
1825     #Echo "tmp:" "$(tmp)" ;
1826     #Echo "out:" "$(<)" ;
1827     #Echo "in :" "$(>)" ;
1828     #Echo "_h :" "$(_h)" ;
1829     #Echo "=========================" ;
1830     #
1831     Depends $(<) $(_h) : $(>) ;
1832     Yacc1 $(<) : $(>) ;
1833     #Yacc1 $(<) $(_h) : $(>) ;
1834     #YaccMv $(<) $(_h) : $(>) ;
1835     Clean clean : $(<) $(_h) ;
1836   }
1838   # make sure someone includes $(_h) else it will be
1839   # a deadly independent target
1840   Includes $(<) : $(_h) ;
1845 # Utility rules; no side effects on these
1849 # /FGrist path to file ;
1851 # Returns a single string that is used as grist
1853 rule FGrist {
1854   return $(<:J=!) ;
1858 rule FGristFiles {
1859   return $(<:G=$(SOURCE_GRIST:E)) ;
1863 rule FGristSourceFiles {
1864   ## LOCAL CHANGE: OPT_HEADER_CACHE_EXT
1865   # With header caching, there is no performance penalty to gristing
1866   # header files. It is also not correct to assume that header
1867   # files have global visibility.
1868   #
1869   # Here we comment out the old version and replace it with the new.
1870 #  # Produce source file name name with grist in it,
1871 #  # if SOURCE_GRIST is set.
1873 #  # Leave header files alone, because they have a global
1874 #  # visibility.
1875 #  if ! $(SOURCE_GRIST) {
1876 #    return $(<) ;
1877 #  } else {
1878 #    local _i _o ;
1880 #    for _i in $(<) {
1881 #      switch $(_i) {
1882 #        case *.h : _o += $(_i) ;
1883 #        case *   : _o += $(_i:G=$(SOURCE_GRIST)) ;
1884 #      }
1885 #    }
1886 #    return $(_o) ;
1887 #  }
1888   return [ FGristFiles $(<) ] ;
1892 rule FReverse {
1893   if $(1) { return [ FReverse $(1[2-]) ] $(1[1]) ; }
1897 rule FSubDir {
1898   # If $(>) is the path to the current directory, compute the
1899   # path (using ../../ etc) back to that root directory.
1900   # Sets result in $(<)
1901   if ! $(<[1]) {
1902     return $(DOT) ;
1903   } else {
1904     local _i _d ;
1906     _d = $(DOTDOT) ;
1907     for _i in $(<[2-]) { _d = $(_d:R=$(DOTDOT)) ; }
1908     return $(_d) ;
1909   }
1913 rule FStripCommon {
1914   # FStripCommon v1 : v2 ;
1916   # Strip common initial elements of variables v1 and v2.
1917   # Modifies the variable values themselves.
1918   if $($(<)[1]) && $($(<)[1]) = $($(>)[1]) {
1919     $(<) = $($(<)[2-]) ;
1920     $(>) = $($(>)[2-]) ;
1921     FStripCommon $(<) : $(>) ;
1922   }
1926 rule FRelPath {
1927   local _l _r ;
1929   # first strip off common parts
1930   _l = $(<) ;
1931   _r = $(>) ;
1932   FStripCommon _l : _r ;
1934   # now make path to root and path down
1935   _l = [ FSubDir $(_l) ] ;
1936   _r = [ FDirName $(_r) ] ;
1938   # Concatenate and save
1939   # XXX This should be better
1940   if $(_r) = $(DOT) { return $(_l) ; } else { return $(_r:R=$(_l)) ; }
1944 rule FAppendSuffix {
1945   # E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;"
1946   # returns (yacc,lex,foo.bat) on Unix and
1947   # (yacc.exe,lex.exe,foo.bat) on NT.
1948   if $(>) {
1949     local _i _o ;
1951     for _i in $(<) {
1952       if $(_i:S) { _o += $(_i) ; } else { _o += $(_i:S=$(>)) ; }
1953     }
1954     return $(_o) ;
1955   } else {
1956     return $(<) ;
1957   }
1962 # Operating system specific utility rules
1963 # First, the (generic) UNIX versions
1966 rule FQuote { return "\\\"$(<)\\\"" ; }
1967 rule FDefines { return -D$(<) ; }
1968 rule FIncludes { return -I$(<) ; }
1970 rule FDirName {
1971   # Turn individual elements in $(<) into a usable path.
1972   local _i ;
1973   local _s = $(DOT) ;
1975   for _i in $(<) { _s = $(_i:R=$(_s)) ; }
1976   return $(_s) ;
1980 if $(NT) && $(JAM_TOOLSET) != MINGW && $(JAM_TOOLSET) != LCC {
1981   rule FDefines { return /D$(<) ; }
1982   rule FIncludes { return /I$(<) ; }
1987 # various install rules
1989 rule AddSlash {
1990   local _ttt = [ Split "$(<[1])" ] ;
1991   local _len = [ ListLength $(_ttt) ];
1992   if $(_len) != "0" && $(_ttt[$(_len)]) != "/" { _ttt = "$(<[1])/" ; } else { _ttt = $(<[1]) ; }
1993   return $(_ttt) ;
1997 rule InstallDestDir {
1998   local ddd = [ AddSlash $(DESTDIR) ] ;
1999   local spl = [ Split $(<) ] ;
2001   if $(spl[1]) != "/" {
2002     local ppp = [ AddSlash $(PREFIX) ] ;
2003     if ! $(ppp) { ppp = "/usr/local/" ; }
2004     if $(ddd) { ppp = $(ddd)$(ppp) ; }
2005     return $(ppp)$(<);
2006   } else {
2007     return $(ddd)$(<) ;
2008   }
2012 # InstallInto dir : sources ;
2013 rule InstallInto {
2014   local i t ddir ;
2016   t = $(>:G=$(INSTALLGRIST)) ;
2017   ddir = [ InstallDestDir $(<) ] ;
2019   # Arrange for jam install
2020   # Arrange for jam uninstall
2021   # sources are in SEARCH_SOURCE
2022   # targets are in dir
2024   Depends install : $(t) ;
2025   Clean uninstall : $(t) ;
2026   SEARCH on $(ddir) = $(SEARCH_SOURCE) ;
2027   MakeLocate $(t) : $(ddir) ;
2029   # For each source, make gristed target name
2030   # and Install, Chmod, Chown, and Chgrp
2031   for i in $(>) {
2032     local tt = $(i:G=$(INSTALLGRIST)) ;
2034     Depends $(tt) : $(i) ;
2035     Install $(tt) : $(i) ;
2036     Chmod $(tt) ;
2038     if $(OWNER) && $(CHOWN) {
2039       Chown $(tt) ;
2040       OWNER on $(tt) = $(OWNER) ;
2041     }
2042     if $(GROUP) && $(CHGRP) {
2043       Chgrp $(tt) ;
2044       GROUP on $(tt) = $(GROUP) ;
2045     }
2046   }
2050 # /InstallBin dir : sources ;
2052 # Copy _sources_ into _dir_ with mode $(EXEMODE)
2054 rule InstallBin {
2055   local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;
2057   InstallInto $(<) : $(_t) ;
2058   MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ;
2062 # /InstallFile dir : sources ;
2064 # Copy _sources_ into _dir_ with mode $(FILEMODE)
2066 rule InstallFile {
2067   InstallInto $(<) : $(>) ;
2068   MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
2072 # /InstallLib dir : sources ;
2074 # Copy _sources_ into _dir_ with mode $(FILEMODE)
2076 rule InstallLib {
2077   InstallInto $(<) : $(>) ;
2078   MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
2082 # /InstallMan dir : sources ;
2084 #  Copy _sources_ into the appropriate subdirectory of _dir_ with mode
2085 #  $(FILEMODE). The subdirectory is manS, where S is the suffix of each of
2086 #  sources.
2088 rule InstallMan {
2089   # Really this just strips the . from the suffix
2090   local i s d ;
2092   for i in $(>) {
2093     switch $(i:S) {
2094       case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;
2095       case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;
2096       case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;
2097       case .n : s = n ; case .man : s = 1 ;
2098     }
2099     d = man$(s) ;
2100     InstallInto $(d:R=$(<)) : $(i) ;
2101   }
2102   MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
2106 # /InstallShell dir : sources ;
2108 # Copy _sources_ into _dir_ with mode $(SHELLMODE)
2110 rule InstallShell {
2111   InstallInto $(<) : $(>) ;
2112   MODE on $(>:G=$(INSTALLGRIST)) = $(SHELLMODE) ;
2116 rule WindozeResourceCompiler {
2117   Depends $(<) : $(>) ;
2118   Clean clean : $(<) ;
2121 rule windoze-fix {
2122   if $(WINDOZE) {
2123     if $(WINDOZE_THREADS) {
2124       CC += -mthreads ;
2125       CC++ += -mthreads ;
2126     }
2127     local ss = $(WINSUBSYS) ;
2128     if ! $(ss) { ss = "console" ; }
2129     LINK += "-Wl,-subsystem,$(ss)" ;
2130     C++LINK += "-Wl,-subsystem,$(ss)" ;
2131     if $(WINLIBS) { LINKLIBS += $(WINLIBS) ; } else { LINKLIBS += -lkernel32 ; }
2132   }
2137 # Actions
2139 actions WindozeResourceCompiler {
2140   "$(WINE)" $(MGPATH)windres.exe -i $(>) -o $(<)
2144 # First the defaults
2146 actions updated together piecemeal Archive {
2147   $(AR) $(<) $(>)
2151 actions As {
2152   $(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>)
2156 actions Cc {
2157   $(CC) -c -o $(<) $(CFLAGS.all) $(CCFLAGS) $(OPTIM.all) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2161 actions C++ {
2162   $(C++) -c -o $(<) $(CFLAGS.all) $(C++FLAGS) $(OPTIM.all) $(C++OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2166 actions ObjC {
2167   $(OBJCC) -c -o $(<) $(CFLAGS.all) $(OBJCFLAGS) $(OPTIM.all) $(OBJCOPTIM) $(CCDEFS) $(CCHDRS) $(>)
2171 actions Dc {
2172   $(DC) -c -of$(<) $(DCFLAGS) $(DOPTIM) $(>)
2176 actions Chgrp {
2177   $(CHGRP) $(GROUP) $(<)
2181 actions Chmod1 {
2182   $(CHMOD) $(MODE) $(<)
2186 actions Chown {
2187   $(CHOWN) $(OWNER) $(<)
2191 actions piecemeal together existing Clean {
2192   $(RM) $(>)
2196 actions File {
2197   $(CP) $(>) $(<)
2201 actions GenFile1 {
2202   $(>[1]) $(<) $(>[2-])
2206 actions HardLink {
2207   $(RM) $(<) && $(LN) $(>) $(<)
2211 actions Install {
2212   $(CP) $(>) $(<)
2216 actions Lex {
2217   $(LEX) -o $(<) $(>)
2221 ##actions LexMv {
2222 ##  $(MV) lex.yy.c $(<)
2226 actions Link bind NEEDLIBS {
2227   $(LINK) $(LINKFLAGS.all) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS.all) $(LINKLIBS)
2230 actions C++Link bind NEEDLIBS {
2231   $(C++LINK) $(LINKFLAGS.all) $(C++LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS.all) $(C++LINKLIBS)
2234 actions ObjC-Link bind NEEDLIBS {
2235   $(OBJCLINK) $(LINKFLAGS.all) $(OBJCLINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS.all) $(OBJCLINKLIBS)
2239 actions updated together piecemeal LinkUnixLibrary bind NEEDLIBS {
2240   $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2243 actions updated together piecemeal C++LinkUnixLibrary bind NEEDLIBS {
2244   $(C++LINK) $(C++LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(C++LINKLIBS)
2248 actions MkDir1 {
2249   $(MKDIR) $(<)
2253 actions together Ranlib {
2254   $(RANLIB) $(<)
2258 actions quietly updated piecemeal together RmTemps {
2259   $(RM) $(>)
2263 actions Shell {
2264 #DONT_TOUCH
2265   $(AWK) '
2266     NR == 1 { print "$(SHELLHEADER)" }
2267     NR == 1 && /^[#:]/ { next }
2268     /^##/ { next }
2269     { print }
2270   ' < $(>) > $(<)
2271 #DONT_TOUCH
2275 actions SoftLink {
2276   $(RM) $(<) && $(LN) -s $(>) $(<)
2280 actions Yacc1 {
2281   $(YACC) $(YACCFLAGS) $(>) -o $(<)
2285 actions YaccMv {
2286   #$(MV) $(YACCFILES).c $(<[1])
2287   #$(MV) $(YACCFILES).h $(<[2])
2292 # RELOCATE - for compilers with broken -o flags
2294 if $(RELOCATE) {
2295   actions C++ {
2296     $(C++) -c $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2297   }
2298   actions Cc {
2299     $(CC) -c $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2300   }
2301   actions ignore CcMv {
2302     [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)
2303   }
2308 # NOARUPDATE - can't update an archive
2310 if $(NOARUPDATE) {
2311   actions Archive {
2312     $(AR) $(<) $(>)
2313   }
2318 # UNIX specific actions
2320 if $(UNIX) {
2321   actions GenFile1 {
2322     PATH="$PATH:."
2323     $(>[1]) $(<) $(>[2-])
2324   }
2329 # NT specific actions
2331 if $(NT) {
2332   if $(JAM_TOOLSET) = MINGW {
2333     actions together piecemeal Archive {
2334       $(AR) $(<) $(>:T)
2335     }
2336     actions Cc {
2337       $(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>)
2338     }
2339     actions C++ {
2340       $(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>)
2341     }
2342     actions DllLink bind DEFFILENAME IMPLIBNAME {
2343       $(LINK) $(LINKFLAGS) -shared -o $(<) $(>) $(DEFFILENAME) -Wl,--out-implib,$(IMPLIBNAME)
2344     }
2345   } else if $(JAM_TOOLSET) = LCC {
2346     actions together piecemeal Archive {
2347       $(AR) /out:$(<) $(>)
2348     }
2349     actions Cc {
2350       $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -Fo$(<) -I$(STDHDRS) $(>)
2351     }
2352     actions Link bind NEEDLIBS {
2353       $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2354     }
2355     actions DllLink bind NEEDLIBS DEFFILENAME {
2356       $(LINK) $(LINKFLAGS) -DLL -o $(<) $(UNDEFS) $(>) $(DEFFILENAME) $(NEEDLIBS) $(LINKLIBS)
2357     }
2358     actions ignore DllLinkMv {
2359       $(MV) $(2) $(1)
2360     }
2361     actions Shell {
2362       $(CP) $(>) $(<)
2363     }
2364   } else if $(JAM_TOOLSET) = PELLESC {
2365     actions together piecemeal Archive {
2366       $(AR) /OUT:$(<) $(>)
2367     }
2368     actions Cc {
2369       $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS)   /Fo $(<) -I$(STDHDRS)  $(>)
2370     }
2371     actions Link bind NEEDLIBS {
2372       $(LINK) $(LINKFLAGS) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS)
2373     }
2374     actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME {
2375       $(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS)
2376     }
2377     actions Shell {
2378       $(CP) $(>) $(<)
2379     }
2380   }
2385 # Ketmar's additions
2387 rule SetCPUFlags {
2388   if $(OS) != "LINUX" {
2389     DETECTED_CPU = "i486" ;
2390     OPTIM_SPEED = -O3 -march=i486 -mtune=i486 ;
2391   } else {
2392     DETECTED_CPU = native ;
2393     OPTIM_SPEED = -O3 -march=native -mtune=native ;
2394   }
2398 # VAR = [ RemoveOptWild regexp-options-to-remove : options-list ] ;
2399 # remove options from list with egrep-like regexps
2400 rule RemoveOptWild {
2401   local oname = $(1) ;
2402   local str = $(2) ;
2403   local res = ;
2404   local f ;
2405   local t ;
2406   #Echo "removing " $(oname) " from " $(str) ;
2407   for f in $(str) {
2408     t = [ Match $(oname) : $(f) ] ;
2409     #Echo $(f) ": " $(t) ;
2410     if $(t[1]) = "" {
2411       #Echo "include: " $(f) ;
2412       res += $(f) ;
2413     }
2414   }
2415   return $(res) ;
2419 # profile rules
2420 K8JAM-KNOWN-PROFILES =
2421   none default  # don't change
2422   empty         # remove optimisation flags
2423   speed         # optimise for speed
2424   size          # optimise for size
2425   debug         # don't optimize, add debug info
2426   standard      # -O2
2430 rule --k8jam-profile-none-- {
2431   Echo "MSG: default profile" ;
2432   OPT_PROFILE = ;
2435 rule --k8jam-profile-empty-- {
2436   Echo "MSG: empty profile" ;
2437   SLACK_PKG_ARCH = "i486" ;
2438   LINKFLAGS.all += -s ;
2441 rule --k8jam-profile-speed-- {
2442   Echo "MSG: 'speed' profile" ;
2443   SLACK_PKG_ARCH = "i686" ;
2444   CFLAGS.all += $(OPTIM_SPEED) ;
2445   LINKFLAGS.all += $(LINKFLAGS_SPEED) ;
2446   OPTIM += -std=gnu99 ;
2449 rule --k8jam-profile-size-- {
2450   Echo "MSG: 'size' profile" ;
2451   SLACK_PKG_ARCH = "i686" ;
2452   CFLAGS.all += $(OPTIM_SIZE) ;
2453   LINKFLAGS.all += $(LINKFLAGS_SIZE) ;
2454   OPTIM += -std=gnu99 ;
2457 rule --k8jam-profile-debug-- {
2458   Echo "MSG: 'debug' profile" ;
2459   SLACK_PKG_ARCH = "i486" ;
2460   LINKFLAGS.all -= -s ;
2461   CFLAGS.all += $(OPTIM_DEBUG) ;
2462   LINKFLAGS.all += $(LINKFLAGS_DEBUG) ;
2463   OPTIM += -std=gnu99 ;
2466 rule --k8jam-profile-standard-- {
2467   Echo "MSG: 'standard' profile" ;
2468   SLACK_PKG_ARCH = "i486" ;
2469   CFLAGS.all += $(OPTIM_STANDARD) ;
2470   LINKFLAGS.all += $(LINKFLAGS_STANDARD) ;
2471   OPTIM += -std=gnu99 ;
2475 # remove-opt-flags $(var)
2476 # remove optimization flags from compiler options
2477 rule remove-opt-flags {
2478   local orm = "^(\\-march\\=)" "^(\\-mtune\\=)" "^(\\-mfpmath\\=)" "^(\\-O.$)" ;
2479   local ormff = "^(\\-f[^n][^o])" ;
2480   local res = [ RemoveOptWild $(orm) $(ormff) : $(<) ] ;
2481   return $(res) ;
2485 rule remove-opt-flags-for-all-compilers {
2486   OPTIM = [ remove-opt-flags $(OPTIM) ] ;
2487   C++OPTIM = [ remove-opt-flags $(C++OPTIM) ] ;
2488   OBJCOPTIM = [ remove-opt-flags $(OBJCOPTIM) ] ;
2489   OPTIM.all = [ remove-opt-flags $(OPTIM.all) ] ;
2491   OPTIM = [ RemoveOptWild $(orm) $(ormff) : $(OPTIM) ] ;
2492   C++OPTIM = [ RemoveOptWild $(orm) $(ormff) : $(C++OPTIM) ] ;
2493   OBJCOPTIM = [ RemoveOptWild $(orm) $(ormff) : $(OBJCOPTIM) ] ;
2494   OPTIM.all = [ RemoveOptWild $(orm) $(ormff) : $(OPTIM.all) ] ;
2498 # profile "name" ;
2499 # set compile flags for profile; works only for gcc/g++
2500 # available profiles:
2501 #  none, default: don't change
2502 #  empty: remove optimisation flags
2503 #  speed: optimise for speed and pIII
2504 #  size: optimise for size
2505 #  debug: don't optimize, add debug info
2506 #  standard: -O2
2507 rule profile {
2508   if ! $(1) in $(K8JAM-KNOWN-PROFILES) {
2509     Echo "known profiles: $(K8JAM-KNOWN-PROFILES)" ;
2510     Exit "unknown profile: $(1)" ;
2511   }
2513   remove-opt-flags-for-all-compilers ;
2514   LINKFLAGS -= "-g" "-s" ;
2515   C++LINKFLAGS -= "-g" "-s" ;
2516   OBJCLINKFLAGS -= "-g" "-s" ;
2517   LINKFLAGS.all -= "-g" "-s" ;
2519   OPT_PROFILE = $(1) ;
2520   --k8jam-profile-$(OPT_PROFILE)-- ;
2522 #SLACK_PKG_ARCH ?= "i486" ;
2525 # selects 'debug', 'standard', 'speed' or 'size' profile according to vars:
2526 #  DEBUG = 1 : debug
2527 #  OPT_SIZE = 1 : size
2528 #  OPT_SPEED = 1 : speed
2529 #  OPT=SIZE or OPT=SPEED
2530 #  default: standard
2531 rule set-profile {
2532   local otp ;
2534   if $(OPT) = "size" { otp = "size" ; }
2535   else if $(OPT) = "SIZE" { otp = "size" ; }
2536   if $(OPT) = "speed" { otp = "speed" ; }
2537   else if $(OPT) = "SPEED" { otp = "speed" ; }
2538   else if $(OPT_SIZE) { otp = "size" ; }
2539   else if $(OPT_SPEED) { otp = "speed" ; }
2541   if $(DEBUG) {
2542     profile "debug" ;
2543   } else if $(otp) = "size" {
2544     profile "size" ;
2545   } else if $(otp) = "speed" {
2546     profile "speed" ;
2547   } else {
2548     profile "standard" ;
2549   }
2550   if $(VALGRIND) {
2551     CFLAGS.all -= "-g" "-s" ;
2552     LINKFLAGS.all -= "-g" "-s" ;
2553     CFLAGS.all += -g ;
2554     LINKFLAGS.all += -g ;
2555   }
2556   if ! $(NO_WARNINGS) {
2557     CFLAGS.all += -Wall ;
2558   }
2562 # set default 'locate' vars -- _build/, etc
2563 rule set-default-subdir-locates {
2564   local bdir ;
2565   local d = $(TOP) ;
2567   if ! $(d) { d = "." ; }
2568   if $(WINDOZE) { bdir = _wbuild ; } else { bdir = _build ; }
2570   ALL_LOCATE_BIN = $(d) ;
2571   ALL_LOCATE_LIBSO = $(d) ;
2572   ALL_LOCATE_TARGET = "$(d)$(PATH_SEPARATOR)$(bdir)" ;
2573   ALL_LOCATE_LIB = "$(d)$(PATH_SEPARATOR)$(bdir)$(PATH_SEPARATOR)_libs" ;
2574   HCACHEFILE = "$(d)$(PATH_SEPARATOR)$(bdir)$(PATH_SEPARATOR).jamhdr.cache" ;
2576   Clean clean : $(HCACHEFILE) ;
2580 rule set-default-target-locations {
2581   set-default-subdir-locates ;
2584 rule set-default-locations {
2585   set-default-subdir-locates ;
2588 rule set-target-locations {
2589   set-default-subdir-locates ;
2594 # windoze setup
2597 rule setup-windoze {
2598   if ! $(WINDOZE) { WINDOZE = 1 ; }
2599   PICFLAGS = ;
2600   SUFLIBSHR = .dll ;
2601   #WINDOZE_THREADS = -mthreads ;
2602   #WINDOZE_THREADS = ;
2603   WINE ?= "wine" ;
2604   MGPATH ?= "c:\\\\mingw\\\\bin\\\\" ;
2605   MGCC ?= "mingw32-gcc.exe -static-libgcc" ;
2606   MG++ ?= "mingw32-g++.exe -static-libgcc -static-libstdc++" ;
2607   CC = "$(WINE)" $(MGPATH)$(MGCC) ;
2608   LINK = "$(WINE)" $(MGPATH)$(MGCC) -Wl,--enable-auto-import ;
2609   AR = "$(WINE)" $(MGPATH)ar.exe -ru ;
2610   RANLIB = "$(WINE)" $(MGPATH)ranlib.exe ;
2611   C++ = "$(WINE)" $(MGPATH)$(MG++) ;
2612   C++LINK = "$(WINE)" $(MGPATH)$(MG++) -Wl,--enable-auto-import ;
2613   #LINKLIBS += -lkernel32 ;
2614   #LINKLIBS += -luser32 ;
2615   #LINKLIBS += -ladvapi32 ;
2616   #LINKLIBS += -lws2_32 ;
2617   #WINSUBSYS = "windows" ;
2618   #WINSUBSYS = "console" ;
2619   SUFEXE = .exe ;
2620   #LINKFLAGS += "-Wl,-subsystem,$(WINSUBSYS)" ;
2624 rule check-setup-windoze {
2625   if $(WINDOZE) { setup-windoze ; }
2629 rule use-mingw32 {
2630   CC = i686-pc-mingw32-gcc -pipe -static-libgcc ;
2631   C++ = i686-pc-mingw32-g++ -pipe -static-libgcc -static-libstdc++ ;
2632   LINK = i686-pc-mingw32-gcc -pipe -Wl,--enable-auto-import ;
2633   C++LINK = i686-pc-mingw32-g++ -pipe -Wl,--enable-auto-import ;
2634   AR = i686-pc-mingw32-ar -ru ;
2635   RANLIB = i686-pc-mingw32-ranlib ;
2637   actions WindozeResourceCompiler {
2638     i686-pc-mingw32-windres -i $(>) -o $(<)
2639   }
2643 # ObjectNoAliasing filelist ;
2644 # turn off aliasing optimization for specified files
2645 # works only for gcc/g++
2646 rule ObjectNoAliasing {
2647   local isGCC = "ona" ;
2648   local isG++ = "ona" ;
2649   if ( "gcc" in $(CC) ) || ( $(JAM_TOOLSET) = MINGW ) { isGCC = "tan" ; }
2650   if ( "g++" in $(C++) ) || ( $(JAM_TOOLSET) = MINGW ) { isG++ = "tan" ; }
2651   if $(JAM_FORCE_GCC_OPTIONS) { isGCC = "tan" ; isG++ = "tan" ; }
2653   if $(isGCC) = "tan" { CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(OPTIM_NOALIAS) ; }
2654   if $(isG++) = "tan" { C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(OPTIM_NOALIAS) ; }
2655   OBJCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(OPTIM_NOALIAS) ;
2659 rule gcc-suggest-attrs {
2660   if $(SUGGEST) {
2661     CFLAGS.all += -Wsuggest-attribute=const ;
2662     CFLAGS.all += -Wsuggest-attribute=pure ;
2663     CFLAGS.all += -Wsuggest-attribute=noreturn ;
2664   }
2668 # call $(1)
2669 # add output to var $(2)
2670 # return resulting (non-empty) string if library is present
2671 # if $(2) = "" -- don't add flags, just return
2672 # [ lib-config-ex "pkg-config sdl --cflags" : "CFLAGS" ]
2673 rule lib-config-ex {
2674   local cf lf res ;
2675   cf = [ Command "$(1) 2>/dev/null" : parse-output exit-code code-first ] ;
2676   if $(cf[1]) = "0" && $(cf[2]) {
2677     res = $(cf[2-]) ;
2678     if $(2) {
2679       $(2) += $(cf[2-]) ;
2680     }
2681   } else {
2682     res = ;
2683   }
2684   return $(res) ;
2688 # call $(1) --cflags and $(1) --libs (many libs provides such configurators)
2689 # add necessary flags to compiler and linker vars
2690 # return "tan" (non-empty string) if library is present
2691 # if $(2) != "" -- don't add flags, just check
2692 # [ lib-config "pkg-config sdl" ]
2693 rule lib-config {
2694   local cf lf hasit ;
2696   cf = [ Command "$(1) --cflags 2>/dev/null" : parse-output exit-code code-first ] ;
2697   #Echo "cf:" $(cf) ;
2698   if $(cf[1]) = "0" && $(cf[2]) {
2699     hasit = "tan" ;
2700     #Echo "flags:" $(cf[2-]) ;
2701     if ! $(2) {
2702       CCFLAGS += $(cf[2-]) ;
2703       C++FLAGS += $(cf[2-]) ;
2704       OBJCFLAGS += $(cf[2-]) ;
2705     }
2706   }
2708   lf = [ Command "$(1) --libs 2>/dev/null" : parse-output exit-code code-first ] ;
2709   #Echo "lf:" $(lf) ;
2710   if $(lf[1]) = "0" && $(lf[2]) {
2711     hasit = "tan" ;
2712     #Echo "flags:" $(lf[2-]) ;
2713     if ! $(2) {
2714       LINKFLAGS += $(lf[2-]) ;
2715       C++LINKFLAGS += $(lf[2-]) ;
2716       OBJCLINKFLAGS += $(lf[2-]) ;
2717     }
2718   }
2720   return $(hasit) ;
2723 rule pkg-config {
2724   local res ;
2725   res = [ lib-config "pkg-config $(1)" ] ;
2726   return $(res) ;
2730 rule pkg-config-has {
2731   local res ;
2732   res = [ lib-config-ex "pkg-config $(1) --cflags --libs" ] ;
2733   return $(res) ;
2737 rule sys-has-command {
2738   local cf ;
2740   cf = [ Command "which \"$(1)\" 2>/dev/null 1>&2" : exit-code code-first ] ;
2741   #Echo "cf:" $(cf) ;
2742   if $(cf[1]) = "0" {
2743     return "tan" ;
2744   }
2746   return "" ;
2751 # Objective C vars
2754 OBJC_GNUSTEP_BASE_LIB = gnustep-base ;
2755 OBJC_GNUSTEP_GUI_LIB = gnustep-gui ;
2758 # Objective C rules
2760 rule ObjCUseGNUstepBase {
2761   if ! $(K8_INTERNAL_GNUSTEP_BASE) {
2762     #Echo "-l$(OBJC_GNUSTEP_BASE_LIB)" ;
2763     OBJCLINKLIBS += "-l$(OBJC_GNUSTEP_BASE_LIB)" ;
2764     K8_INTERNAL_GNUSTEP_BASE = tan ;
2765   }
2768 rule ObjCUseGNUstepGui {
2769   ObjCUseGNUstepBase ;
2770   if ! $(K8_INTERNAL_GNUSTEP_GUI) {
2771     K8_INTERNAL_GNUSTEP_GUI = tan ;
2772     #Echo "-l$(OBJC_GNUSTEP_GUI_LIB)" ;
2773     OBJCLINKLIBS += "-l$(OBJC_GNUSTEP_GUI_LIB)" ;
2774   }
2777 rule ObjCUseGNUstep {
2778   ObjCUseGNUstepBase ;
2779   ObjCUseGNUstepGui ;
2784 # 'help' and 'push' targets
2786 rule ShowHelpProfile {
2787   NotFile help-profile ;
2788   Always help-profile ;
2789   AShowHelpProfile help-profile ;
2791 actions quietly AShowHelpProfile {
2792   echo "profile flags:"
2793   echo "  DEBUG=1           -- debug build"
2794   echo "  OPT_SPEED=1       -- optimize for speed"
2795   echo "  OPT_SIZE=1        -- optimize for size"
2796   echo "  VALGRIND=1        -- do not strip debug info"
2797   echo "  NO_WARNINGS=1     -- do not all '-Wall' flag"
2798   echo "WARNING: DON'T FORGET TO DO 'jam clean' before building with new flags!"
2800 ShowHelpProfile ;
2802 rule ShowHelp {
2803   NotFile help ;
2804   Always help ;
2805   AShowHelp help ;
2806   #AShowHelpProfile help ;
2808 actions quietly AShowHelp {
2809   echo "WARNING: default help; override 'actions AShowHelp' definition to use 'help' target!"
2811 ShowHelp ;
2813 rule GitPush {
2814   NotFile push ;
2815   Always push ;
2816   AGitPush push ;
2818 actions quietly AGitPush {
2819   echo "WARNING: add 'actions AGitPush' definition to use 'push' target!"
2821 GitPush ;
2824 check-setup-windoze ;
2827 # Now include the user's Jamfile.
2829 include $(JAMFILE) ;