fixed rule for flex
[k8jam.git] / defaults / Jambase
blob224cc0b916cbec3b32d376313dad54a986f6ce1b
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=native -mtune=native -mfpmath=sse ;
198 LINKFLAGS_SPEED = -s ;
200 OPTIM_SIZE = -Os -march=native -mtune=native ;
201 LINKFLAGS_SIZE = -s ;
203 OPTIM_DEBUG = -O0 -g ;
204 LINKFLAGS_DEBUG = -g ;
206 OPTIM_NOALIAS = -fno-strict-aliasing ;
210 # OS specific variable settings
213 ###############################################################################
214 # Windoze
215 ###############################################################################
216 if $(NT) {
217   PATH_SEPARATOR = "\\" ;
218   local SUPPORTED_TOOLSETS =
219     MINGW
220     LCC
221     PELLESC
222   ;
224   # if the JAM_TOOLSET environment variable is defined, check that it is
225   # one of our supported values
226   #
227   if $(JAM_TOOLSET) {
228     if ! $(JAM_TOOLSET) in $(SUPPORTED_TOOLSETS) {
229       Echo "The JAM_TOOLSET environment variable is defined but its value" ;
230       Echo "is invalid, please use one of the following:" ;
231       Echo ;
232       for t in $(SUPPORTED_TOOLSETS) { Echo "  " $(t) ; }
233       Exit ;
234     }
235   }
237   if ! $(JAM_TOOLSET) {
238     Echo "The JAM_TOOLSET environment variable is not defined, defaults to MINGW" ;
239     JAM_TOOLSET = MINGW ;
240     MINGW = "c:\\mingw\\" ;
241   }
243   MV        ?= move /y ;
244   CP        ?= copy ;
245   RM        ?= del /f/q ;
246   RMDIR     ?= rmdir /s/q ;
247   SLASH     ?= \\ ;
248   SUFLIB    ?= .lib ;
249   SUFOBJ    ?= .obj ;
250   SUFEXE    ?= .exe ;
251   SUFLIBSHR ?= .dll ;
253   if $(JAM_TOOLSET) = MINGW {
254     Echo "Compiler is GCC with MinGW" ;
255     AR           ?= ar -ru ;
256     RANLIB       ?= ranlib ;
257     CC           ?= mingw-gcc ;
258     CCFLAGS      ?= "" ;
259     C++          ?= mingw-g++ ;
260     C++FLAGS     ?= $(CCFLAGS) ;
261     LINK         ?= $(CC) ;
262     LINKFLAGS    ?= "" ;
263     LINKLIBS     ?= -lkernel32 ;
264     OPTIM        ?= ;
265     SUFOBJ        = .o ;
266     SUFLIB        = .a ;
267     SLASH         = / ;
268     # MinGW-specific thingy
269     MINGW_GUI     = "-Wl,-subsystem,windows" ;
270     MINGW_THREADS = "-mthreads" ;
271     # k8
272     C++OPTIM     ?= $(OPTIM) ;
273     C++LINK      ?= $(C++) ;
274     C++LINKFLAGS ?= $(LINKFLAGS) ;
275     C++LINKLIBS  ?= $(LINKLIBS) ;
276     #NOARSCAN     ?= true ;
277     # set path if any
278     if $(MINGW) {
279       CC = "$(MINGW)$(CC:J= )" ;
280       C++ = "$(MINGW)$(C++:J= )" ;
281       LINK = "$(MINGW)$(LINK:J= )" ;
282       C++LINK = "$(MINGW)$(C++LINK:J= )" ;
283       AR = "$(MINGW)$(AR:J= )" ;
284       RANLIB = "$(MINGW)$(RANLIB:J= )" ;
285     }
286   } else if $(JAM_TOOLSET) = LCC {
287     Echo "Compiler is Win32-LCC" ;
288     AR        ?= lcclib ;
289     CC        ?= lcc ;
290     CCFLAGS   ?= "" ;
291     C++       ?= "error" ;
292     LINK      ?= lcclnk ;
293     LINKFLAGS ?= "" ;
294     LINKLIBS  ?= "" ;
295     OPTIM     ?= ;
296     NOARSCAN   = true ;
297     # k8
298     C++LINK    = "error" ;
299   } else if $(JAM_TOOLSET) = PELLESC {
300     Echo "Compiler is PellesC" ;
301     AR        ?= polib ;
302     CC        ?= pocc ;
303     CCFLAGS   ?= "" ;
304     C++       ?= "error" ;
305     LINK      ?= polink ;
306     LINKFLAGS ?= ;
307     LINKLIBS  ?= ;
308     OPTIM     ?= ;
309     NOARSCAN   = true ;
310     LINKLIBS  ?= crt.lib oldnames.lib Win\\kernel32.lib ;
311     # k8
312     C++LINK    = "error" ;
313   } else {
314     # XXX: We need better comments here !!
315     Exit "On NT, set MINGW to the root of the MinGW dir (but it won't help you anyway)" ;
316   }
317   STDHRS ?= "" ;
318   PICFLAGS = ;
320 ###############################################################################
321 # UNIX
322 ###############################################################################
323 else if $(UNIX) {
324   PATH_SEPARATOR = "/" ;
325   switch $(OS) {
326     case CYGWIN :
327       CC       ?= gcc ;
328       CCFLAGS  += -D__cygwin__ ;
329       LEX      ?= flex ;
330       JAMSHELL ?= sh -c ;
331       RANLIB   ?= "" ;
332       SUFEXE   ?= .exe ;
333       YACC     ?= bison -y ;
334     }
336     # UNIX defaults
337     CC        ?= gcc ;
338     C++       ?= g++ ;
339     OBJCC     ?= gcc ;
340     CCFLAGS   ?= ;
341     OBJCFLAGS ?= $(CCFLAGS) ;
342     C++FLAGS  ?= $(CCFLAGS) ;
343     CHMOD     ?= chmod ;
344     CHGRP     ?= chgrp ;
345     CHOWN     ?= chown ;
346     LEX       ?= flex ;
347     LINKFLAGS ?= $(CCFLAGS) ;
348     LINKLIBS  ?= ;
349     OPTIM     ?= ;
350     RANLIB    ?= ranlib ;
351     YACC      ?= bison ;
352     YACCGEN   ?= .c ;
353     YACCFILES ?= y.tab ;
354     YACCFLAGS ?= -ld ;
355 #!LIBTOOL!#    if $(K8_USE_LIBTOOL) {
356 #!LIBTOOL!#      SUFOBJSHR ?= .lo ;
357 #!LIBTOOL!#      SUFLIBSHR ?= .la ;
358 #!LIBTOOL!#    } else {
359 #!LIBTOOL!#      SUFOBJSHR ?= .o ;
360 #!LIBTOOL!#      SUFLIBSHR ?= .so ;
361 #!LIBTOOL!#    }
362     SUFOBJSHR ?= .o ;
363     SUFLIBSHR ?= .so ;
364 #!LIBTOOL!#
365     PICFLAGS  ?= -fpic ;
366     STDHDRS   ?= /usr/include ;
369 # shared library object file suffix. We assume that it is identical
370 # than the normal one
371 SUFOBJSHR ?= $(SUFOBJ) ;
372 SUFLIBSHR ?= $(SUFLIB) ;
375 # the D compiler
376 DC ?= dmd ;
379 # General defaults; a lot like UNIX
381 PATH_SEPARATOR ?= "/" ;
382 AR          ?= ar ru ;
383 AS          ?= as ;
384 ASFLAGS     ?= ;
385 AWK         ?= awk ;
386 BINDIR      ?= /usr/local/bin ;
387 C++         ?= g++ ;  # k8: was cc
388 C++FLAGS    ?= ;
389 CC          ?= gcc ;  # k8: was cc
390 CCFLAGS     ?= ;
391 CP          ?= cp -f ;
392 CRELIB      ?= ;
393 DOT         ?= . ;
394 DOTDOT      ?= .. ;
395 EXEMODE     ?= 755 ;
396 FILEMODE    ?= 644 ;
397 HDRS        ?= ;
398 INSTALLGRIST    ?= installed ;
399 JAMFILE     ?= Jamfile ;
400 JAMRULES    ?= Jamrules ;
401 LEX         ?= ;
402 LIBDIR      ?= /usr/local/lib ;
403 LINK        ?= $(CC) ;
404 LINKFLAGS   ?= ;
405 LINKLIBS    ?= ;
406 LN          ?= ln ;
407 MANDIR      ?= /usr/local/man ;
408 MKDIR       ?= mkdir ;
409 MV          ?= mv -f ;
410 OPTIM       ?= ;
411 RCP         ?= rcp ;
412 RM          ?= rm -f ;
413 RMDIR       ?= $(RM) ;
414 RSH         ?= rsh ;
415 SED         ?= sed ;
416 SHELLHEADER ?= "#!/bin/sh" ;
417 SHELLMODE   ?= 755 ;
418 SLASH       ?= / ;
419 SUBDIRRULES ?= ;
420 SUBDIRRESET ?= ASFLAGS HDRS C++FLAGS CCFLAGS ;
421 SUFEXE      ?= "" ;
422 SUFLIB      ?= .a ;
423 SUFOBJ      ?= .o ;
424 UNDEFFLAG   ?= "-u _" ;
425 YACC        ?= ;
426 YACCGEN     ?= ;
427 YACCFILES   ?= ;
428 YACCFLAGS   ?= ;
430 HDRPATTERN = "^[[:space:]]*#[[:space:]]*include[[:space:]]*[<\"]([^\">]*)[\">].*$" ;
432 OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;
434 # k8
435 C++OPTIM     ?= $(OPTIM) ;
436 C++LINK      ?= $(C++) ;
437 C++LINKFLAGS ?= $(LINKFLAGS) ;
438 C++LINKLIBS  ?= $(LINKLIBS) ;
440 OBJCOPTIM     ?= $(OPTIM) ;
441 OBJCLINK      ?= $(CC) ;
442 OBJCLINKFLAGS ?= $(LINKFLAGS) ;
443 OBJCLINKLIBS  ?= $(LINKLIBS) ;
444 OBJCLINKLIBS  += -lobjc ;
446 if $(OS) = "LINUX" {
447   if ( "gcc" in $(CC) ) && ! ( "-pipe" in $(CC) ) { CC += -pipe ; }
448   if ( "g++" in $(C++) ) && ! ( "-pipe" in $(C++) ) { C++ += -pipe ; }
451 #Echo "OS:" $(OS) ;
452 #Echo "OSFULL:" $(OSFULL) ;
453 #Echo "UNIX:" $(UNIX) ;
458 # Base dependencies - first for "bootstrap" kinds of rules
460 Depends all : shell files lib exe obj ;
461 Depends all shell files lib exe obj : first ;
462 NotFile all first shell files lib exe obj dirs clean uninstall ;
463 Always  clean uninstall ;
466 # Rules
469 # /As object : source ;
471 # Assemble the file _source_, called by the @Object rule.
473 # Do not call this rule directly, since _object_ and _source_ may have
474 # have platform-specific file extensions
476 rule As {
477   Depends $(<) : $(>) ;
478   ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;
479   ASHDRS on $(<) = [ FIncludes $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
482 # /Bulk  directory : sources ;
484 # Copies _sources_ into _directory_
486 rule Bulk {
487   local i ;
489   for i in $(>) {
490     File $(i:D=$(<)) : $(i) ;
491   }
495 # /Dc object : source ;
497 # Compile the file source into object, usin the D compiler $(DC), its
498 # flags $(DCFLAGS) and $(DOPTIM)
499 # Called by the @Object rule
501 # Do not call this rule directly, since _object_ and _source_ may have
502 # have platform-specific file extensions
504 rule Dc {
505   Depends $(<) : $(>) ;
506   # Just to clarify here: this sets the per-target DCFLAGS to
507   # be the current value of (global) DCFLAGS and SUBDIRDCFLAGS.
508   DCFLAGS on $(<) += $(DCFLAGS) $(SUBDIRDCFLAGS) ;
512 # /Cc object : source ;
514 # Compile the file source into object, using the C compiler $(CC), its
515 # flags $(CCFLAGS) and $(OPTIM), and the header file directories $(HDRS).
516 # Called by the @Object rule
518 # Do not call this rule directly, since _object_ and _source_ may have
519 # have platform-specific file extensions
521 rule Cc {
522   Depends $(<) : $(>) ;
524   # If the compiler's -o flag doesn't work, relocate the .o
525   if $(RELOCATE) { CcMv $(<) : $(>) ; }
527   # Just to clarify here: this sets the per-target CCFLAGS to
528   # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
529   # CCHDRS and CCDEFS must be reformatted each time for some
530   # compiles (VMS, NT) that malign multiple -D or -I flags.
531   CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ;
532   CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
533   CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
537 # /C++ object : source ;
539 # Compile the C++ source file _source_. Similar to @CC, called by @Object
541 # Do not call this rule directly, since _object_ and _source_ may have
542 # have platform-specific file extensions
544 rule C++ {
545   local ktmp ;
547   Depends $(<) : $(>) ;
549   if $(RELOCATE) { CcMv $(<) : $(>) ; }
551   # Just to clarify here: this sets the per-target CCFLAGS to
552   # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
553   # CCHDRS and CCDEFS must be reformatted each time for some
554   # compiles (VMS, NT) that malign multiple -D or -I flags.
555   ktmp = $(C++FLAGS) ;
556   if ! $(ktmp) { ktmp = $(CCFLAGS) ; }
557   C++FLAGS on $(<) += $(ktmp) $(SUBDIRC++FLAGS) ;
559   ktmp = $(C++OPTIM) ;
560   if ! $(ktmp) { ktmp = $(OPTIM) ; }
561   C++OPTIM on $(<) += $(ktmp) ;
563   CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
564   CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
568 # /ObjC object : source ;
570 # Compile the ObjC source file _source_. Similar to @CC, called by @Object
572 # Do not call this rule directly, since _object_ and _source_ may have
573 # have platform-specific file extensions
575 rule ObjC {
576   local ktmp ;
578   Depends $(<) : $(>) ;
580   if $(RELOCATE) { CcMv $(<) : $(>) ; }
582   # Just to clarify here: this sets the per-target CCFLAGS to
583   # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS.
584   # CCHDRS and CCDEFS must be reformatted each time for some
585   # compiles (VMS, NT) that malign multiple -D or -I flags.
586   ktmp = $(OBJCFLAGS) ;
587   if ! $(ktmp) { ktmp = $(CCFLAGS) ; }
588   OBJCFLAGS on $(<) += $(ktmp) $(SUBDIROBJCFLAGS) ;
590   ktmp = $(OBJCOPTIM) ;
591   if ! $(ktmp) { ktmp = $(OBJCOPTIM) ; }
592   OBJCOPTIM on $(<) += $(ktmp) ;
594   CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
595   CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
599 # /Chmod target ;
601 # (Unix and VMS only). Change file permissions on _target_ to target-specific
602 # $(MODE) value set by @Link, @File, @Install* and @Shell rules
604 rule Chmod {
605   if $(CHMOD) { Chmod1 $(<) ; }
608 # /Clean  clean : targets ;
610 # Removes existing _targets_ when _clean_ is built. clean is not a dependency
611 # of all, and must be built explicitely for targets to be removed
615 # /File target : source ;
617 # Copies _source_ into _target_
619 rule File {
620   Depends files : $(<) ;
621   Depends $(<) : $(>) ;
622   SEARCH on $(>) = $(SEARCH_SOURCE) ;
623   MODE on $(<) = $(FILEMODE) ;
624   Chmod $(<) ;
628 # /GenFile target : image sources ;
630 # Runs the command "_image_ _target_ _sources_" to create _target_ from
631 # _sources_ and _image_ (where _image_ is an executable built by the
632 # @Main rule)
634 rule GenFile {
635   local _t = [ FGristSourceFiles $(<) ] ;
636   local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;
637   Depends $(_t) : $(_s) $(>[2-]) ;
638   GenFile1 $(_t) : $(_s) $(>[2-]) ;
639   Clean clean : $(_t) ;
642 rule GenFile1 {
643   MakeLocate $(<) : $(LOCATE_SOURCE) ;
644   SEARCH on $(>) = $(SEARCH_SOURCE) ;
648 # /HardLink target : source ;
650 # Makes _target_ a hard link to _source_, if it isn't one already
651 # (Unix only)
653 rule HardLink {
654   Depends files : $(<) ;
655   Depends $(<) : $(>) ;
656   SEARCH on $(>) = $(SEARCH_SOURCE) ;
660 # /HdrMacroFile
662 # this rule is specific to FT-Jam. It is used to indicate that a given file
663 # contains definitions for filename macros (e.g. "#define MYFILE_H <myfile>.h")
664 # that can later be used in #include statements in the rest of the source
666 # these files must be parsed before any make is tried.
668 rule HdrMacroFile {
669   HDRMACRO $(<) ;
673 # /HdrRule source : headers ;
675 # Arranges the proper dependencies when the file _source_ includes the files
676 # _headers_ through the #include C preprocessor directive
678 # this rule is not intendend to be called explicitely. It is called
679 # automatically during header scanning on sources handled by the @Object
680 # rule (e.g. sources in @Main or @Library rules)
682 rule HdrRule {
683   # HdrRule source : headers ;
685   # N.B.  This rule is called during binding, potentially after
686   # the fate of many targets has been determined, and must be
687   # used with caution: don't add dependencies to unrelated
688   # targets, and don't set variables on $(<).
690   # Tell Jam that anything depending on $(<) also depends on $(>),
691   # set SEARCH so Jam can find the headers, but then say we don't
692   # care if we can't actually find the headers (they may have been
693   # within ifdefs),
695   local s = $(>:G=$(HDRGRIST:E)) ;
697   Includes $(<) : $(s) ;
698   SEARCH on $(s) = $(HDRSEARCH) ;
699   NoCare $(s) ;
701   # Propagate on $(<) to $(>)
703   HDRSEARCH on $(s) = $(HDRSEARCH) ;
704   HDRSCAN on $(s) = $(HDRSCAN) ;
705   HDRRULE on $(s) = $(HDRRULE) ;
706   HDRGRIST on $(s) = $(HDRGRIST) ;
710 # /Lex source.c : source.l ;
712 # Process the lex source file _source.l_ and rename the lex.yy.c
713 # to _source.c_ . Called by the @Object rule
715 rule Lex {
716   ##LexMv $(<) : $(>) ;
717   Depends $(<) : $(>) ;
718   MakeLocate $(<) : $(LOCATE_SOURCE) ;
719   Clean clean : $(<) ;
723 # /Library  library : sources ;
725 #  Compiles _sources_ and archives them into _library_. The intermediate
726 #  objects are deleted. Calles @Object and @LibraryFromObjects
728 #  If @Library is invoked with no suffix on _library_, the $(SUFLIB)
729 #  suffix is used
731 rule Library {
732   LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
733   Objects $(>) ;
737 # /SharedLibrary  library : sources : def : import ;
739 # Compiles _sources_ and generates a shared _library_ (i.e. DLL on Windows,
740 # or shared object on Unix). Calls @SharedObjects and @SharedLibraryFromObjects
742 # If @SharedLibrary is invoked with no suffix on _library_, then
743 # $(SUFLIBSHR) suffix is used
745 # _def_ is the name of the corresponding definition file used to generate
746 # the library on Windows and OS/2 (ignored otherwise). If undefined, it
747 # will default to _library_ with the .def suffix
749 # _import_ is the name of the corresponding import library for Windows
750 # and OS/2 platforms (ignored otherwise). If undefined, it will default
751 # to _library_ with the .dll.lib suffix.
753 rule SharedLibrary {
754   #Echo "SharedLibrary: $(<)" ; #dbg
755   #Echo "SharedLibrary: $(>:S=$(SUFOBJSHR))" ; #dbg
756   #Echo "SharedLibrary: $(3)" ; #dbg
757   #Echo "SharedLibrary: $(4)" ; #dbg
758   SharedLibraryFromObjects $(<) : $(>:S=$(SUFOBJSHR)) : $(3) : $(4) ;
759   SharedObjects $(>) ;
762 ######################################################
763 # k8: REWORK!
764 ######################################################
765 #!LIBTOOL!#if $(UNIX) {
766 #!LIBTOOL!#  # this rule is used to find the 'libtool' script in the current
767 #!LIBTOOL!#  # path, this is required when compiling shared objects on Unix
768 #!LIBTOOL!#  rule LibToolFind {
769 #!LIBTOOL!#    if $(LIBTOOL) { return $(LIBTOOL) ; }
770 #!LIBTOOL!#    local matches = [ Glob $(PATH) : libtool ] ;
771 #!LIBTOOL!#    if ! $(matches) { Exit "could not find 'libtool' program in current path. Aborting !" ; }
772 #!LIBTOOL!#    LIBTOOL = $(matches[1]) ;
773 #!LIBTOOL!#    return $(LIBTOOL) ;
774 #!LIBTOOL!#  }
775 #!LIBTOOL!#}
778 # /LibraryFromObjects library : objects ;
780 # Archives _objects_ into _library_. The _objects_ are then deleted
782 # If _library_ has no suffix, the $(SUFLIB) suffix is used
784 # Called by @Library rule. Most people should never call this rule
785 # directly.
787 rule LibraryFromObjects {
788   local _i _l _s ;
790   # Add grist to file names
791   _s = [ FGristFiles $(>) ] ;
792   _l = $(<:S=$(SUFLIB)) ;
794   # library depends on its member objects
795   if $(KEEPOBJS) {
796     Depends obj : $(_s) ;
797   } else {
798     Depends lib : $(_l) ;
799   }
801   # Set LOCATE for the library and its contents.  The bound
802   # value shows up as $(NEEDLIBS) on the Link actions.
803   # For compatibility, we only do this if the library doesn't
804   # already have a path.
805   if ! $(_l:D) {
806     #!!MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;
807     MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_LIB) ;
808   }
810   if $(NOARSCAN) {
811     # If we can't scan the library to timestamp its contents,
812     # we have to just make the library depend directly on the
813     # on-disk object files.
814     Depends $(_l) : $(_s) ;
815   } else {
816     # If we can scan the library, we make the library depend
817     # on its members and each member depend on the on-disk
818     # object file.
819     Depends $(_l) : $(_l)($(_s:BS)) ;
820     for _i in $(_s) {
821       Depends $(_l)($(_i:BS)) : $(_i) ;
822     }
823   }
825   Clean clean : $(_l) ;
827   if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
829   Archive $(_l) : $(_s) ;
831   if $(RANLIB) { Ranlib $(_l) ; }
833   # If we can't scan the library, we have to leave the .o's around.
834   if ! ( $(NOARSCAN) || $(NOARUPDATE) ) { RmTemps $(_l) : $(_s) ; }
838 # /SharedLibraryFromObjects  library : objects : def : import ;
840 # Equivalent of @LibraryFromObjects for shared libraries.
842 # Called by @SharedLibrary. Most people shouldn't call this rule
843 # directly
845 rule SharedLibraryFromObjects {
846   local _i _l _s ;
848   # Add grist to file names
849   _s = [ FGristFiles $(>) ] ;
850   _l = $(<:S=$(SUFLIBSHR)) ;
852   #Echo "Library is $(_l)"    ;
853   # library depends on its member objects
854   if $(KEEPOBJS) {
855     Depends obj : $(_s) ;
856   } else {
857     Depends lib : $(_l) ;
858   }
860   # Set LOCATE for the library and its contents.  The bound
861   # value shows up as $(NEEDLIBS) on the Link actions.
862   # For compatibility, we only do this if the library doesn't
863   # already have a path.
864   if ! $(_l:D) {
865     #!!MakeLocate $(_l) : $(LOCATE_TARGET) ;
866     MakeLocate $(_l) : $(LOCATE_LIBSO) ;
867   }
869   #Echo "SharedLibraryFromObjects: _s = $(_s)" ; #dbg
870   #Echo "SharedLibraryFromObjects: _l = $(_l)" ; #dbg
872   # we never scan shared libraries for member objects
873   Depends $(_l) : $(_s) ;
875   Clean clean : $(_l) ;
877   # I don't know if VMS supports shared libraries, so I prefer
878   # to disable the following right now
879   #
880   #if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
882   # creating the library is so much fun on Unix :-)
883   if $(UNIX) {
884 #!LIBTOOL!#    if $(K8_USE_LIBTOOL) {
885 #!LIBTOOL!#      local libtool = [ LibToolFind ] ;  # find the right libtool
886 #!LIBTOOL!#      AR on $(_l) = "$(libtool) --mode=link $(AR:J= )" ;
887 #!LIBTOOL!#    } else {
888       LINKFLAGS on $(_l) += "-shared" ;
889       C++LINKFLAGS on $(_l) += "-shared" ;
890       LinkUnixLibrary $(_l) : $(_s) ;
891 #!LIBTOOL!#    }
892   } else if $(NT) {
893     local _implib = $(4) ;
894     local _def    = $(3) ;
896     _implib ?= $(_l:S=$(SUFLIBSHR)$(SUFLIB)) ;
897     _def    ?= $(_l:S=.def) ;
899     Clean    clean : $(_implib) ;
900     Depends  lib   : $(_implib) $(_def) ;
902     Depends $(_implib) : $(_def) $(_l) ;
903     Depends $(_l)      : $(_def) ;
905     DEFFILENAME on $(_l) = $(_def) ;
906     IMPLIBNAME  on $(_l) = $(_implib) ;
908     #!!MakeLocate $(_implib)        : $(LOCATE_TARGET) ;
909     #!!MakeLocate $(_implib:S=.exp) : $(LOCATE_TARGET) ;
910     MakeLocate $(_implib)        : $(LOCATE_LIBSO) ;
911     MakeLocate $(_implib:S=.exp) : $(LOCATE_LIBSO) ;
913     if $(JAM_TOOLSET) in VISUALC BORLANDC LCC WATCOM DIGITALMARS {
914       SharedLink-$(JAM_TOOLSET) $(_l) : $(_s) : $(_implib) : $(_def) ;
915     }
916     DllLink $(_l) : $(_s) ;
917   } else {
918     Echo "Sorry, I don't know how to make a shared library on your system" ;
919     Exit "Please *DON'T* contact the K8Jam maintainer for help" ;
920   }
924 # Since building shared libraries is so different depending on the
925 # compiler being used, I've broken this task into compiler-specific
926 # ones
928 rule SharedLink-LCC {
929   Echo "Sorry, but generating DLLs with LCC is not supported. That's" ;
930   Echo "because the 'lcclnk' tool that comes with this compiler is" ;
931   Echo "unreliable and doesn't work as expected." ;
932   Exit ;
934   # the 'lcclnk' tool is absolutely broken:
935   #   - its -o flag doesn't work when there is a LIBRARY statement
936   #     in the .def file.
937   #
938   #   - it uses the LIBRARY name in the .def file to determine
939   #     the name of the dll and its import library, and always
940   #     places them in the current directory !!
941   #
942   #   - if there is no LIBRARY statement, the -o flag is only
943   #     used to determine where the DLL is placed, the import
944   #     library will always be placed in the current directory !!
945   #
947   # clean the .exp file too, don't know how to get rid of it
948   Clean clean : $(4:S=.exp) ;
952 # /Link  image : objects ;
954 # Links _image_ from _objects_ and sets permissions on _image_ to
955 # $(EXEMODE). _image_ must be an actual filename; suffix is not
956 # supplied.
958 # Called by @Main, shouldn't be called by most people
960 rule Link {
961   MODE on $(<) = $(EXEMODE) ;
962   Chmod $(<) ;
966 # /C++Link  image : objects ;
968 # Links _image_ from _objects_ and sets permissions on _image_ to
969 # $(EXEMODE). _image_ must be an actual filename; suffix is not
970 # supplied.
972 # Called by @Main, shouldn't be called by most people
974 rule C++Link {
975   MODE on $(<) = $(EXEMODE) ;
976   Chmod $(<) ;
979 rule ObjC-Link {
980   MODE on $(<) = $(EXEMODE) ;
981   Chmod $(<) ;
985 # /LinkLibraries image : libraries ;
987 # Makes _image_ depend on _libraries_ and includes them during linking
989 # _image_ may be referenced without a suffix in this rule invocation.
990 # @LinkLibraries supplies the suffix
992 # You should only use this rule with libraries created through the
993 # @Library rule. For external libraries, use something else (XXX)
995 rule LinkLibraries {
996   # make library dependencies of target
997   # set NEEDLIBS variable used by 'actions Main'
998   local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1000   Depends $(_t) : $(>:S=$(SUFLIB)) ;
1001   NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ;
1005 # /LinkSharedLibraries image : libraries :
1007 # Same as @LinkLibraries, but to link _image_ with shared libraries
1008 # generated through the @SharedLibrary rule
1010 rule LinkSharedLibraries {
1011   # make library dependencies of target
1012   # set NEEDLIBS variable used by 'actions Main'
1013   local _t   = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1014   local _ext = $(SUFLIBSHR) ;
1016   if $(NT) {
1017     # on NT, we need to link agains the import library, not the DLL itself !!
1018     _ext = $(SUFLIBSHR)$(SUFLIB) ;
1019   }
1020   Depends $(_t) : $(>:S=$(_ext))  ;
1021   NEEDLIBS on $(_t) += $(>:S=$(_ext)) ;
1025 # /Main image : sources ;
1027 # Compiles _sources_ and links them into _image_. Calls @Objects and
1028 # @MainFromObjects.
1030 # _image_ may be supplied without suffix.
1032 rule Main {
1033   MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
1034   Objects $(>) ;
1038 # /C++Main image : sources ;
1040 # Compiles _sources_ and links them into _image_. Calls @Objects and
1041 # @C++MainFromObjects.
1043 # _image_ may be supplied without suffix.
1045 rule C++Main {
1046   C++MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
1047   Objects $(>) ;
1050 rule ObjC-Main {
1051   ObjC-MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;
1052   Objects $(>) ;
1056 # /MainFromObjects image : objects ;
1058 # Links _objects_ into _image_. Dependency of exe.
1059 # @MainFromObjects provides a default suffix for _image_
1061 rule MainFromObjects {
1062   local _s _t ;
1064   # Add grist to file names
1065   # Add suffix to exe
1066   _s = [ FGristFiles $(>) ] ;
1067   _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1068   # so 'jam foo' works when it's really foo.exe
1070   if $(_t) != $(<) {
1071     Depends $(<) : $(_t) ;
1072     NotFile $(<) ;
1073   }
1075   # make compiled sources a dependency of target
1076   Depends exe : $(_t) ;
1077   Depends $(_t) : $(_s) ;
1078   #k8:MakeLocate $(_t) : $(LOCATE_TARGET) ;
1079   MakeLocate $(_t) : $(LOCATE_BIN) ;
1080   Clean clean : $(_t) ;
1082   # special case for stupid Borland C++, which always generates a
1083   # .tds file for executables, even when no debug information is needed
1084   #
1085   #if $(JAM_TOOLSET) = BORLANDC {
1086   #  MakeLocate $(_t:S=.tds) : $(LOCATE_TARGET) ;
1087   #  Clean  clean : $(_t:S=.tds) ;
1088   #}
1090   Link $(_t) : $(_s) ;
1094 # /C++MainFromObjects image : objects ;
1096 # Links _objects_ into _image_. Dependency of exe.
1097 # @MainFromObjects provides a default suffix for _image_
1099 rule C++MainFromObjects {
1100   local _s _t ;
1102   # Add grist to file names
1103   # Add suffix to exe
1104   _s = [ FGristFiles $(>) ] ;
1105   _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1106   # so 'jam foo' works when it's really foo.exe
1108   if $(_t) != $(<) {
1109     Depends $(<) : $(_t) ;
1110     NotFile $(<) ;
1111   }
1113   # make compiled sources a dependency of target
1114   Depends exe : $(_t) ;
1115   Depends $(_t) : $(_s) ;
1116   #k8:MakeLocate $(_t) : $(LOCATE_TARGET) ;
1117   MakeLocate $(_t) : $(LOCATE_BIN) ;
1118   Clean clean : $(_t) ;
1120   # special case for stupid Borland C++, which always generates a
1121   # .tds file for executables, even when no debug information is needed
1122   #
1123   #if $(JAM_TOOLSET) = BORLANDC {
1124   #  MakeLocate $(_t:S=.tds) : $(LOCATE_TARGET) ;
1125   #  Clean  clean : $(_t:S=.tds) ;
1126   #}
1128   C++Link $(_t) : $(_s) ;  ###k8:FIXME
1132 rule ObjC-MainFromObjects {
1133   local _s _t ;
1135   # Add grist to file names
1136   # Add suffix to exe
1137   _s = [ FGristFiles $(>) ] ;
1138   _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
1139   # so 'jam foo' works when it's really foo.exe
1141   if $(_t) != $(<) {
1142     Depends $(<) : $(_t) ;
1143     NotFile $(<) ;
1144   }
1146   # make compiled sources a dependency of target
1147   Depends exe : $(_t) ;
1148   Depends $(_t) : $(_s) ;
1149   #k8:MakeLocate $(_t) : $(LOCATE_TARGET) ;
1150   MakeLocate $(_t) : $(LOCATE_BIN) ;
1151   Clean clean : $(_t) ;
1153   ObjC-Link $(_t) : $(_s) ;  ###k8:FIXME
1157 # /MakeLocate  targets : directory
1159 # Creates _dir_ and causes _target_ to be built into _dir_
1161 # This is done by setting the target-specific variable LOCATE
1162 # on _targets_, and arranges with @MkDir to create the target
1163 # directory
1165 rule MakeLocate {
1166   # Note we grist the directory name with 'dir',
1167   # so that directory path components and other
1168   # targets don't conflict.
1169   local srcname = $(<[1]:G=) ;
1170   local srcdir = $(srcname:D) ;
1171   local outdir = $(>[1]:G=dir) ;
1172   local odir ;
1173   if $(srcdir) {
1174     odir = $(outdir)$(PATH_SEPARATOR)$(srcdir) ;
1175   } else {
1176     odir = $(outdir) ;
1177   }
1178   #Echo "MakeLocate:" "$(<)" "|" "$(>)" ;
1179   #Echo "srcname:" "$(srcname)" ;
1180   #Echo "srcdir :" "$(srcdir)" ;
1181   #Echo "outdir :" "$(outdir)" ;
1182   #Echo "odir   :" "$(odir)" ;
1183   if $(>) {
1184     LOCATE on $(<) = $(>) ;
1185     Depends $(<) : $(odir) ;
1186     MkDir $(odir) ;
1187   }
1191 # /MkDir  dir ;
1193 # Creates _dir_ and its parent directories
1195 rule MkDir {
1196   # Ignore timestamps on directories: we only care if they exist.
1197   NoUpdate $(<) ;
1199   # Don't create . or any directory already created.
1200   if $(<:G=) != $(DOT) && ! $($(<)-mkdir) {
1201     # Cheesy gate to prevent multiple invocations on same dir
1202     # Arrange for jam dirs
1203     # MkDir1 has the actions
1204     $(<)-mkdir = true ;
1205     Depends dirs : $(<) ;
1206     MkDir1 $(<) ;
1208     # Recursively make parent directories.
1209     # $(<:P) = $(<)'s parent, & we recurse until root
1210     local s = $(<:P) ;
1212     # Don't try to create A: or A:\ on windows
1213     if $(NT) {
1214       switch $(s) {
1215         case "*:"   : s = ;
1216         case "*:\\" : s = ;
1217       }
1218     }
1219     # handle "C:", "C:/", "/cygdrive" and "/cygdrive/" in Cygwin
1220     if $(UNIX) && $(OS) = CYGWIN {
1221       switch $(s) {
1222         case "?:"   : s = ;
1223         case "?:/"  : s = ;
1224         case "<dir>/cygdrive"   : s = ;
1225         case "<dir>/cygdrive/"  : s = ;
1226       }
1227     }
1229     if $(s) = $(<) {
1230       # The parent is the same as the dir.
1231       # We're at the root, which some OS's can't stat, so we mark
1232       # it as NotFile.
1233       NotFile $(s) ;
1234     } else if $(s:G=) {
1235       # There's a parent; recurse.
1236       Depends $(<) : $(s) ;
1237       MkDir $(s) ;
1238     }
1239   }
1243 # /Object object : source ;
1245 # Compile s a single _source_ file into _object_. The @Main and @Library
1246 # rules use it to compile sources.
1248 # Causes _source_ to be scanned for #include directives and calls @HdrRule
1249 # to make all included files dependencies of _object_.
1251 # Calls one of the following rules depending on the suffix to do the
1252 # actual compilation:
1254 rule Object {
1255   # locate object and search for source, if wanted
1257   Clean clean : $(<) ;
1258   MakeLocate $(<) : $(LOCATE_TARGET) ;
1259   SEARCH on $(>) = $(SEARCH_SOURCE) ;
1261   # Save HDRS for -I$(HDRS) on compile.
1262   # We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers
1263   # in the .c file's directory, but generated .c files (from
1264   # yacc, lex, etc) are located in $(LOCATE_TARGET), possibly
1265   # different from $(SEARCH_SOURCE).
1266   HDRS on $(<) = $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ;
1268   # handle #includes for source: Jam scans for headers with
1269   # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
1270   # with the scanned file as the target and the found headers
1271   # as the sources.  HDRSEARCH is the value of SEARCH used for
1272   # the found header files.  Finally, if jam must deal with
1273   # header files of the same name in different directories,
1274   # they can be distinguished with HDRGRIST.
1276   # $(SEARCH_SOURCE:E) is where cc first looks for #include
1277   # "foo.h" files.  If the source file is in a distant directory,
1278   # look there.  Else, look in "" (the current directory).
1280   HDRRULE on $(>) = HdrRule ;
1281   HDRSCAN on $(>) = $(HDRPATTERN) ;
1282   HDRSEARCH on $(>) = $(SEARCH_SOURCE:E) $(SUBDIRHDRS) $(HDRS) $(STDHDRS) ;
1283   HDRGRIST on $(>) = $(HDRGRIST) ;
1285   # propagate target specific-defines
1286   DEFINES on $(<) += $(DEFINES) ;
1288   if $(WINDOZE) && $(>:S) = ".rc" {
1289     WindozeResourceCompiler $(<) : $(>) ;
1290   } else if $(WINDOZE) && $(>:S) = ".o" {
1291     # do nothing
1292   } else {
1293     # if source is not .c, generate .c with specific rule
1294     switch $(>:S) {
1295       case .asm : As $(<) : $(>) ;
1296       case .c   : Cc $(<) : $(>) ;
1297       case .C   : C++ $(<) : $(>) ;
1298       case .cc  : C++ $(<) : $(>) ;
1299       case .cpp : C++ $(<) : $(>) ;
1300       case .cxx : C++ $(<) : $(>) ;
1301       case .c++ : C++ $(<) : $(>) ;
1302       case .C++ : C++ $(<) : $(>) ;
1303       case .m   : ObjC $(<) : $(>) ;
1304       case .d   : Dc $(<) : $(>) ;
1305       case .l   : Cc $(<) : $(<:S=.c) ;
1306                   Lex $(<:S=.c) : $(>) ;
1307       case .s   : As $(<) : $(>) ;
1308       case .y   : Cc $(<) : $(<:S=$(YACCGEN)) ;
1309                   Yacc $(<:S=$(YACCGEN)) : $(>) ;
1310       case *    : UserObject $(<) : $(>) ;
1311     }
1312   }
1316 # /ObjectCcFlags  sources : flags ;
1318 # this rule is used to add compiler flags to the compilation of
1319 # specific C sources files.
1321 rule ObjectCcFlags {
1322   CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1326 # /ObjectC++Flags  sources : flags ;
1328 # this rule is used to add compiler flags to the compilation of
1329 # specific C++ source files
1331 rule ObjectC++Flags {
1332   C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1336 rule ObjectObjCFlags {
1337   OBJCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;
1341 # /LinkFlagsOn  mains : flags ;
1343 # this rule is used to add compiler flags to the compilation of
1344 # specific C sources files.
1346 rule LinkFlagsOn {
1347   LINKFLAGS on [ FGristFiles $(<) ] += $(>) ;
1351 # /C++LinkFlagsOn  mains : flags ;
1353 # this rule is used to add compiler flags to the compilation of
1354 # specific C++ source files
1356 rule C++LinkFlagsOn {
1357   C++LINKFLAGS on [ FGristFiles $(<) ] += $(>) ;
1361 rule ObjCLinkFlagsOn {
1362   OBJCLINKFLAGS on [ FGristFiles $(<) ] += $(>) ;
1366 # /ObjectDefines  objects : macros ;
1368 # this rule is used to add macro defines to the compilation of
1369 # specific C and C++ source files
1371 rule ObjectDefines {
1372   # must reformat CCDEFS according to current defines
1373   local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;
1375   DEFINES on $(s) += $(>) ;
1376   CCDEFS on $(s) = [ on $(s) FDefines $(DEFINES) ] ;
1380 # /ObjectHdrs  sources : paths ;
1382 # this rule is used to add include paths to the compilation of
1383 # specific C and C++ source files
1385 rule ObjectHdrs {
1386   # Add to HDRS for HdrScan's benefit.
1387   # must reformat CCHDRS according to headers
1388   local s = [ FGristFiles $(<:S=$(SUFOBJ)) ] ;
1390   HDRS on $(s) += $(>) ;
1391   CCHDRS on $(s) = [ on $(s) FIncludes $(HDRS) ] ;
1395 # /Objects sources ;
1397 # this rule is used to compile one or more sources into object files.
1398 # do not call it directly, it is used by the Main and Library rules
1399 # automatically
1401 rule Objects {
1402   local _i ;
1404   for _i in [ FGristFiles $(<) ] {
1405     Object $(_i:S=$(SUFOBJ)) : $(_i) ;
1406     Depends obj : $(_i:S=$(SUFOBJ)) ;
1407   }
1411 # /SharedObjects
1413 # this rule is used to compile one or more sources into 'shared object
1414 # files'. This means object files used to build either DLLs or Unix shared
1415 # libraries.
1417 # do not call this rule directly, it is called by SharedLibrary automatically
1419 rule SharedObjects {
1420   # temporarily override SUFOBJ with $(SUFOBJSHR) to
1421   local SUFOBJ = $(SUFOBJSHR) ;
1423   # call the normal Objects rule
1424   Objects $(<) ;
1426   # add the compiler-specific position-independent-code flag  where needed
1427   ObjectCcFlags $(<) : $(PICFLAGS) ;
1429   # change the compiler invokation for all these objects
1430   # to use Libtool on Unix systems. We explicitely disable the
1431   # generation of static objects here
1432 #!LIBTOOL!#  if $(UNIX) {
1433 #!LIBTOOL!#    #libtool on $(<:S=$(SUFOBJ)) = [ LibToolFind ] ;
1434 #!LIBTOOL!#    if $(K8_USE_LIBTOOL) {
1435 #!LIBTOOL!#      local libtool = [ LibToolFind ] ;
1436 #!LIBTOOL!#      CC on $(<:S=$(SUFOBJ)) = "$(libtool) --mode=compile $(CC:J= ) -dynamic" ;
1437 #!LIBTOOL!#      C++ on $(<:S=$(SUFOBJ)) = "$(libtool) --mode=compile $(C++:J= ) -dynamic" ; #k8:?
1438 #!LIBTOOL!#    }
1439 #!LIBTOOL!#  }
1443 rule RmTemps {
1444   Temporary $(>) ;
1448 rule Setuid {
1449   MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ;
1453 rule Shell {
1454   Depends shell : $(<) ;
1455   Depends $(<) : $(>) ;
1456   SEARCH on $(>) = $(SEARCH_SOURCE) ;
1457   MODE on $(<) = $(SHELLMODE) ;
1458   Clean clean : $(<) ;
1459   Chmod $(<) ;
1463 rule SoftLink {
1464   Depends files : $(<) ;
1465   Depends $(<) : $(>) ;
1466   SEARCH on $(>) = $(SEARCH_SOURCE) ;
1467   Clean clean : $(<) ;
1471 rule SubDir {
1472   #
1473   # SubDir TOP d1 d2 ... ;
1474   #
1475   # Support for a project tree spanning multiple directories.
1476   #
1477   # SubDir declares a Jamfile's location in a project tree, setting
1478   # Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source
1479   # files can be found.
1480   #
1481   # TOP is a user-select variable name for root of the tree, and
1482   # d1 d2 ...  are the directory elements that lead from the root
1483   # of the tree to the directory of the Jamfile.
1484   #
1485   # TOP can be set externally, but normally the first SubDir call
1486   # computes TOP as the path up from the current directory; the
1487   # path contains one ../ for each of d1 d2 ...
1488   #
1489   # SubDir reads once the project-specific rules file Jamrules
1490   # in the TOP directory, if present.  This can be overridden
1491   # with the variable TOPRULES.
1492   #
1493   # SubDir supports multiple, overlaid project trees:  SubDir
1494   # invocations with different TOPs can appear in the same Jamfile.
1495   # The location established by the first SubDir call is used set
1496   # the TOPs for the subsequent SubDir calls.
1497   #
1498   # SubDir's public variables:
1499   #
1500   #   $(TOP) = path from CWD to root.
1501   #   $(SUBDIR) = path from CWD to the directory SubDir names.
1502   #   $(SUBDIR_TOKENS) = path from $(TOP) to $(SUBDIR) as dir names
1503   #   $(SEARCH_SOURCE) = $(SUBDIR)
1504   #   $(LOCATE_SOURCE) = $(ALL_LOCATE_TARGET) $(SUBDIR)
1505   #   $(LOCATE_TARGET) = $(ALL_LOCATE_TARGET) $(SUBDIR)
1506   #   $(LOCATE_BIN) = $(ALL_LOCATE_BIN) $(ALL_LOCATE_TARGET) $(SUBDIR)
1507   #   $(LOCATE_LIB) = $(ALL_LOCATE_LIB) $(ALL_LOCATE_TARGET) $(SUBDIR)
1508   #   $(LOCATE_LIBSO) = $(ALL_LOCATE_LIBSO) $(ALL_LOCATE_LIB) $(ALL_LOCATE_TARGET) $(SUBDIR)
1509   #   $(SOURCE_GRIST) = $(SUBDIR_TOKENS) with !'s
1510   #
1511   local _top = $(<[1]) ;
1512   local _tokens = $(<[2-]) ;
1514   local ktmp ;
1516   # First time through sets up relative root and includes Jamrules.
1517   if ! $(_top) { Exit "SubDir syntax error" ; }
1519   if ! $($(_top)-SET) {
1520     $(_top)-SET = true ;
1521     # First time we've seen this TOP.
1522     # We'll initialize a number of internal variables:
1523     #
1524     #   $(TOP-UP) = directories from ROOT to a common point
1525     #   $(TOP-DOWN) = directories from common point to TOP
1526     #   $(TOP-ROOT) = root directory for UP/DOWN -- normally CWD
1527     #   $(SUBDIR_UP) = current value of $(TOP-UP)
1528     #   $(SUBDIR_DOWN) = current value of $(TOP-DOWN)
1529     #   $(SUBDIR_ROOT) = current value of $(TOP-ROOT)
1530     #
1531     if $($(_top)) {
1532       # TOP externally set.
1533       # We'll ignore the relative (UP/DOWN) path that
1534       # got us here, and instead remember the hard ROOT.
1535       $(_top)-UP = ;
1536       $(_top)-DOWN = ;
1537       $(_top)-ROOT = $($(_top)) ;
1538     } else {
1539       # TOP not preset.
1541       # Establishing a new TOP.  In the simplest case,
1542       # (SUBDIR_UP/SUBDIR_DOWN/SUBDIR_ROOT unset), it's
1543       # merely a certain number of directories down from
1544       # the current directory, and FSubDirPath will set
1545       # TOP to a path consisting of ../ for each of the
1546       # elements of _tokens, because that represents how
1547       # far below TOP the current directory sits.
1548       #
1549       # In the more complicated case, the starting directory
1550       # isn't the directory of jam's invocation but an
1551       # location established by previous SubDir call.  The
1552       # starting directory is SUBDIR_UP directories up from
1553       # SUBDIR_ROOT, and then SUBDIR_DOWN directories down
1554       # from that.   If SUBDIR_ROOT is not set, that means
1555       # SUBDIR_DOWN and SUBDIR_UP represent the path from
1556       # the directory of jam's invocation.
1557       #
1558       # In the most complicated case, the _tokens also
1559       # represents directories down, because TOP is being
1560       # estalished in a directory other than TOP's root.
1561       # Hopefully, _tokens and SUBDIR_DOWN represent the
1562       # same final directory, relative to the new TOP and
1563       # the previous SubDIr's TOP.  To find the new TOP,
1564       # we have to chop off any common directories from
1565       # then ends of _tokens and SUBDIR_DOWN.  To do so,
1566       # we reverse each of them, call FStripCommon to
1567       # remove the initial common elements, and then
1568       # reverse them again.  After this process, if
1569       # both _tokens and SUBDIR_DOWN have elements, it
1570       # means the directory names estalished by the two
1571       # SubDir calls don't match, and a warning is issued.
1572       # All hell will likely break loose at this point,
1573       # since the whole SubDir scheme relies on the SubDir
1574       # calls accurately naming the current directory.
1576       # Strip common trailing elements of _tokens and SUBDIR_DOWN.
1577       _tokens = [ FReverse $(_tokens) ] ;
1578       SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
1579       FStripCommon _tokens : SUBDIR_DOWN ;
1580       SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
1581       _tokens = [ FReverse $(_tokens) ] ;
1583       if $(SUBDIR_DOWN) && $(_tokens) { Echo "Warning:" SubDir $(<) "misplaced!" ; }
1585       # We'll remember the relative (UP/DOWN) path that
1586       # got us here, plus any hard ROOT starting point
1587       # for the UP/DOWN.  If TOP is never set externally,
1588       # ROOT will always be "" (directory of jam's invocation).
1589       $(_top)-UP = $(SUBDIR_UP) $(_tokens) ;
1590       $(_top)-DOWN = $(SUBDIR_DOWN) ;
1591       $(_top)-ROOT = $(SUBDIR_ROOT:E="") ;
1592       $(_top) = [ FSubDirPath $(_top) ] ;
1593     }
1595     # Set subdir vars for the inclusion of the Jamrules,
1596     # just in case they have SubDir rules of their own.
1597     # Note that SUBDIR_DOWN is empty: it's all the way
1598     # up where the Jamrules live.  These gets overrided
1599     # just after the inclusion.
1600     SUBDIR_UP = $($(_top)-UP) ;
1601     SUBDIR_DOWN = ;
1602     SUBDIR_ROOT = $($(_top)-ROOT) ;
1604     # Include $(TOPRULES) or $(TOP)/Jamrules.
1605     # Include $(TOPRULES) if set.
1606     # Otherwise include $(TOP)/Jamrules if present.
1607     if $($(_top)RULES) {
1608       include $($(_top)RULES) ;
1609     } else {
1610       NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ;
1611       include $(JAMRULES:R=$($(_top)):G=$(_top)) ;
1612     }
1613   }
1615   # Get path from $(TOP) to named directory.
1616   # Save dir tokens for other potential uses.
1617   SUBDIR_UP = $($(_top)-UP) ;
1618   SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ;
1619   SUBDIR_ROOT = $($(_top)-ROOT) ;
1620   SUBDIR_TOKENS = $(SUBDIR_DOWN) ;
1622   SUBDIR = [ FSubDirPath $(<) ] ;
1624   # Now set up SEARCH_SOURCE, LOCATE_TARGET, LOCATE_BIN, SOURCE_GRIST
1625   # These can be reset if needed.  For example, if the source
1626   # directory should not hold object files, LOCATE_TARGET can
1627   # subsequently be redefined.
1628   SEARCH_SOURCE = $(SUBDIR) ;
1629   LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
1630   LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
1632   ktmp = $(ALL_LOCATE_BIN) ;
1633   if ! $(ktmp) { ktmp = $(ALL_LOCATE_TARGET) ; }
1634   LOCATE_BIN = $(ktmp) $(SUBDIR) ;
1636   ktmp = $(ALL_LOCATE_LIB) ;
1637   if ! $(ktmp) { ktmp = $(ALL_LOCATE_TARGET) ; }
1638   LOCATE_LIB = $(ktmp) $(SUBDIR) ;
1640   ktmp = $(ALL_LOCATE_LIBSO) ;
1641   if ! $(ktmp) { ktmp = $(ALL_LOCATE_LIB) ; }
1642   if ! $(ktmp) { ktmp = $(ALL_LOCATE_TARGET) ; }
1643   LOCATE_LIBSO = $(ktmp) $(SUBDIR) ;
1645   SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ;
1646   #if ! $(LOCATE_BIN) { LOCATE_BIN = $(LOCATE_TARGET) ; }
1648   ## OPT_HEADER_CACHE_EXT
1649   # With the header cache, we can grist all files found
1650   # during a header scan without incurring a performance
1651   # penalty.
1652   #
1653   HDRGRIST = $(SOURCE_GRIST) ;
1655   # Reset per-directory ccflags, hdrs, etc,
1656   # listed in SUBDIRRESET.
1657   # Note use of variable expanded assignment var
1658   SUBDIR$(SUBDIRRESET) = ;
1660   # Invoke user-specific SubDir extensions,
1661   # rule names listed in SUBDIRRULES.
1662   # Note use of variable expanded rule invocation
1663   $(SUBDIRRULES) $(<) ;
1667 rule FSubDirPath {
1668   # FSubDirPath TOP d1 ... ;
1670   # Returns path to named directory.
1672   # If jam is invoked in a subdirectory of the TOP, then we
1673   # need to prepend a ../ for every level we must climb up
1674   # (TOP-UP), and then append the directory names we must
1675   # climb down (TOP-DOWN), plus the named directories d1 ...
1676   # If TOP was set externally, or computed from another TOP
1677   # that was, we'll have to reroot the whole thing at TOP-ROOT.
1678   local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ;
1680   return $(_r:R=$($(<[1])-ROOT)) ;
1684 rule SubDirDcFlags {
1685   SUBDIRDCFLAGS += $(<) ;
1689 rule SubDirCcFlags {
1690   SUBDIRCCFLAGS += $(<) ;
1694 rule SubDirC++Flags {
1695   SUBDIRC++FLAGS += $(<) ;
1699 rule SubDirObjCFlags {
1700   SUBDIROBJCFLAGS += $(<) ;
1704 rule SubDirHdrs {
1705   SUBDIRHDRS += [ FDirName $(<) ] ;
1709 rule SubIncludeMany {
1710   # SubIncludeMany TOP d1 ... ;
1711   #
1712   # Include a subdirectory's Jamfile.
1714   # We use SubDir to get there, in case the included Jamfile
1715   # either doesn't have its own SubDir (naughty) or is a subtree
1716   # with its own TOP.
1717   #Echo "including " $(<) " : " $(>) ;
1719   if ! $($(<[1])) { Exit "SubIncludeMany" $(<[1]) "without prior SubDir" $(<[1]) ; }
1720   SubDir $(<) ;
1721   include $(JAMFILE:D=$(SUBDIR)) ;
1725 rule SubIncludeOnce {
1726   # SubIncludeOnce varname : TOP d1 ... ;
1727   #
1728   # Include a subdirectory's Jamfile.
1730   local _vn = $(<[1]) ;
1731   if ! $($(_vn)) {
1732     #Echo "processing $(_vn)" ;
1733     #Echo "$(>)" ;
1734     $(_vn) = tan ;
1735     SubIncludeMany $(>) ;
1736   #} else {
1737   #  Echo "skiped $(_vn) -- $($(_vn))" ;
1738   #  Echo "$(>)" ;
1739   }
1743 rule SubInclude {
1744   # SubInclude TOP d1 ... ;
1745   #
1746   # Include a subdirectory's Jamfile.
1747   if ! $($(<[1])) { Exit "SubInclude" $(<[1]) "without prior SubDir" $(<[1]) ; }
1748   local _sbiguard = _K8JAM_SUB_GUARD_$(<:J=_) ;
1749   SubIncludeOnce $(_sbiguard) : $(<) ;
1753 rule SubRules {
1754   # SubRules TOP d1 ... : Other-TOP ;
1755   #
1756   # Read another tree's Jamrules, by giving it's path according
1757   # to this tree and it's own name.
1758   if ! $($(<[1])) { Exit "SubRules" $(<[1]) "without prior SubDir" $(<[1]) ; }
1759   SubDir $(<) ;
1760   SubDir $(>) ;
1764 rule Undefines {
1765   UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ;
1769 rule UserObject {
1770   Exit "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ;
1774 rule Yacc {
1775   local _h ;
1777   _h = $(<:BS=.h) ;
1779   # Some places don't have a yacc.
1780   MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;
1781   #MakeLocate $(>) $(_h) : $(LOCATE_SOURCE) ;
1783   if $(YACC) {
1784     #local tmp ;
1785     #tmp = $(<:G=:D) ;
1786     #if $(tmp) { tmp = $(PATH_SEPARATOR)$(tmp) ; }
1787     #tmp = $(LOCATE_SOURCE[1])$(tmp) ;
1788     #CCFLAGS on $(<:S=$(SUFOBJ)) += -I$(tmp) ;
1789     #C++FLAGS on $(<:S=$(SUFOBJ)) += -I$(tmp) ;
1790     #OBJCFLAGS on $(<:S=$(SUFOBJ)) += -I$(tmp) ;
1791     #Echo "-------------------------" ;
1792     #Echo "LS:" "$(LOCATE_SOURCE)" ;
1793     #Echo "tmp:" "$(tmp)" ;
1794     #Echo "out:" "$(<)" ;
1795     #Echo "in :" "$(>)" ;
1796     #Echo "_h :" "$(_h)" ;
1797     #Echo "=========================" ;
1798     #
1799     Depends $(<) $(_h) : $(>) ;
1800     Yacc1 $(<) : $(>) ;
1801     #Yacc1 $(<) $(_h) : $(>) ;
1802     #YaccMv $(<) $(_h) : $(>) ;
1803     Clean clean : $(<) $(_h) ;
1804   }
1806   # make sure someone includes $(_h) else it will be
1807   # a deadly independent target
1808   Includes $(<) : $(_h) ;
1813 # Utility rules; no side effects on these
1817 # /FGrist path to file ;
1819 # Returns a single string that is used as grist
1821 rule FGrist {
1822   return $(<:J=!) ;
1826 rule FGristFiles {
1827   return $(<:G=$(SOURCE_GRIST:E)) ;
1831 rule FGristSourceFiles {
1832   ## LOCAL CHANGE: OPT_HEADER_CACHE_EXT
1833   # With header caching, there is no performance penalty to gristing
1834   # header files. It is also not correct to assume that header
1835   # files have global visibility.
1836   #
1837   # Here we comment out the old version and replace it with the new.
1838 #  # Produce source file name name with grist in it,
1839 #  # if SOURCE_GRIST is set.
1841 #  # Leave header files alone, because they have a global
1842 #  # visibility.
1843 #  if ! $(SOURCE_GRIST) {
1844 #    return $(<) ;
1845 #  } else {
1846 #    local _i _o ;
1848 #    for _i in $(<) {
1849 #      switch $(_i) {
1850 #        case *.h : _o += $(_i) ;
1851 #        case *   : _o += $(_i:G=$(SOURCE_GRIST)) ;
1852 #      }
1853 #    }
1854 #    return $(_o) ;
1855 #  }
1856   return [ FGristFiles $(<) ] ;
1860 rule FReverse {
1861   if $(1) { return [ FReverse $(1[2-]) ] $(1[1]) ; }
1865 rule FSubDir {
1866   # If $(>) is the path to the current directory, compute the
1867   # path (using ../../ etc) back to that root directory.
1868   # Sets result in $(<)
1869   if ! $(<[1]) {
1870     return $(DOT) ;
1871   } else {
1872     local _i _d ;
1874     _d = $(DOTDOT) ;
1875     for _i in $(<[2-]) { _d = $(_d:R=$(DOTDOT)) ; }
1876     return $(_d) ;
1877   }
1881 rule FStripCommon {
1882   # FStripCommon v1 : v2 ;
1884   # Strip common initial elements of variables v1 and v2.
1885   # Modifies the variable values themselves.
1886   if $($(<)[1]) && $($(<)[1]) = $($(>)[1]) {
1887     $(<) = $($(<)[2-]) ;
1888     $(>) = $($(>)[2-]) ;
1889     FStripCommon $(<) : $(>) ;
1890   }
1894 rule FRelPath {
1895   local _l _r ;
1897   # first strip off common parts
1898   _l = $(<) ;
1899   _r = $(>) ;
1900   FStripCommon _l : _r ;
1902   # now make path to root and path down
1903   _l = [ FSubDir $(_l) ] ;
1904   _r = [ FDirName $(_r) ] ;
1906   # Concatenate and save
1907   # XXX This should be better
1908   if $(_r) = $(DOT) { return $(_l) ; } else { return $(_r:R=$(_l)) ; }
1912 rule FAppendSuffix {
1913   # E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;"
1914   # returns (yacc,lex,foo.bat) on Unix and
1915   # (yacc.exe,lex.exe,foo.bat) on NT.
1916   if $(>) {
1917     local _i _o ;
1919     for _i in $(<) {
1920       if $(_i:S) { _o += $(_i) ; } else { _o += $(_i:S=$(>)) ; }
1921     }
1922     return $(_o) ;
1923   } else {
1924     return $(<) ;
1925   }
1930 # Operating system specific utility rules
1931 # First, the (generic) UNIX versions
1934 rule FQuote { return "\\\"$(<)\\\"" ; }
1935 rule FDefines { return -D$(<) ; }
1936 rule FIncludes { return -I$(<) ; }
1938 rule FDirName {
1939   # Turn individual elements in $(<) into a usable path.
1940   local _i ;
1941   local _s = $(DOT) ;
1943   for _i in $(<) { _s = $(_i:R=$(_s)) ; }
1944   return $(_s) ;
1948 if $(NT) && $(JAM_TOOLSET) != MINGW && $(JAM_TOOLSET) != LCC {
1949   rule FDefines { return /D$(<) ; }
1950   rule FIncludes { return /I$(<) ; }
1955 # various install rules
1958 rule InstallInto {
1959   # InstallInto dir : sources ;
1961   local i t ;
1963   t = $(>:G=$(INSTALLGRIST)) ;
1965   # Arrange for jam install
1966   # Arrange for jam uninstall
1967   # sources are in SEARCH_SOURCE
1968   # targets are in dir
1970   Depends install : $(t) ;
1971   Clean uninstall : $(t) ;
1972   SEARCH on $(>) = $(SEARCH_SOURCE) ;
1973   MakeLocate $(t) : $(<) ;
1975   # For each source, make gristed target name
1976   # and Install, Chmod, Chown, and Chgrp
1977   for i in $(>) {
1978     local tt = $(i:G=$(INSTALLGRIST)) ;
1980     Depends $(tt) : $(i) ;
1981     Install $(tt) : $(i) ;
1982     Chmod $(tt) ;
1984     if $(OWNER) && $(CHOWN) {
1985       Chown $(tt) ;
1986       OWNER on $(tt) = $(OWNER) ;
1987     }
1988     if $(GROUP) && $(CHGRP) {
1989       Chgrp $(tt) ;
1990       GROUP on $(tt) = $(GROUP) ;
1991     }
1992   }
1996 # /InstallBin dir : sources ;
1998 # Copy _sources_ into _dir_ with mode $(EXEMODE)
2000 rule InstallBin {
2001   local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;
2003   InstallInto $(<) : $(_t) ;
2004   MODE on $(_t:G=$(INSTALLGRIST)) = $(EXEMODE) ;
2008 # /InstallFile dir : sources ;
2010 # Copy _sources_ into _dir_ with mode $(FILEMODE)
2012 rule InstallFile {
2013   InstallInto $(<) : $(>) ;
2014   MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
2018 # /InstallLib dir : sources ;
2020 # Copy _sources_ into _dir_ with mode $(FILEMODE)
2022 rule InstallLib {
2023   InstallInto $(<) : $(>) ;
2024   MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
2028 # /InstallMan dir : sources ;
2030 #  Copy _sources_ into the appropriate subdirectory of _dir_ with mode
2031 #  $(FILEMODE). The subdirectory is manS, where S is the suffix of each of
2032 #  sources.
2034 rule InstallMan {
2035   # Really this just strips the . from the suffix
2036   local i s d ;
2038   for i in $(>) {
2039     switch $(i:S) {
2040       case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;
2041       case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;
2042       case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;
2043       case .n : s = n ; case .man : s = 1 ;
2044     }
2045     d = man$(s) ;
2046     InstallInto $(d:R=$(<)) : $(i) ;
2047   }
2048   MODE on $(>:G=$(INSTALLGRIST)) = $(FILEMODE) ;
2052 # /InstallShell dir : sources ;
2054 # Copy _sources_ into _dir_ with mode $(SHELLMODE)
2056 rule InstallShell {
2057   InstallInto $(<) : $(>) ;
2058   MODE on $(>:G=$(INSTALLGRIST)) = $(SHELLMODE) ;
2062 rule WindozeResourceCompiler {
2063   DEPENDS $(<) : $(>) ;
2064   Clean clean : $(<) ;
2067 rule windoze-fix {
2068   if $(WINDOZE) {
2069     if $(WINDOZE_THREADS) {
2070       CC += -mthreads ;
2071       CC++ += -mthreads ;
2072     }
2073     local ss = $(WINSUBSYS) ;
2074     if ! $(ss) { ss = "console" ; }
2075     LINK += "-Wl,-subsystem,$(ss)" ;
2076     C++LINK += "-Wl,-subsystem,$(ss)" ;
2077     if $(WINLIBS) { LINKLIBS += $(WINLIBS) ; } else { LINKLIBS += -lkernel32 ; }
2078   }
2083 # Actions
2085 actions WindozeResourceCompiler {
2086   "$(WINE)" $(MGPATH)windres.exe -i $(>) -o $(<)
2090 # First the defaults
2092 actions updated together piecemeal Archive {
2093   $(AR) $(<) $(>)
2097 actions As {
2098   $(AS) $(ASFLAGS) $(ASHDRS) -o $(<) $(>)
2102 actions Cc {
2103   $(CC) -c -o $(<) $(CFLAGS.all) $(CCFLAGS) $(OPTIM.all) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2107 actions C++ {
2108   $(C++) -c -o $(<) $(CFLAGS.all) $(C++FLAGS) $(OPTIM.all) $(C++OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2112 actions ObjC {
2113   $(OBJCC) -c -o $(<) $(CFLAGS.all) $(OBJCFLAGS) $(OPTIM.all) $(OBJCOPTIM) $(CCDEFS) $(CCHDRS) $(>)
2117 actions Dc {
2118   $(DC) -c -of$(<) $(DCFLAGS) $(DOPTIM) $(>)
2122 actions Chgrp {
2123   $(CHGRP) $(GROUP) $(<)
2127 actions Chmod1 {
2128   $(CHMOD) $(MODE) $(<)
2132 actions Chown {
2133   $(CHOWN) $(OWNER) $(<)
2137 actions piecemeal together existing Clean {
2138   $(RM) $(>)
2142 actions File {
2143   $(CP) $(>) $(<)
2147 actions GenFile1 {
2148   $(>[1]) $(<) $(>[2-])
2152 actions HardLink {
2153   $(RM) $(<) && $(LN) $(>) $(<)
2157 actions Install {
2158   $(CP) $(>) $(<)
2162 actions Lex {
2163   $(LEX) -o $(<) $(>)
2167 ##actions LexMv {
2168 ##  $(MV) lex.yy.c $(<)
2172 actions Link bind NEEDLIBS {
2173   $(LINK) $(LINKFLAGS.all) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS.all) $(LINKLIBS)
2176 actions C++Link bind NEEDLIBS {
2177   $(C++LINK) $(LINKFLAGS.all) $(C++LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS.all) $(C++LINKLIBS)
2180 actions ObjC-Link bind NEEDLIBS {
2181   $(OBJCLINK) $(LINKFLAGS.all) $(OBJCLINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS.all) $(OBJCLINKLIBS)
2185 actions updated together piecemeal LinkUnixLibrary bind NEEDLIBS {
2186   $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2189 actions updated together piecemeal C++LinkUnixLibrary bind NEEDLIBS {
2190   $(C++LINK) $(C++LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(C++LINKLIBS)
2194 actions MkDir1 {
2195   $(MKDIR) $(<)
2199 actions together Ranlib {
2200   $(RANLIB) $(<)
2204 actions quietly updated piecemeal together RmTemps {
2205   $(RM) $(>)
2209 actions Shell {
2210 #DONT_TOUCH
2211   $(AWK) '
2212     NR == 1 { print "$(SHELLHEADER)" }
2213     NR == 1 && /^[#:]/ { next }
2214     /^##/ { next }
2215     { print }
2216   ' < $(>) > $(<)
2217 #DONT_TOUCH
2221 actions SoftLink {
2222   $(RM) $(<) && $(LN) -s $(>) $(<)
2226 actions Yacc1 {
2227   $(YACC) $(YACCFLAGS) $(>) -o $(<)
2231 actions YaccMv {
2232   #$(MV) $(YACCFILES).c $(<[1])
2233   #$(MV) $(YACCFILES).h $(<[2])
2238 # RELOCATE - for compilers with broken -o flags
2240 if $(RELOCATE) {
2241   actions C++ {
2242     $(C++) -c $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2243   }
2244   actions Cc {
2245     $(CC) -c $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) $(>)
2246   }
2247   actions ignore CcMv {
2248     [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)
2249   }
2254 # NOARUPDATE - can't update an archive
2256 if $(NOARUPDATE) {
2257   actions Archive {
2258     $(AR) $(<) $(>)
2259   }
2264 # UNIX specific actions
2266 if $(UNIX) {
2267   actions GenFile1 {
2268     PATH="$PATH:."
2269     $(>[1]) $(<) $(>[2-])
2270   }
2275 # NT specific actions
2277 if $(NT) {
2278   if $(JAM_TOOLSET) = MINGW {
2279     actions together piecemeal Archive {
2280       $(AR) $(<) $(>:T)
2281     }
2282     actions Cc {
2283       $(CC) -c -o $(<) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>)
2284     }
2285     actions C++ {
2286       $(C++) -c -o $(<) $(C++FLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -I$(STDHDRS) $(>)
2287     }
2288     actions DllLink bind DEFFILENAME IMPLIBNAME {
2289       $(LINK) $(LINKFLAGS) -shared -o $(<) $(>) $(DEFFILENAME) -Wl,--out-implib,$(IMPLIBNAME)
2290     }
2291   } else if $(JAM_TOOLSET) = LCC {
2292     actions together piecemeal Archive {
2293       $(AR) /out:$(<) $(>)
2294     }
2295     actions Cc {
2296       $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS) -Fo$(<) -I$(STDHDRS) $(>)
2297     }
2298     actions Link bind NEEDLIBS {
2299       $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)
2300     }
2301     actions DllLink bind NEEDLIBS DEFFILENAME {
2302       $(LINK) $(LINKFLAGS) -DLL -o $(<) $(UNDEFS) $(>) $(DEFFILENAME) $(NEEDLIBS) $(LINKLIBS)
2303     }
2304     actions ignore DllLinkMv {
2305       $(MV) $(2) $(1)
2306     }
2307     actions Shell {
2308       $(CP) $(>) $(<)
2309     }
2310   } else if $(JAM_TOOLSET) = PELLESC {
2311     actions together piecemeal Archive {
2312       $(AR) /OUT:$(<) $(>)
2313     }
2314     actions Cc {
2315       $(CC) $(CCFLAGS) $(OPTIM) $(CCDEFS) $(CCHDRS)   /Fo $(<) -I$(STDHDRS)  $(>)
2316     }
2317     actions Link bind NEEDLIBS {
2318       $(LINK) $(LINKFLAGS) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS)
2319     }
2320     actions DllLink bind NEEDLIBS DEFFILENAME IMPLIBNAME {
2321       $(LINK) $(LINKFLAGS) /DLL /DEF:$(DEFFILENAME) /IMPLIB:$(IMPLIBNAME) /OUT:$(<) $(>) $(NEEDLIBS) $(LINKLIBS)
2322     }
2323     actions Shell {
2324       $(CP) $(>) $(<)
2325     }
2326   }
2331 # Ketmar's additions
2333 rule SetCPUFlags {
2334   if $(OS) != "LINUX" {
2335     DETECTED_CPU = "i486" ;
2336     OPTIM_SPEED = -O3 -march=i486 -mtune=i486 ;
2337   } else {
2338     DETECTED_CPU = native ;
2339     OPTIM_SPEED = -O3 -march=native -mtune=native ;
2340   }
2344 # VAR = [ RemoveOptWild regexp-options-to-remove : options-list ] ;
2345 # remove options from list with egrep-like regexps
2346 rule RemoveOptWild {
2347   local oname = $(1) ;
2348   local str = $(2) ;
2349   local res = ;
2350   local f ;
2351   local t ;
2352   #Echo "removing " $(oname) " from " $(str) ;
2353   for f in $(str) {
2354     t = [ Match $(oname) : $(f) ] ;
2355     #Echo $(f) ": " $(t) ;
2356     if $(t[1]) = "" {
2357       #Echo "include: " $(f) ;
2358       res += $(f) ;
2359     }
2360   }
2361   return $(res) ;
2365 # profile rules
2366 K8JAM-KNOWN-PROFILES =
2367   none default  # don't change
2368   empty         # remove optimisation flags
2369   speed         # optimise for speed
2370   size          # optimise for size
2371   debug         # don't optimize, add debug info
2372   standard      # -O2
2376 rule --k8jam-profile-none {
2377   Echo "MSG: default profile" ;
2378   OPT_PROFILE = ;
2381 rule --k8jam-profile-empty {
2382   Echo "MSG: default profile" ;
2385 rule --k8jam-profile-empty-- {
2386   Echo "MSG: empty profile" ;
2387   SLACK_PKG_ARCH = "i486" ;
2388   LINKFLAGS.all += -s ;
2391 rule --k8jam-profile-speed-- {
2392   Echo "MSG: 'speed' profile" ;
2393   SLACK_PKG_ARCH = "i686" ;
2394   CFLAGS.all += $(OPTIM_SPEED) ;
2395   LINKFLAGS.all += $(LINKFLAGS_SPEED) ;
2398 rule --k8jam-profile-size-- {
2399   Echo "MSG: 'size' profile" ;
2400   SLACK_PKG_ARCH = "i686" ;
2401   CFLAGS.all += $(OPTIM_SIZE) ;
2402   LINKFLAGS.all += $(LINKFLAGS_SIZE) ;
2405 rule --k8jam-profile-debug-- {
2406   Echo "MSG: 'debug' profile" ;
2407   SLACK_PKG_ARCH = "i486" ;
2408   LINKFLAGS.all -= -s ;
2409   CFLAGS.all += $(OPTIM_DEBUG) ;
2410   LINKFLAGS.all += $(LINKFLAGS_DEBUG) ;
2413 rule --k8jam-profile-standard-- {
2414   Echo "MSG: 'standard' profile" ;
2415   SLACK_PKG_ARCH = "i486" ;
2416   CFLAGS.all += -O2 ;
2417   LINKFLAGS.all += -s ;
2421 # profile "name" ;
2422 # set compile flags for profile; works only for gcc/g++
2423 # available profiles:
2424 #  none, default: don't change
2425 #  empty: remove optimisation flags
2426 #  speed: optimise for speed and pIII
2427 #  size: optimise for size
2428 #  debug: don't optimize, add debug info
2429 #  standard: -O2
2430 rule profile {
2431   if ! $(1) in $(K8JAM-KNOWN-PROFILES) {
2432     Echo "known profiles: $(K8JAM-KNOWN-PROFILES)" ;
2433     Exit "unknown profile: $(1)" ;
2434   }
2436   local orm = "(^\\-march\\=)" "(^\\-mtune\\=)" "(^\\-mfpmath\\=)" "(^\\-O.$)" ;
2437   local ormff = "(^\\-f[^n][^o])" ;
2439   OPTIM = [ RemoveOptWild $(orm) $(ormff) : $(OPTIM) ] ;
2440   C++OPTIM = [ RemoveOptWild $(orm) $(ormff) : $(C++OPTIM) ] ;
2441   OBJCOPTIM = [ RemoveOptWild $(orm) $(ormff) : $(OBJCOPTIM) ] ;
2442   OPTIM.all = [ RemoveOptWild $(orm) $(ormff) : $(OPTIM.all) ] ;
2443   LINKFLAGS -= "-g" "-s" ;
2444   C++LINKFLAGS -= "-g" "-s" ;
2445   OBJCLINKFLAGS -= "-g" "-s" ;
2446   LINKFLAGS.all -= "-g" "-s" ;
2448   OPT_PROFILE = $(1) ;
2449   --k8jam-profile-$(OPT_PROFILE)-- ;
2451 #SLACK_PKG_ARCH ?= "i486" ;
2454 # selects 'debug', 'standard', 'speed' or 'size' profile according to vars:
2455 #  DEBUG = 1 : debug
2456 #  OPT_SIZE = 1 : size
2457 #  OPT_SPEED = 1 : speed
2458 #  default: standard
2459 rule set-profile {
2460   if $(DEBUG) {
2461     profile "debug" ;
2462   } else if $(OPT_SIZE) {
2463     profile "size" ;
2464   } else if $(OPT_SPEED) {
2465     profile "speed" ;
2466   } else {
2467     profile "standard" ;
2468   }
2469   if $(VALGRIND) {
2470     CFLAGS.all -= "-g" "-s" ;
2471     LINKFLAGS.all -= "-g" "-s" ;
2472     CFLAGS.all += -g ;
2473     LINKFLAGS.all += -g ;
2474   }
2475   if ! $(NO_WARNINGS) {
2476     CFLAGS.all += -Wall ;
2477   }
2481 # set default 'locate' vars -- _build/, etc
2482 rule set-default-subdir-locates {
2483   local d = $(TOP) ;
2484   if ! $(d) { d = "." ; }
2485   ALL_LOCATE_BIN = $(d) ;
2486   ALL_LOCATE_LIBSO = $(d) ;
2487   if $(WINDOZE) {
2488     ALL_LOCATE_TARGET = $(d)$(PATH_SEPARATOR)_wbuild ;
2489     ALL_LOCATE_LIB = $(d)$(PATH_SEPARATOR)_wbuild$(PATH_SEPARATOR)lib ;
2490     HCACHEFILE = $(d)$(PATH_SEPARATOR)_wbuild$(PATH_SEPARATOR).jamhdr.cache ;
2491   } else {
2492     ALL_LOCATE_TARGET = $(d)$(PATH_SEPARATOR)_build ;
2493     ALL_LOCATE_LIB = $(d)$(PATH_SEPARATOR)_build$(PATH_SEPARATOR)lib ;
2494     HCACHEFILE = $(d)$(PATH_SEPARATOR)_build$(PATH_SEPARATOR).jamhdr.cache ;
2495   }
2496   Clean clean : $(HCACHEFILE) ;
2500 rule set-default-target-locations {
2501   set-default-subdir-locates ;
2504 rule set-default-locations {
2505   set-default-subdir-locates ;
2508 rule set-target-locations {
2509   set-default-subdir-locates ;
2514 # windoze setup
2517 rule setup-windoze {
2518   if ! $(WINDOZE) { WINDOZE = 1 ; }
2519   PICFLAGS = ;
2520   SUFLIBSHR = .dll ;
2521   #WINDOZE_THREADS = -mthreads ;
2522   #WINDOZE_THREADS = ;
2523   WINE ?= "wine" ;
2524   MGPATH ?= "c:\\\\mingw\\\\bin\\\\" ;
2525   MGCC ?= "mingw32-gcc.exe -static-libgcc" ;
2526   MG++ ?= "mingw32-g++.exe -static-libgcc -static-libstdc++" ;
2527   CC = "$(WINE)" $(MGPATH)$(MGCC) ;
2528   LINK = "$(WINE)" $(MGPATH)$(MGCC) -Wl,--enable-auto-import ;
2529   AR = "$(WINE)" $(MGPATH)ar.exe -ru ;
2530   RANLIB = "$(WINE)" $(MGPATH)ranlib.exe ;
2531   C++ = "$(WINE)" $(MGPATH)$(MG++) ;
2532   C++LINK = "$(WINE)" $(MGPATH)$(MG++) -Wl,--enable-auto-import ;
2533   #LINKLIBS += -lkernel32 ;
2534   #LINKLIBS += -luser32 ;
2535   #LINKLIBS += -ladvapi32 ;
2536   #LINKLIBS += -lws2_32 ;
2537   #WINSUBSYS = "windows" ;
2538   #WINSUBSYS = "console" ;
2539   SUFEXE = .exe ;
2540   #LINKFLAGS += "-Wl,-subsystem,$(WINSUBSYS)" ;
2544 rule check-setup-windoze {
2545   if $(WINDOZE) { setup-windoze ; }
2550 # ObjectNoAliasing filelist ;
2551 # turn off aliasing optimization for specified files
2552 # works only for gcc/g++
2553 rule ObjectNoAliasing {
2554   local isGCC = "ona" ;
2555   local isG++ = "ona" ;
2556   if ( "gcc" in $(CC) ) || ( $(JAM_TOOLSET) = MINGW ) { isGCC = "tan" ; }
2557   if ( "g++" in $(C++) ) || ( $(JAM_TOOLSET) = MINGW ) { isG++ = "tan" ; }
2558   if $(JAM_FORCE_GCC_OPTIONS) { isGCC = "tan" ; isG++ = "tan" ; }
2560   if $(isGCC) = "tan" { CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(OPTIM_NOALIAS) ; }
2561   if $(isG++) = "tan" { C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(OPTIM_NOALIAS) ; }
2562   OBJCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(OPTIM_NOALIAS) ;
2566 # call $(1)
2567 # add output to var $(2)
2568 # return resulting (non-empty) string if library is present
2569 # if $(2) = "" -- don't add flags, just return
2570 # [ lib-config-ex "pkg-config sdl --cflags" : "CFLAGS" ]
2571 rule lib-config-ex {
2572   local cf lf res ;
2573   cf = [ Command "$(1) 2>/dev/null" : parse-output exit-code code-first ] ;
2574   if $(cf[1]) = "0" && $(cf[2]) {
2575     res = $(cf[2-]) ;
2576     if $(2) {
2577       $(2) += $(cf[2-]) ;
2578     }
2579   } else {
2580     res = ;
2581   }
2582   return $(res) ;
2586 # call $(1) --cflags and $(1) --libs (many libs provides such configurators)
2587 # add necessary flags to compiler and linker vars
2588 # return "tan" (non-empty string) if library is present
2589 # if $(2) != "" -- don't add flags, just check
2590 # [ lib-config "pkg-config sdl" ]
2591 rule lib-config {
2592   local cf lf hasit ;
2594   cf = [ Command "$(1) --cflags 2>/dev/null" : parse-output exit-code code-first ] ;
2595   #Echo "cf:" $(cf) ;
2596   if $(cf[1]) = "0" && $(cf[2]) {
2597     hasit = "tan" ;
2598     #Echo "flags:" $(cf[2-]) ;
2599     if ! $(2) {
2600       CCFLAGS += $(cf[2-]) ;
2601       C++FLAGS += $(cf[2-]) ;
2602       OBJCFLAGS += $(cf[2-]) ;
2603     }
2604   }
2606   lf = [ Command "$(1) --libs 2>/dev/null" : parse-output exit-code code-first ] ;
2607   #Echo "lf:" $(lf) ;
2608   if $(lf[1]) = "0" && $(lf[2]) {
2609     hasit = "tan" ;
2610     #Echo "flags:" $(lf[2-]) ;
2611     if ! $(2) {
2612       LINKFLAGS += $(lf[2-]) ;
2613       C++LINKFLAGS += $(lf[2-]) ;
2614       OBJCLINKFLAGS += $(lf[2-]) ;
2615     }
2616   }
2618   return $(hasit) ;
2621 rule pkg-config {
2622   local res ;
2623   res = [ lib-config "pkg-config $(1)" ] ;
2624   return $(res) ;
2628 rule pkg-config-has {
2629   local res ;
2630   res = [ lib-config-ex "pkg-config $(1) --cflags --libs" ] ;
2631   return $(res) ;
2636 # Objective C vars
2639 OBJC_GNUSTEP_BASE_LIB = gnustep-base ;
2640 OBJC_GNUSTEP_GUI_LIB = gnustep-gui ;
2643 # Objective C rules
2645 rule ObjCUseGNUstepBase {
2646   if ! $(K8_INTERNAL_GNUSTEP_BASE) {
2647     #Echo "-l$(OBJC_GNUSTEP_BASE_LIB)" ;
2648     OBJCLINKLIBS += "-l$(OBJC_GNUSTEP_BASE_LIB)" ;
2649     K8_INTERNAL_GNUSTEP_BASE = tan ;
2650   }
2653 rule ObjCUseGNUstepGui {
2654   ObjCUseGNUstepBase ;
2655   if ! $(K8_INTERNAL_GNUSTEP_GUI) {
2656     K8_INTERNAL_GNUSTEP_GUI = tan ;
2657     #Echo "-l$(OBJC_GNUSTEP_GUI_LIB)" ;
2658     OBJCLINKLIBS += "-l$(OBJC_GNUSTEP_GUI_LIB)" ;
2659   }
2662 rule ObjCUseGNUstep {
2663   ObjCUseGNUstepBase ;
2664   ObjCUseGNUstepGui ;
2669 # 'help' and 'push' targets
2671 rule ShowHelpProfile {
2672   NotFile help-profile ;
2673   Always help-profile ;
2674   AShowHelpProfile help-profile ;
2676 actions AShowHelpProfile {
2677   echo "profile flags:"
2678   echo "  DEBUG=1           -- debug build"
2679   echo "  OPT_SPEED=1       -- optimize for speed"
2680   echo "  OPT_SIZE=1        -- optimize for size"
2681   echo "  VALGRIND=1        -- do not strip debug info"
2682   echo "  NO_WARNINGS=1     -- do not all '-Wall' flag"
2683   echo "WARNING: DON'T FORGET TO DO 'jam clean' before building with new flags!"
2685 ShowHelpProfile ;
2687 rule ShowHelp {
2688   NotFile help ;
2689   Always help ;
2690   AShowHelp help ;
2691   #AShowHelpProfile help ;
2693 actions AShowHelp {
2694   echo "WARNING: default help; override 'actions AShowHelp' definition to use 'help' target!"
2696 ShowHelp ;
2698 rule GitPush {
2699   NotFile push ;
2700   Always push ;
2701   AGitPush push ;
2703 actions AGitPush {
2704   echo "WARNING: add 'actions AGitPush' definition to use 'push' target!"
2706 GitPush ;
2709 check-setup-windoze ;
2712 # Now include the user's Jamfile.
2714 include $(JAMFILE) ;