Imported Upstream version 1.57.0
[platform/upstream/boost.git] / tools / build / src / engine / build.jam
1 #~ Copyright 2002-2007 Rene Rivera.
2 #~ Distributed under the Boost Software License, Version 1.0.
3 #~ (See accompanying file LICENSE_1_0.txt or copy at
4 #~ http://www.boost.org/LICENSE_1_0.txt)
5
6 # Clean env vars of any "extra" empty values.
7 for local v in ARGV CC CFLAGS LIBS
8 {
9     local values ;
10     for local x in $($(v))
11     {
12         if $(x) != ""
13         {
14             values += $(x) ;
15         }
16     }
17     $(v) = $(values) ;
18 }
19
20 # Platform related specifics.
21 if $(OS) = NT { rule .path { return "$(<:J=\\)" ; } ./ = "/" ; }
22 else { rule .path { return "$(<:J=/)" ; } }
23
24 . = "." ;
25 ./ ?= "" ;
26
27 # Info about what we are building.
28 _VERSION_ = 3 1 19 ;
29 NAME = boost-jam ;
30 VERSION = $(_VERSION_:J=$(.)) ;
31 RELEASE = 1 ;
32 LICENSE = LICENSE_1_0 ;
33
34 # Generate development debug binaries?
35 if --debug in $(ARGV)
36 {
37     debug = true ;
38 }
39
40 if --profile in $(ARGV)
41 {
42     profile = true ;
43 }
44
45 # Attempt to generate and/or build the grammar?
46 if --grammar in $(ARGV)
47 {
48     grammar = true ;
49 }
50
51 # Do we need to add a default build type argument?
52 if ! ( --release in $(ARGV) ) &&
53    ! ( --debug in $(ARGV) ) &&
54    ! ( --profile in $(ARGV) )
55 {
56     ARGV += --release ;
57 }
58
59 # Enable, and configure, Python hooks.
60 with-python = ;
61 python-location = [ MATCH --with-python=(.*) : $(ARGV) ] ;
62 if $(python-location)
63 {
64     with-python = true ;
65 }
66 if $(with-python)
67 {
68     if $(OS) = NT
69     {
70         --python-include = [ .path $(python-location) include ] ;
71         --python-lib = ;
72         for local v in 27 26 25 24 23 22
73         {
74             --python-lib ?=
75                 [ GLOB [ .path $(python-location) libs ] : "python$(v).lib" ]
76                 [ GLOB $(python-location) [ .path $(python-location) libs ]
77                     $(Path) $(PATH) $(path) : "python$(v).dll" ]
78                 ;
79             if ! $(--python-lib[2])
80             {
81                 --python-lib = ;
82             }
83         }
84         --python-lib = $(--python-lib[1]) ;
85     }
86     else if $(OS) = MACOSX
87     {
88         --python-include = [ .path $(python-location) Headers ] ;
89         --python-lib = $(python-location) Python ;
90     }
91     else
92     {
93         --python-include = ;
94         --python-lib = ;
95         for local v in 2.7 2.6 2.5 2.4 2.3 2.2
96         {
97             local inc = [ GLOB [ .path $(python-location) include ] : python$(v) ] ;
98             local lib = [ GLOB [ .path $(python-location) lib ] : libpython$(v)* ] ;
99             if $(inc) && $(lib)
100             {
101                 --python-include ?= $(inc) ;
102                 --python-lib ?= $(lib[1]:D) python$(v) ;
103             }
104         }
105     }
106 }
107
108 # Boehm GC?
109 if --gc in $(ARGV)
110 {
111     --boehm-gc = true ;
112 }
113 if $(--boehm-gc)
114 {
115     --extra-include += [ .path [ PWD ] "boehm_gc" "include" ] ;
116 }
117
118 # Duma?
119 if --duma in $(ARGV)
120 {
121     --duma = true ;
122 }
123 if $(--duma)
124 {
125     --extra-include += [ .path [ PWD ] "duma" ] ;
126 }
127
128 # An explicit root for the toolset? (trim spaces)
129 toolset-root = [ MATCH --toolset-root=(.*) : $(ARGV) ] ;
130 {
131     local t = [ MATCH "[ ]*(.*)" : $(toolset-root:J=" ") ] ;
132     toolset-root = ;
133     while $(t)
134     {
135         t = [ MATCH "([^ ]+)([ ]*)(.*)" : $(t) ] ;
136         toolset-root += $(t[1]) ;
137         if $(t[3]) { toolset-root += $(t[2]) ; }
138         t = $(t[3]) ;
139     }
140     toolset-root = $(toolset-root:J="") ;
141 }
142
143 # Configure the implemented toolsets. These are minimal commands and options to
144 # compile the full Jam. When adding new toolsets make sure to add them to the
145 # "known" list also.
146
147 rule toolset ( name command .type ? : opt.out + : opt.define * : flags * : linklibs * )
148 {
149     .type ?= "" ;
150     tool.$(name)$(.type).cc ?= $(command) ;
151     tool.$(name)$(.type).opt.out ?= $(opt.out) ;
152     tool.$(name)$(.type).opt.define ?= $(opt.define) ;
153     tool.$(name)$(.type).flags ?= $(flags) ;
154     tool.$(name)$(.type).linklibs ?= $(linklibs) ;
155     if ! $(name) in $(toolsets) { toolsets += $(name) ; }
156 }
157
158 rule if-os ( os + : yes-opt * : no-opt * )
159     { if $(os) in $(OS) { return $(yes-opt) ; } else { return $(no-opt) ; } }
160
161 rule opt ( type : yes-opt * : no-opt * )
162     { if $(type) in $(ARGV) { return $(yes-opt) ; } else { return $(no-opt) ; } }
163
164 ## HP-UX aCC compiler
165 toolset acc cc : "-o " : -D
166     : -Ae
167     [ opt --release : -s -O3 ]
168     [ opt --debug : -g -pg ]
169     -I$(--python-include) -I$(--extra-include)
170     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
171 ## Borland C++ 5.5.x
172 toolset borland bcc32 : -e -n : /D
173     : -WC -w- -q "-I$(toolset-root)Include" "-L$(toolset-root)Lib"
174     [ opt --release : -O2 -vi -w-inl ]
175     [ opt --debug : -v -Od -vi- ]
176     -I$(--python-include) -I$(--extra-include)
177     : $(--python-lib[1]) ;
178 ## Generic Unix cc
179 if ! $(CC) { CC = cc ; }
180 toolset cc $(CC) : "-o " : -D
181     : $(CFLAGS)
182     [ opt --release : -s -O ]
183     [ opt --debug : -g ]
184     -I$(--python-include) -I$(--extra-include)
185     : $(LIBS) -L$(--python-lib[1]) -l$(--python-lib[2]) ;
186 ## Comeau C/C++ 4.x
187 toolset como como : "-o " : -D
188     : --c
189     [ opt --release : --inlining ]
190     [ opt --debug : --no_inlining ]
191     -I$(--python-include) -I$(--extra-include)
192     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
193 ## Clang Linux 2.8+
194 toolset clang clang :  "-o " : -D
195     : -Wno-unused -Wno-format
196     [ opt --release : -Os ]
197     [ opt --debug : -g -O0 -fno-inline ]
198     [ opt --profile : -finline-functions -g ]
199     -I$(--python-include) -I$(--extra-include)
200     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
201 ## MacOSX Darwin, using GCC 2.9.x, 3.x
202 toolset darwin cc :  "-o " : -D
203     :
204     [ opt --release : -Wl,-x -O3 -finline-functions ]
205     [ opt --debug : -g -O0 -fno-inline -pg ]
206     [ opt --profile : -Wl,-x -O3 -finline-functions -g -pg ]
207     -I$(--python-include) -I$(--extra-include)
208     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
209 ## GCC 2.x, 3.x, 4.x
210 toolset gcc gcc : "-o " : -D
211     : -pedantic -fno-strict-aliasing
212     [ opt --release : [ opt --symbols : -g : -s ] -O3 ]
213     [ opt --debug : -g -O0 -fno-inline ]
214     [ opt --profile : -O3 -g -pg ]
215     -I$(--python-include) -I$(--extra-include) -Wno-long-long
216     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
217 ## GCC 2.x, 3.x on CYGWIN but without cygwin1.dll
218 toolset gcc-nocygwin gcc : "-o " : -D
219     : -s -O3 -mno-cygwin
220     [ opt --release : -finline-functions ]
221     [ opt --debug : -s -O3 -fno-inline -pg ]
222     -I$(--python-include) -I$(--extra-include)
223     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
224 ## Intel C/C++ for Darwin
225 toolset intel-darwin icc : "-o " : -D
226     :
227     [ opt --release : -O3 ]
228     [ opt --debug : -g -O0 -p ]
229     -I$(--python-include) -I$(--extra-include)
230     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
231 ## Intel C/C++ for Linux
232 toolset intel-linux icc : "-o " : -D
233     :
234     [ opt --release : -Xlinker -s -O3 ]
235     [ opt --debug : -g -O0 -p ]
236     -I$(--python-include) -I$(--extra-include)
237     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
238 ## Intel C/C++ for Win32
239 toolset intel-win32 icl : /Fe : -D
240     : /nologo
241     [ opt --release : /MT /O2 /Ob2 /Gy /GF /GA /GB ]
242     [ opt --debug : /MTd /DEBUG /Z7 /Od /Ob0 ]
243     -I$(--python-include) -I$(--extra-include)
244     : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ;
245 ## KCC ?
246 toolset kcc KCC : "-o " : -D
247     :
248     [ opt --release : -s +K2 ]
249     [ opt --debug : -g +K0 ]
250     -I$(--python-include) -I$(--extra-include)
251     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
252 ## Borland Kylix
253 toolset kylix bc++ : -o : -D
254     : -tC -q
255     [ opt --release : -O2 -vi -w-inl ]
256     [ opt --debug : -v -Od -vi- ]
257     -I$(--python-include) -I$(--extra-include)
258     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
259 ## Metrowerks CodeWarrior 8.x
260 {
261     # Even though CW can compile all files at once, it crashes if it tries in
262     # the bjam case.
263     local mwcc ; if $(OS) != NT { mwcc = mwc$(OSPLAT:L) ; }
264     mwcc ?= mwcc ;
265     toolset metrowerks $(mwcc) : "-o " : -D
266         : -c -lang c -subsystem console -cwd include
267         [ opt --release : -runtime ss -opt full -inline all ]
268         [ opt --debug : -runtime ssd -opt none -inline off ]
269         -I$(--python-include) -I$(--extra-include) ;
270     toolset metrowerks $(mwcc) .link : "-o " :
271         : -subsystem console -lkernel32.lib -ladvapi32.lib -luser32.lib
272         [ opt --release : -runtime ss ]
273         [ opt --debug : -runtime ssd ]
274         : $(--python-lib[1]) ;
275 }
276 ## MINGW GCC
277 toolset mingw gcc : "-o " : -D
278     :
279     [ opt --release : -s -O3 -finline-functions ]
280     [ opt --debug : -g -O0 -fno-inline -pg ]
281     -I$(--python-include) -I$(--extra-include)
282     : $(--python-lib[2]) ;
283 ## MIPS Pro
284 toolset mipspro cc : "-o " : -D
285     :
286     [ opt --release : -s -O3 -g0 -INLINE:none ]
287     [ opt --debug : -g -O0 -INLINE ]
288     -I$(--python-include) -I$(--extra-include)
289     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
290 ## Microsoft Visual Studio C++ 6.x
291 toolset msvc cl : /Fe /Fe /Fd /Fo : -D
292     : /nologo
293     [ opt --release : /ML /O2 /Ob2 /Gy /GF /GA /GB ]
294     [ opt --debug : /MLd /DEBUG /Z7 /Od /Ob0 ]
295     -I$(--python-include) -I$(--extra-include)
296     : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ;
297 ## QNX 6.x GCC 3.x/2.95.3
298 toolset qcc qcc : "-o " : -D
299     : -Wc,-pedantic -Wc,-fno-strict-aliasing
300     [ opt --release : [ opt --symbols : -g ] -O3 -Wc,-finline-functions ]
301     [ opt --debug : -g -O0 -Wc,-fno-inline ]
302     -I$(--python-include) -I$(--extra-include)
303     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
304 ## Qlogic Pathscale 2.4
305 toolset pathscale pathcc : "-o " : -D
306     :
307     [ opt --release : -s -Ofast -O3 ]
308     [ opt --debug : -g ]
309     -I$(--python-include) -I$(--extra-include)
310     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
311 ## Portland Group Pgi 6.2
312 toolset pgi pgcc : "-o " : -D
313     :
314     [ opt --release : -s -O3 ]
315     [ opt --debug : -g ]
316     -I$(--python-include) -I$(--extra-include)
317     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
318 ## Sun Workshop 6 C++
319 toolset sun cc : "-o " : -D
320     :
321     [ opt --release : -s -xO3 ]
322     [ opt --debug : -g ]
323     -I$(--python-include) -I$(--extra-include)
324     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
325 ## Sun Workshop 6 C++ (old alias)
326 toolset sunpro cc : "-o " : -D
327     :
328     [ opt --release : -s -xO3 ]
329     [ opt --debug : -g ]
330     -I$(--python-include) -I$(--extra-include)
331     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
332 ## Compaq Alpha CXX
333 toolset tru64cxx cc : "-o " : -D
334     :
335     [ opt --release : -s -O5 -inline speed ]
336     [ opt --debug : -g -O0 -pg ]
337     -I$(--python-include) -I$(--extra-include)
338     : -L$(--python-lib[1]) -l$(--python-lib[2]) ;
339 ## IBM VisualAge C++
340 toolset vacpp xlc : "-o " : -D
341     :
342     [ opt --release : -s -O3 -qstrict -qinline ]
343     [ opt --debug : -g -qNOOPTimize -qnoinline -pg ]
344     -I$(--python-include) -I$(--extra-include)
345     : -L$(--python-lib[1]) -l$(--python-lib[2]) [ if-os AIX : -bmaxdata:0x40000000 ] ;
346 ## Microsoft Visual C++ .NET 7.x
347 toolset vc7 cl : /Fe /Fe /Fd /Fo : -D
348     : /nologo
349     [ opt --release : /ML /O2 /Ob2 /Gy /GF /GA /GB ]
350     [ opt --debug : /MLd /DEBUG /Z7 /Od /Ob0 ]
351     -I$(--python-include) -I$(--extra-include)
352     : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ;
353 ## Microsoft Visual C++ 2005
354 toolset vc8 cl : /Fe /Fe /Fd /Fo : -D
355     : /nologo
356     [ opt --release : /MT /O2 /Ob2 /Gy /GF /GA /wd4996 ]
357     [ opt --debug : /MTd /DEBUG /Z7 /Od /Ob0 /wd4996 ]
358     -I$(--python-include) -I$(--extra-include)
359     : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ;
360 ## Microsoft Visual C++ 2008
361 toolset vc9 cl : /Fe /Fe /Fd /Fo : -D
362     : /nologo
363     [ opt --release : /MT /O2 /Ob2 /Gy /GF /GA /wd4996 ]
364     [ opt --debug : /MTd /DEBUG /Z7 /Od /Ob0 /wd4996 ]
365     -I$(--python-include) -I$(--extra-include)
366     : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ;
367 ## Microsoft Visual C++ 2010
368 toolset vc10 cl : /Fe /Fe /Fd /Fo : -D
369     : /nologo
370     [ opt --release : /MT /O2 /Ob2 /Gy /GF /GA /wd4996 ]
371     [ opt --debug : /MTd /DEBUG /Z7 /Od /Ob0 /wd4996 ]
372     -I$(--python-include) -I$(--extra-include)
373     : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ;
374 ## Microsoft Visual C++ 2012
375 toolset vc11 cl : /Fe /Fe /Fd /Fo : -D
376     : /nologo
377     [ opt --release : /GL /MT /O2 /Ob2 /Gy /GF /GA /wd4996 ]
378     [ opt --debug : /MTd /DEBUG /Z7 /Od /Ob0 /wd4996 ]
379     -I$(--python-include) -I$(--extra-include)
380     : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ;
381 ## Microsoft Visual C++ 2013
382 toolset vc12 cl : /Fe /Fe /Fd /Fo : -D
383     : /nologo
384     [ opt --release : /GL /MT /O2 /Ob2 /Gy /GF /GA /wd4996 ]
385     [ opt --debug : /MTd /DEBUG /Z7 /Od /Ob0 /wd4996 ]
386     -I$(--python-include) -I$(--extra-include)
387     : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ;
388 toolset vc14 cl : /Fe /Fe /Fd /Fo : -D
389     : /nologo
390     [ opt --release : /GL /MT /O2 /Ob2 /Gy /GF /GA /wd4996 ]
391     [ opt --debug : /MTd /DEBUG /Z7 /Od /Ob0 /wd4996 ]
392     -I$(--python-include) -I$(--extra-include)
393     : kernel32.lib advapi32.lib user32.lib $(--python-lib[1]) ;
394
395 # First set the build commands and options according to the
396 # preset toolset.
397 toolset = [ MATCH --toolset=(.*) : $(ARGV) ] ;
398 if ! $(toolset)
399 {
400     # For some reason, the following test does not catch empty toolset.
401     ECHO "###" ;
402     ECHO "###" No toolset specified. Please use --toolset option. ;
403     ECHO "###" ;
404     ECHO "###" Known toolsets are: $(toolsets:J=", ") ;
405     EXIT "###" ;
406 }
407 if ! $(toolset) in $(toolsets)
408 {
409     ECHO "###" ;
410     ECHO "###" Unknown toolset: $(toolset) ;
411     ECHO "###" ;
412     ECHO "###" Known toolsets are: $(toolsets:J=", ") ;
413     EXIT "###" ;
414 }
415 --cc = $(tool.$(toolset).cc) ;
416 if $(tool.$(toolset).opt.out[2])
417 {
418     if $(tool.$(toolset).opt.out[1]) = $(tool.$(toolset).opt.out[2])
419     {
420         --out = $(tool.$(toolset).opt.out[1]) ;
421         --dir = $(tool.$(toolset).opt.out[3-]) ;
422     }
423     else
424     {
425         --bin = $(tool.$(toolset).opt.out[1]) ;
426         --dir = $(tool.$(toolset).opt.out[2-]) ;
427     }
428 }
429 else
430 {
431     --out = $(tool.$(toolset).opt.out) ;
432 }
433 --def = $(tool.$(toolset).opt.define) ;
434 --flags = $(tool.$(toolset).flags) ;
435 --defs = $(tool.$(toolset).defines) ;
436 --libs = $(tool.$(toolset).linklibs) ;
437 if $(tool.$(toolset).link.cc)
438 {
439     --link = $(tool.$(toolset).link.cc) ;
440     if $(tool.$(toolset).link.opt.out[2])
441     {
442         if $(tool.$(toolset).link.opt.out[1]) = $(tool.$(toolset).link.opt.out[2])
443         {
444             --link-out = $(tool.$(toolset).link.opt.out[1]) ;
445             --link-dir = $(tool.$(toolset).link.opt.out[3-]) ;
446         }
447         else
448         {
449             --link-bin = $(tool.$(toolset).link.opt.out[1]) ;
450             --link-dir = $(tool.$(toolset).link.opt.out[2-]) ;
451         }
452     }
453     else
454     {
455         --link-out = $(tool.$(toolset).link.opt.out) ;
456     }
457     --link-def = $(tool.$(toolset).link.opt.define) ;
458     --link-flags = $(tool.$(toolset).link.flags) ;
459     --link-defs = $(tool.$(toolset).link.defines) ;
460     --link-libs = $(tool.$(toolset).link.linklibs) ;
461 }
462
463 # Put executables in platform-specific subdirectory.
464 locate-target = $(LOCATE_TARGET) ;
465 if $(OSPLAT)
466 {
467     locate-target ?= bin$(.)$(OS:L)$(OSPLAT:L) ;
468     platform = $(OS:L)$(OSPLAT:L) ;
469 }
470 else
471 {
472     locate-target ?= bin$(.)$(OS:L) ;
473     platform = $(OS:L) ;
474 }
475 if $(debug)
476 {
477     locate-target = [ .path $(locate-target)$(.)debug ] ;
478 }
479 if $(profile)
480 {
481     locate-target = [ .path $(locate-target)$(.)profile ] ;
482 }
483 else
484 {
485     locate-target = [ .path $(locate-target) ] ;
486 }
487
488 if --show-locate-target in $(ARGV)
489 {
490     ECHO $(locate-target) ;
491 }
492
493 # We have some different files for UNIX, and NT.
494 jam.source =
495     command.c compile.c constants.c debug.c execcmd.c frames.c function.c glob.c
496     hash.c hcache.c headers.c hdrmacro.c jam.c jambase.c jamgram.c lists.c
497     make.c make1.c mem.c object.c option.c output.c parse.c pathsys.c regexp.c
498     rules.c scan.c search.c subst.c w32_getreg.c timestamp.c variable.c
499     modules.c strings.c filesys.c builtins.c class.c cwd.c native.c md5.c
500     [ .path modules set.c ] [ .path modules path.c ] [ .path modules regex.c ]
501     [ .path modules property-set.c ] [ .path modules sequence.c ] [ .path modules order.c ] ;
502 if $(OS) = NT
503 {
504     jam.source += execnt.c filent.c pathnt.c ;
505 }
506 else
507 {
508     jam.source += execunix.c fileunix.c pathunix.c ;
509 }
510
511 # Debug assertions, or not.
512 if ! $(debug) || --noassert in $(ARGV)
513 {
514     --defs += NDEBUG ;
515 }
516
517 # Enable some optional features.
518 --defs += OPT_HEADER_CACHE_EXT ;
519 --defs += OPT_GRAPH_DEBUG_EXT ;
520 --defs += OPT_SEMAPHORE ;
521 --defs += OPT_AT_FILES ;
522 --defs += OPT_DEBUG_PROFILE ;
523
524 # Bug fixes
525 --defs += OPT_FIX_TARGET_VARIABLES_EXT ;
526 #~ --defs += OPT_NO_EXTERNAL_VARIABLE_SPLIT ;
527
528 # Improvements
529 --defs += OPT_IMPROVED_PATIENCE_EXT ;
530
531 # Use Boehm GC memory allocator?
532 if $(--boehm-gc)
533 {
534     --defs += OPT_BOEHM_GC ;
535     if $(debug)
536     {
537         --defs += GC_DEBUG ;
538     }
539 }
540
541 if $(--duma)
542 {
543     --defs += OPT_DUMA ;
544 }
545
546 if ( $(OS) = NT ) && ! NT in $(--defs)
547 {
548     --defs += NT ;
549 }
550 --defs += YYSTACKSIZE=5000 ;
551
552 if $(with-python)
553 {
554     --defs += HAVE_PYTHON ;
555 }
556
557 if $(debug)
558 {
559     --defs += BJAM_NEWSTR_NO_ALLOCATE ;
560 }
561
562
563 # The basic symbolic targets...
564 NOTFILE all clean dist ;
565 ALWAYS clean ;
566
567 # Utility rules and actions...
568 rule .clean
569 {
570     [DELETE] clean : $(<) ;
571 }
572 if $(OS) = NT { actions piecemeal together existing [DELETE] {
573     del /F /Q "$(>)"
574 } }
575 if $(UNIX) = true { actions piecemeal together existing [DELETE] {
576     rm -f "$(>)"
577 } }
578 if $(OS) = NT {
579     --chmod+w = "attrib -r " ;
580 }
581 if $(UNIX) = true {
582     --chmod+w = "chmod +w " ;
583 }
584
585 rule .mkdir
586 {
587     NOUPDATE $(<) ;
588     if $(<:P) { DEPENDS $(<) : $(<:P) ; .mkdir $(<:P) ; }
589     if ! $(md<$(<)>) { [MKDIR] $(<) ; md<$(<)> = - ; }
590 }
591 if $(OS) = NT { actions [MKDIR] {
592     md "$(<)"
593 } }
594 if $(UNIX) = true { actions [MKDIR] {
595     mkdir "$(<)"
596 } }
597
598 rule .exe
599 {
600     local exe = $(<) ;
601     if $(OS) = NT || ( $(UNIX) = true && $(OS) = CYGWIN ) { exe = $(exe:S=.exe) ; }
602     LOCATE on $(exe) = $(locate-target) ;
603     DEPENDS all : $(exe) ;
604     .mkdir $(locate-target) ;
605     if $(--link)
606     {
607         local objs ;
608         for local s in $(>)
609         {
610             # Translate any subdir elements into a simple file name.
611             local o = [ MATCH "([^/]+)[/]?(.+)" : $(s) ] ;
612             o = $(o:J=_) ;
613             o = $(o:S=.o) ;
614             objs += $(o) ;
615             LOCATE on $(o) = $(locate-target) ;
616             DEPENDS $(exe) : $(o) ;
617             DEPENDS $(o) : $(s) ;
618             DEPENDS $(o) : $(locate-target) ;
619             [COMPILE] $(o) : $(s) ;
620             .clean $(o) ;
621         }
622         DEPENDS $(exe) : $(objs) ;
623         DEPENDS $(exe) : $(locate-target) ;
624         [COMPILE.LINK] $(exe) : $(objs) ;
625         .clean $(exe) ;
626     }
627     else
628     {
629         DEPENDS $(exe) : $(>) ;
630         DEPENDS $(exe) : $(locate-target) ;
631         [COMPILE] $(exe) : $(>) ;
632         .clean $(exe) ;
633     }
634     return $(exe) ;
635 }
636 if ! $(--def[2]) { actions [COMPILE] {
637     "$(--cc)" "$(--bin)$(<:D=)" "$(--dir)$(<:D)$(./)" $(--out)$(<) "$(--def)$(--defs)" "$(--flags)" "$(>)" "$(--libs)"
638 } }
639 else { actions [COMPILE] {
640     "$(--cc)" "$(--bin)$(<:D=)" "$(--dir)$(<:D)$(./)" $(--out)$(<) "$(--def[1])$(--defs:J=$(--def[2]))$(--def[3])" "$(--flags)"  "$(>)" "$(--libs)"
641 } }
642
643 actions [COMPILE.LINK] {
644     "$(--link)" "$(--link-bin)$(<:D=)" "$(--link-dir)$(<:D)$(./)" "$(--link-out)$(<)" "$(--link-def)$(--link-defs)" "$(--link-flags)"  "$(>)" "$(--link-libs)"
645 }
646
647 rule .link
648 {
649     DEPENDS all : $(<) ;
650     DEPENDS $(<) : $(>) ;
651     [LINK] $(<) : $(>) ;
652     .clean $(<) ;
653 }
654 if $(OS) = NT { actions [LINK] {
655     copy "$(>)" "$(<)"
656 } }
657 if $(UNIX) = true { actions [LINK] {
658     ln -fs "$(>)" "$(<)"
659 } }
660
661 rule .copy
662 {
663     DEPENDS all : $(<) ;
664     DEPENDS $(<) : $(>) ;
665     [COPY] $(<) : $(>) ;
666     .clean $(<) ;
667 }
668
669 # Will be redefined later.
670 actions [COPY]
671 {
672 }
673
674
675 rule .move
676 {
677     DEPENDS $(<) : $(>) ;
678     [MOVE] $(<) : $(>) ;
679 }
680 if $(OS) = NT { actions [MOVE] {
681     del /f "$(<)"
682     rename "$(>)" "$(<)"
683 } }
684 if $(UNIX) = true { actions [MOVE] {
685     mv -f "$(>)" "$(<)"
686 } }
687
688 # Generate the grammar tokens table, and the real yacc grammar.
689 rule .yyacc
690 {
691     local exe = [ .exe yyacc : yyacc.c ] ;
692     NOUPDATE $(exe) ;
693     DEPENDS $(<) : $(exe) $(>) ;
694     LEAVES $(<) ;
695     yyacc.exe on $(<) = $(exe:R=$(locate-target)) ;
696     [YYACC] $(<) : $(>) ;
697 }
698 actions [YYACC] {
699     $(--chmod+w)$(<[1])
700     $(--chmod+w)$(<[2])
701     "$(yyacc.exe)" "$(<)" "$(>)"
702 }
703 if $(grammar)
704 {
705     .yyacc jamgram.y jamgramtab.h : jamgram.yy ;
706 }
707 else if $(debug)
708 {
709     .exe yyacc : yyacc.c ;
710 }
711
712 # How to build the grammar.
713 if $(OS) = NT
714 {
715     SUFEXE = .exe ;
716     # try some other likely spellings...
717     PATH ?= $(Path) ;
718     PATH ?= $(path) ;
719 }
720 SUFEXE ?= "" ;
721
722 yacc ?= [ GLOB $(PATH) : yacc$(SUFEXE) ] ;
723 yacc ?= [ GLOB $(PATH) : bison$(SUFEXE) ] ;
724 yacc ?= [ GLOB "$(ProgramFiles:J= )\\GnuWin32\\bin"
725     "C:\\Program Files\\GnuWin32\\bin" : bison$(SUFEXE) ] ;
726 yacc = $(yacc[1]) ;
727 switch $(yacc:D=:S=)
728 {
729     case bison : yacc += -d --yacc ;
730     case yacc  : yacc += -d ;
731 }
732 if $(debug) && $(yacc)
733 {
734     yacc += -t -v ;
735 }
736 yacc += $(YACCFLAGS) ;
737
738 rule .yacc
739 {
740     DEPENDS $(<) : $(>) ;
741     LEAVES $(<) ;
742     [YACC] $(<) : $(>) ;
743 }
744 if $(OS) = NT { actions [YACC] {
745     "$(yacc)" "$(>)"
746     if not errorlevel 1 (
747         del /f "$(<[1])"
748         rename y.tab$(<[1]:S) "$(<[1])"
749         del /f $(<[2])
750         rename y.tab$(<[2]:S) "$(<[2])"
751     ) else set _error_ =
752 } }
753 if $(UNIX) = true { actions [YACC] {
754     if ` "$(yacc)" "$(>)" ` ; then
755         mv -f y.tab$(<[1]:S) "$(<[1])"
756         mv -f y.tab$(<[2]:S) "$(<[2])"
757     else
758         exit 1
759     fi
760 } }
761 if $(grammar) && ! $(yacc)
762 {
763     EXIT Could not find the 'yacc' tool, and therefore can not build the
764         grammar. ;
765 }
766 if $(grammar) && $(yacc)
767 {
768     .yacc jamgram.c jamgram.h : jamgram.y ;
769 }
770
771 # How to build the compiled in jambase.
772 rule .mkjambase
773 {
774     local exe = [ .exe mkjambase : mkjambase.c ] ;
775     DEPENDS $(<) : $(exe) $(>) ;
776     LEAVES $(<) ;
777     mkjambase.exe on $(<) = $(exe:R=$(locate-target)) ;
778     [MKJAMBASE] $(<) : $(>) ;
779 }
780 actions [MKJAMBASE] {
781     $(--chmod+w)$(<)
782     $(mkjambase.exe) "$(<)" "$(>)"
783 }
784 if $(debug)
785 {
786     .mkjambase jambase.c : Jambase ;
787 }
788
789 # How to build Jam.
790 rule .jam
791 {
792     $(>).exe = [ .exe $(>) : $(jam.source) ] ;
793     DEPENDS all : $($(>).exe) ;
794
795     # Make a copy under the old name.
796     $(<).exe = $(<:S=$($(>).exe:S)) ;
797     LOCATE on $($(<).exe) = $(locate-target) ;
798     .copy $($(<).exe) : $($(>).exe) ;
799     DEPENDS all : $($(<).exe) ;
800 }
801 .jam bjam : b2 ;
802
803
804 # Scan sources for header dependencies.
805 #
806 # In order to keep things simple, we made a slight compromise here - we only
807 # detect changes in headers included relative to the current folder as opposed
808 # to those included from somewhere on the include path.
809 rule .scan ( targets + )
810 {
811     HDRRULE on $(targets) = .hdr.scan ;
812     HDRSCAN on $(targets) = "^[ \t]*#[ \t]*include[ \t]*\"([^\"]*)\".*$" ;
813 }
814 rule .hdr.scan ( target : includes * : binding )
815 {
816     local target-path = [ NORMALIZE_PATH $(binding:D) ] ;
817     # Extra grist provides target name uniqueness when referencing same name
818     # header files from different folders.
819     local include-targets = <$(target-path)>$(includes) ;
820     NOCARE $(include-targets) ;
821     INCLUDES $(target) : $(include-targets) ;
822     SEARCH on $(include-targets) = $(target-path) ;
823     ISFILE $(include-targets) ;
824     .scan $(include-targets) ;
825 }
826 .scan $(jam.source) ;
827
828
829 # Distribution making from here on out. Assumes that the docs are already built
830 # as HTML at ../doc/html. Otherwise they will not be included in the built
831 # distribution archive.
832 dist.license =
833     [ GLOB . : $(LICENSE).txt ]
834     ;
835 dist.license = $(dist.license:D=)
836     [ GLOB [ .path .. .. .. ] : $(LICENSE).txt ]
837     [ GLOB [ .path .. boost ] : $(LICENSE).txt ] ;
838 dist.docs =
839     [ GLOB . : *.png *.css *.html ]
840     ;
841 dist.docs = $(dist.docs:D=)
842     [ GLOB [ .path images ] : *.png ]
843     [ GLOB [ .path jam ] : *.html ]
844     ;
845 dist.source =
846     [ GLOB . : *.c *.h ]
847     ;
848 dist.source = $(dist.source:D=)
849     $(dist.license[1])
850     $(dist.docs)
851     build.jam build.bat build.sh
852     Jambase
853     jamgram.y jamgram.yy
854     [ .path modules set.c ]
855     [ .path modules path.c ]
856     [ .path modules regex.c ]
857     [ .path modules property-set.c ]
858     [ .path modules sequence.c ]
859     [ .path modules order.c ]
860     [ GLOB [ .path boehm_gc ] : * ]
861     [ GLOB [ .path boehm_gc include ] : * ]
862     [ GLOB [ .path boehm_gc include private ] : * ]
863     [ GLOB [ .path boehm_gc cord ] : * ]
864     [ GLOB [ .path boehm_gc Mac_files ] : * ]
865     [ GLOB [ .path boehm_gc tests ] : * ]
866     [ GLOB [ .path boehm_gc doc ] : * ]
867     ;
868 dist.bin =
869     bjam
870     ;
871 dist.bin =
872     $(dist.license[1])
873     $(dist.bin:S=$(bjam.exe:S))
874     ;
875
876 if $(OS) = NT
877 {
878     zip ?= [ GLOB "$(ProgramFiles:J= )\\7-ZIP" "C:\\Program Files\\7-ZIP" : "7z.exe" ] ;
879     zip ?= [ GLOB "$(ProgramFiles:J= )\\7-ZIP" "C:\\Program Files\\7-ZIP" : "7zn.exe" ] ;
880     zip ?= [ GLOB $(PATH) : zip.exe ] ;
881     zip ?= zip ;
882     zip = $(zip[1]) ;
883     switch $(zip:D=:S=)
884     {
885         case 7z* : zip += a -r -tzip -mx=9 ;
886         case zip : zip += -9r ;
887     }
888     actions piecemeal [PACK] {
889         "$(zip)" "$(<)" "$(>)"
890     }
891     actions piecemeal [ZIP] {
892         "$(zip)" "$(<)" "$(>)"
893     }
894     actions piecemeal [COPY] {
895         copy /Y "$(>)" "$(<)" >NUL:
896     }
897 }
898 if $(UNIX) = true
899 {
900     tar ?= [ GLOB $(PATH) : star bsdtar tar ] ;
901     tar = $(tar[1]) ;
902     switch $(tar:D=:S=)
903     {
904         case star : tar += -c artype=pax -D -d -to-stdout ;
905         case * : tar += -c -f - ;
906     }
907     actions [PACK] {
908         "$(tar)" "$(>)" | gzip -c9 > "$(<)"
909     }
910     #~ actions [PACK] {
911     #~     tar cf "$(<:S=.tar)" "$(>)"
912     #~ }
913     actions [ZIP] {
914     gzip -c9 "$(>)" > "$(<)"
915     }
916     actions [COPY] {
917         cp -Rpf "$(>)" "$(<)"
918     }
919 }
920
921 # The single binary, compressed.
922 rule .binary
923 {
924     local zip ;
925     if $(OS) = NT { zip = $($(<).exe:S=.zip) ; }
926     if $(UNIX) = true { zip = $($(<).exe:S=.tgz) ; }
927     zip = $(zip:S=)-$(VERSION)-$(RELEASE)-$(platform)$(zip:S) ;
928     DEPENDS $(zip) : $($(<).exe) ;
929     DEPENDS dist : $(zip) ;
930     #~ LOCATE on $(zip) = $(locate-target) ;
931     if $(OS) = NT { [ZIP] $(zip) : $($(<).exe) ; }
932     if $(UNIX) = true { [PACK] $(zip) : $($(<).exe) ; }
933     .clean $(zip) ;
934 }
935
936 # Package some file.
937 rule .package ( dst-dir : src-files + )
938 {
939     local dst-files ;
940     local src-files-actual ;
941     for local src-path in $(src-files)
942     {
943         if ! [ GLOB $(src-path:P) : $(src-path:B) ] || [ CHECK_IF_FILE $(src-path) ]
944         {
945             local src-subdir = $(src-path:D) ;
946             local src-file = $(src-path) ;
947             while $(src-subdir:D) { src-subdir = $(src-subdir:D) ; }
948             if $(src-subdir) = ".."
949             {
950                 src-file = $(src-file:D=) ;
951             }
952             dst-files += $(src-file:R=$(dst-dir)) ;
953             src-files-actual += $(src-path) ;
954         }
955     }
956
957     local pack ;
958     if $(OS) = NT { pack = $(dst-dir).zip ; }
959     if $(UNIX) = true { pack = $(dst-dir).tgz ; }
960
961     DEPENDS dist : $(pack) ;
962     DEPENDS $(pack) : $(dst-files) ;
963
964     local dst-files-queue = $(dst-files) ;
965     for local src-path in $(src-files-actual)
966     {
967         local dst-file = $(dst-files-queue[1]) ;
968         dst-files-queue = $(dst-files-queue[2-]) ;
969         DEPENDS $(dst-file) : $(src-path) $(dst-file:D) ;
970         .mkdir $(dst-file:D) ;
971
972         [COPY] $(dst-file) : $(src-path) ;
973         .clean $(dst-file) ;
974     }
975
976     [PACK] $(pack) : $(dst-files) ;
977     .clean $(pack) ;
978 }
979
980 # RPM distro file.
981 rpm-tool = [ GLOB $(PATH) : "rpmbuild" ] ;
982 rpm-tool ?= [ GLOB $(PATH) : "rpm" ] ;
983 rpm-tool = $(rpm-tool[1]) ;
984 rule .rpm ( name : source )
985 {
986     local rpm-arch ;
987     switch $(OSPLAT)
988     {
989         case X86       : rpm-arch ?= i386 ;
990         case PPC       : rpm-arch ?= ppc ;
991         case AXP       : rpm-arch ?= alpha ;
992         # no guaranty for these:
993         case IA64      : rpm-arch ?= ia64 ;
994         case ARM       : rpm-arch ?= arm ;
995         case SPARC     : rpm-arch ?= sparc ;
996         case *         : rpm-arch ?= other ;
997     }
998     local target = $(name)-rpm ;
999     NOTFILE $(target) ;
1000     DEPENDS dist : $(target) ;
1001     DEPENDS $(target) : $(name).$(rpm-arch).rpm $(name).src.rpm ;
1002     DEPENDS $(name).$(rpm-arch).rpm : $(source) ;
1003     DEPENDS $(name).src.rpm : $(name).$(rpm-arch).rpm ;
1004     docs on $(target) = $(dist.docs:J=" ") ;
1005     arch on $(target) = $(rpm-arch) ;
1006     if $(rpm-arch) = ppc { target-opt on $(target) = --target= ; }
1007     else { target-opt on $(target) = "--target " ; }
1008     [RPM] $(target) : $(source) ;
1009     .clean $(name).$(rpm-arch).rpm $(name).src.rpm ;
1010 }
1011 actions [RPM] {
1012     set -e
1013     export BOOST_JAM_TOOLSET="$(toolset)"
1014     $(rpm-tool) -ta $(target-opt)$(arch) $(>) | tee rpm.out
1015     cp `grep -e '^Wrote:' rpm.out | sed 's/^Wrote: //'` .
1016     rm -f rpm.out
1017 }
1018
1019 # The distribution targets. Do not bother with them unless this is a
1020 # distribution build.
1021 if dist in $(ARGV)
1022 {
1023     #~ .binary bjam ;
1024     .package $(NAME)-$(VERSION) : $(dist.source) ;
1025     .package $(NAME)-$(VERSION)-$(RELEASE)-$(platform) : $(dist.bin) ;
1026     if $(rpm-tool)
1027     {
1028         #~ .rpm $(NAME)-$(VERSION)-$(RELEASE) : $(NAME)-$(VERSION).tgz ;
1029     }
1030 }