Prep for 1.40.0
[boost.git] / Jamroot
blob919ab012c999d2693109d9e328d39f8f9707ac84
1 # Copyright Vladimir Prus 2002-2006.
2 # Copyright Dave Abrahams 2005-2006.
3 # Copyright Rene Rivera 2005-2007.
4 # Copyright Douglas Gregor 2005.
6 # Distributed under the Boost Software License, Version 1.0.
7 #    (See accompanying file LICENSE_1_0.txt or copy at
8 #          http://www.boost.org/LICENSE_1_0.txt)
10 # Usage:
12 #   bjam [options] [properties] [install|stage]
14 #   Builds and installs Boost.
16 # Targets and Related Options:
18 #   install                 Install headers and compiled library files to the
19 #   =======                 configured locations (below).
21 #   --prefix=<PREFIX>       Install architecture independent files here.
22 #                           Default; C:\Boost on Win32
23 #                           Default; /usr/local on Unix. Linux, etc.
25 #   --exec-prefix=<EPREFIX> Install architecture dependent files here.
26 #                           Default; <PREFIX>
28 #   --libdir=<DIR>          Install library files here.
29 #                           Default; <EPREFIX>/lib
31 #   --includedir=<HDRDIR>   Install header files here.
32 #                           Default; <PREFIX>/include
34 #   stage                   Build and install only compiled library files
35 #   =====                   to the stage directory.
37 #   --stagedir=<STAGEDIR>   Install library files here
38 #                           Default; ./stage
40 # Other Options:
42 #   --build-type=<type>     Build the specified pre-defined set of variations
43 #                           of the libraries. Note, that which variants get
44 #                           built depends on what each library supports.
46 #                               minimal (default) - Builds the single
47 #                               "release" version of the libraries. This
48 #                               release corresponds to specifying:
49 #                               "release <threading>multi <link>shared
50 #                               <link>static <runtime-link>shared" as the
51 #                               Boost.Build variant to build.
53 #                               complete - Attempts to build all possible
54 #                               variations.
56 #   --build-dir=DIR         Build in this location instead of building
57 #                           within the distribution tree. Recommended!
59 #   --show-libraries        Displays the list of Boost libraries that require
60 #                           build and installation steps, then exit.
62 #   --layout=<layout>       Determines whether to choose library names
63 #                           and header locations such that multiple
64 #                           versions of Boost or multiple compilers can
65 #                           be used on the same system.
67 #                               versioned (default) - Names of boost
68 #                               binaries include the Boost version
69 #                               number and the name and version of the
70 #                               compiler.  Boost headers are installed
71 #                               in a subdirectory of <HDRDIR> whose
72 #                               name contains the Boost version
73 #                               number.
75 #                               system - Binaries names do not include
76 #                               the Boost version number or the name
77 #                               and version number of the compiler.
78 #                               Boost headers are installed directly
79 #                               into <HDRDIR>.  This option is
80 #                               intended for system integrators who
81 #                               are building distribution packages.
83 #   --buildid=ID            Adds the specified ID to the name of built
84 #                           libraries.  The default is to not add anything.
86 #   --help                  This message.
88 #   --with-<library>        Build and install the specified <library>
89 #                           If this option is used, only libraries
90 #                           specified using this option will be built.
92 #   --without-<library>     Do not build, stage, or install the specified
93 #                           <library>. By default, all libraries are built.
95 # Properties:
97 #   toolset=toolset         Indicates the toolset to build with.
99 #   variant=debug|release   Select the build variant
101 #   link=static|shared      Whether to build static or shared libraries
103 #   threading=single|multi  Whether to build single or multithreaded binaries
105 #   runtime-link=static|shared      
106 #                           Whether to link to static or shared C and C++ runtime.
107 #   
109 # TODO:
110 #  - handle boost version
111 #  - handle python options such as pydebug
113 import generate ;
114 import modules ;
115 import set ;
116 import stage ;
117 import package ;
118 import path ;
119 import common ;
120 import os ;
121 import regex ;
122 import errors ;
123 import "class" : new ;
124 import common ;
125 import sequence ;
126 import symlink ;
127 import targets ;
128 import project ;
130 path-constant BOOST_ROOT : . ;
131 constant BOOST_VERSION : 1.40.0 ;
132 constant BOOST_JAMROOT_MODULE : $(__name__) ;
134 local version-tag = [ MATCH "^([^.]+)[.]([^.]+)[.]([^.]+)" : $(BOOST_VERSION) ]
135     ;
136 if $(version-tag[3]) = 0
138     version-tag = $(version-tag[1-2]) ;
141 constant BOOST_VERSION_TAG : $(version-tag:J="_") ;
143 # Option to choose how many variants to build. The default is "minimal".
144 local build-type = [ MATCH "^--build-type=(.*)" : [ modules.peek : ARGV ] ] ;
145 build-type ?= minimal ;
146 if ! ( $(build-type) in minimal complete )
148     ECHO "The value of the --build-type option should be either 'complete' or 'minimal'" ;
149     EXIT ;
152 rule handle-static-runtime ( properties * )
154     # Using static runtime with shared libraries is impossible on Linux,
155     # and dangerous on Windows. Therefore, we disallow it. This might
156     # be drastic, but it was disabled for a while with nobody complaining.
158     # For CW, static runtime is needed so that std::locale works.
159     if <link>shared in $(properties) && <runtime-link>static in $(properties) &&
160         ! ( <toolset>cw in $(properties) )
161     {
162         ECHO "error: link=shared together with runtime-link=static is not allowed" ;
163         ECHO "error: such property combination is either impossible " ;
164         ECHO "error: or too dangerious to be of any use" ;
165         EXIT ;
166     }
170 project boost
171     : requirements <include>.
172       # Disable auto-linking for all targets here, primarily because it caused
173       # troubles with V2.
174       <define>BOOST_ALL_NO_LIB=1
175       # Used to encode variant in target name. See the 'tag' rule below.
176       <tag>@$(__name__).tag
177       <conditional>@handle-static-runtime
178       # The standard library Sun compilers use by default has no chance
179       # of working with Boost. Override it.
180       <toolset>sun:<stdlib>sun-stlport
181     : usage-requirements <include>.
182     : build-dir bin.v2
183     ;
186 # Setup convenient aliases for all libraries.
188 all-libraries = [ MATCH .*libs/(.*)/build/.* : [ glob libs/*/build/Jamfile.v2 ]
189     [ glob libs/*/build/Jamfile ] ]
190     ;
192 all-libraries = [ sequence.unique $(all-libraries) ] ;
193 # The function_types library has a Jamfile, but it's used for maintenance
194 # purposes, there's no library to build and install.
195 all-libraries = [ set.difference $(all-libraries) : function_types ] ;
198 local rule explicit-alias ( id : targets + )
200     alias $(id) : $(targets) ;
201     explicit $(id) ;
205 # First, the complicated libraries: where the target name in Jamfile is
206 # different from its directory name.
207 explicit-alias prg_exec_monitor : libs/test/build//boost_prg_exec_monitor ;
208 explicit-alias test_exec_monitor : libs/test/build//boost_test_exec_monitor ;
209 explicit-alias unit_test_framework : libs/test/build//boost_unit_test_framework ;
210 explicit-alias bgl-vis : libs/graps/build//bgl-vis ;
211 explicit-alias serialization : libs/serialization/build//boost_serialization ;
212 explicit-alias wserialization : libs/serialization/build//boost_wserialization ;
213 for local l in $(all-libraries)
215     if ! $(l) in test graph serialization
216     {
217         explicit-alias $(l) : libs/$(l)/build//boost_$(l) ;
218     }
221 alias headers : : : : <include>. ;
224 # Decides which libraries are to be installed by looking at --with-<library>
225 # --without-<library> arguments. Returns the list of directories under "libs"
226 # which must be built and installed.
228 rule libraries-to-install ( existing-libraries * )
230    local argv = [ modules.peek : ARGV ] ;
231    local with-parameter = [ MATCH --with-(.*) : $(argv) ] ;
232    local without-parameter = [ MATCH --without-(.*) : $(argv) ] ;
233    
234    if ! $(with-parameter) && ! $(without-parameter)
235    {
236        # Nothing is specified on command line. See if maybe
237        # project-config.jam has some choices. 
238        local project-config-libs = [ modules.peek project-config : libraries ] ;
239        with-parameter = [ MATCH --with-(.*) : $(project-config-libs) ] ;
240        without-parameter = [ MATCH --without-(.*) : $(project-config-libs) ] ;
241    }
243    # Do some checks.
244    if $(with-parameter) && $(without-parameter)
245    {
246        ECHO "error: both --with-<library> and --without-<library> specified" ;
247        EXIT ;
248    }
250    local wrong = [ set.difference $(with-parameter) : $(existing-libraries) ] ;
251    if $(wrong)
252    {
253        ECHO "error: wrong library name '$(wrong[1])' in the --with-<library> option." ;
254        EXIT ;
255    }
256    local wrong = [ set.difference $(without-parameter) : $(existing-libraries) ] ;
257    if $(wrong)
258    {
259        ECHO "error: wrong library name '$(wrong[1])' in the --without-<library> option." ;
260        EXIT ;
261    }
263    if $(with-parameter)
264    {
265        return [ set.intersection $(existing-libraries) : $(with-parameter) ] ;
266    }
267    else
268    {
269        return [ set.difference $(existing-libraries) : $(without-parameter) ] ;
270    }
274 # What kind of layout are we doing?
275 layout = [ MATCH "^--layout=(.*)" : [ modules.peek : ARGV ] ] ;
276 layout ?= versioned ;
277 layout-$(layout) = true ;
280 # Possible stage only location.
281 local stage-locate = [ MATCH "^--stagedir=(.*)" : [ modules.peek : ARGV ] ] ;
282 stage-locate ?= stage ;
283 path-constant BOOST_STAGE_LOCATE : $(stage-locate) ;
286 # Python location.
287 local python-root = [ MATCH "^--with-python-root=(.*)" : [ modules.peek : ARGV ]
288     ] ;
289 PYTHON_ROOT ?= $(python-root) ;
292 # Select the libraries to install.
293 libraries = [ libraries-to-install $(all-libraries) ] ;
295 if --show-libraries in [ modules.peek : ARGV ]
297     ECHO "The following libraries require building:" ;
298     for local l in $(libraries)
299     {
300         ECHO "    - $(l)" ;
301     }
302     EXIT ;
305 # Custom build ID.
306 local build-id = [ MATCH "^--buildid=(.*)" : [ modules.peek : ARGV ] ] ;
307 if $(build-id)
309     constant BUILD_ID : [ regex.replace $(build-id) "[*\\/:.\"\' ]" "_" ] ;
313 # This rule is called by Boost.Build to determine the name of target. We use it
314 # to encode the build variant, compiler name and boost version in the target
315 # name.
317 rule tag ( name : type ? : property-set )
319     if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
320     {
321         if $(layout) = versioned
322         {
323             local result = [ common.format-name
324                 <base> <toolset> <threading> <runtime> -$(BOOST_VERSION_TAG)
325                 -$(BUILD_ID)
326                 : $(name) : $(type) : $(property-set) ] ;
328             # Optionally add version suffix. On NT, library with version suffix
329             # will not be recognized by linkers. On CYGWIN, we get strage
330             # duplicate symbol errors when library is generated with version
331             # suffix. On OSX, version suffix is not needed -- the linker expects
332             # the libFoo.1.2.3.dylib format. AIX linkers do not accept version
333             # suffixes either. Pgi compilers can not accept library with version
334             # suffix.
335             if $(type) = SHARED_LIB &&
336               ( ! ( [ $(property-set).get <target-os> ] in windows cygwin darwin aix ) &&
337                 ! ( [ $(property-set).get <toolset> ] in pgi ) )
338             {
339                 result = $(result).$(BOOST_VERSION)  ;
340             }
342             return $(result) ;
343         }
344         else
345         {
346             local result = [ common.format-name
347                 <base> 
348                 -$(BUILD_ID)
349                 : $(name) : $(type) : $(property-set) ] ;
351             # Optionally add version suffix. On NT, library with version suffix
352             # will not be recognized by linkers. On CYGWIN, we get strage
353             # duplicate symbol errors when library is generated with version
354             # suffix. On OSX, version suffix is not needed -- the linker expects
355             # the libFoo.1.2.3.dylib format. AIX linkers do not accept version
356             # suffixes either. Pgi compilers can not accept library with version
357             # suffix.
358             if $(type) = SHARED_LIB &&
359               ( ! ( [ $(property-set).get <target-os> ] in windows cygwin darwin aix ) &&
360                 ! ( [ $(property-set).get <toolset> ] in pgi ) )
361             {
362                 result = $(result).$(BOOST_VERSION)  ;
363             }
365             return $(result) ;
366         }
367     }
371 # Install to system location.
373 install-requirements = <install-source-root>$(BOOST_ROOT)/boost ;
375 if $(layout-versioned)
377     install-requirements += <install-header-subdir>boost-$(BOOST_VERSION_TAG)/boost ;
379 else
381     install-requirements += <install-header-subdir>boost ;
383 if [ modules.peek : NT ]
385     install-requirements += <install-default-prefix>C:/Boost ;
387 else if [ modules.peek : UNIX ]
389     install-requirements += <install-default-prefix>/usr/local ;
392 local headers =
393     # The .SUNWCCh files are present in tr1 include directory and have to be installed,
394     # see http://lists.boost.org/Archives/boost/2007/05/121430.php
395     [ path.glob-tree $(BOOST_ROOT)/boost : *.hpp *.ipp *.h *.inc *.SUNWCCh : CVS .svn ]
396     [ path.glob-tree $(BOOST_ROOT)/boost/compatibility/cpp_c_headers : c* : CVS .svn ] 
397     [ path.glob boost/tr1/tr1 : * : bcc32 sun CVS .svn ]
398           ;
400 # Complete install.
401 package.install install-proper
402     : $(install-requirements) <install-no-version-symlinks>on
403     :
404     : libs/$(libraries)/build
405     : $(headers)
406     ;
407 explicit install-proper ;
409 # Install just library.
410 install stage-proper
411     : libs/$(libraries)/build
412     : <location>$(stage-locate)/lib
413       <install-dependencies>on <install-type>LIB
414       <install-no-version-symlinks>on
415     ;
416 explicit stage-proper ;
419 if $(layout-versioned) && ( [ modules.peek : NT ] || [ modules.peek : UNIX ] )
421     rule make-unversioned-links ( project name ? : property-set : sources * )
422     {
423         local result ;
424         local filtered ;
425         local pattern ;
426         local nt = [ modules.peek : NT ] ;
428         # Collect the libraries that have the version number in 'filtered'.
429         for local s in $(sources)
430         {
431             local m ;
432             if $(nt)
433             {
434                 m = [ MATCH "(.*[.]lib)" : [ $(s).name ] ] ;
435             }
436             else
437             {
438                 m = [ MATCH "(.*[.]so[.0-9]+)" "(.*[.]dylib)" "(.*[.]a)" :
439                     [ $(s).name ] ] ;
440             }
441             if $(m)
442             {
443                 filtered += $(s) ;
444             }
445         }
447         # Create links without version.
448         for local s in $(filtered)
449         {
450             local name = [ $(s).name ] ;
451             local ea = [ $(s).action ] ;
452             local ep = [ $(ea).properties ] ;
453             local a  = [ new non-scanning-action $(s) : symlink.ln : $(ep) ] ;
455             local noversion-file ;
456             if $(nt)
457             {
458                 noversion-file = [ MATCH "(.*)-[0-9_]+(.*[.]lib)" : $(name) ] ;
459             }
460             else
461             {
462                 noversion-file =
463                   [ MATCH "(.*)-[0-9_]+(.*[.]so)[.0-9]*" : $(name) ]
464                   [ MATCH "(.*)-[0-9_]+(.*[.]dylib)" : $(name) ]
465                   [ MATCH "(.*)-[0-9_]+(.*[.]a)" : $(name) ]
466                   [ MATCH "(.*)-[0-9_]+(.*[.]dll[.]a)" : $(name) ] ;
467             }
469             local new-name =
470                $(noversion-file[1])$(noversion-file[2]) ;
471             result += [ new file-target $(new-name) exact : [ $(s).type ] : $(project)
472                     : $(a) ] ;
474         }
475         return $(result) ;
476     }
478     generate stage-unversioned : stage-proper :
479         <generating-rule>@make-unversioned-links ;
480     explicit stage-unversioned ;
482     generate install-unversioned : install-proper :
483         <generating-rule>@make-unversioned-links ;
484     explicit install-unversioned ;
486 else
488     # Create do-nothing aliases.
489     alias stage-unversioned ;
490     explicit stage-unversioned ;
491     alias install-unversioned ;
492     explicit install-unversioned ;
495 # This is a special metatarget class that handles the --build-type=complete
496 # option.
497 class top-level-target : alias-target-class
499     import modules ;
500     import errors ; 
501     
502     rule __init__ ( name : project : sources * : requirements *
503         : default-build * : usage-requirements * )
504     {
505         alias-target-class.__init__ $(name) : $(project) : $(sources) :
506             $(requirements) : $(default-build) : $(usage-requirements) ;
507         
508         local m = [ $(project).project-module ] ;
509         self.build-type = [ modules.peek $(m) : build-type ] ;
510         # On Linux, we build release variant by default, since few users will
511         # ever want to debug C++ Boost libraries, and there's no ABI
512         # incompatibility between debug and release variants. We build
513         # shared and static libraries since that's what most packages
514         # seem to provide (.so in libfoo and .a in libfoo-dev).
515         self.minimal-properties = [ property-set.create 
516             <variant>release <threading>multi <link>shared <link>static <runtime-link>shared ] ;
517         # On Windows, new IDE projects use:
518         #
519         #   runtime-link=dynamic, threading=multi, variant=(debug|release)
520         #
521         # and in addition, C++ Boost's autolink defaults to static linking.
522         self.minimal-properties-win = [ property-set.create 
523             <variant>debug <variant>release <threading>multi <link>static <runtime-link>shared ] ;
525         self.complete-properties = [ property-set.create
526             <variant>debug <variant>release
527             <threading>single <threading>multi
528             <link>shared <link>static
529             <runtime-link>shared <runtime-link>static ] ;
530     }
531     
532     rule generate ( property-set )
533     {
534         if $(self.build-type) = minimal
535         {
536             local expanded ;
537             
538             local os = [ $(property-set).get <target-os> ] ;
539             # Because we completely override parent's 'generate'
540             # we need to check for default value of feature ourself.
541             if ! $(os)
542             {
543                 os = [ feature.defaults <target-os> ] ;
544                 os = $(os:G=) ;
545             }
546             
547             if $(os) = windows
548             {                
549                 expanded = [ targets.apply-default-build $(property-set)
550                   : $(self.minimal-properties-win) ] ;
551             }
552             else
553             {
554                 expanded = [ targets.apply-default-build $(property-set)
555                   : $(self.minimal-properties) ] ;
556             }            
557             return [ build-multiple $(expanded) ] ;
558         }
559         else if $(self.build-type) = complete
560         {                                    
561             local expanded = [ targets.apply-default-build $(property-set)
562               : $(self.complete-properties) ] ;
563             
564             # Filter inappopriate combinations
565             local filtered ;
566             for local p in $(expanded)
567             {
568                 # See comment in handle-static-runtime regarding this logic.
569                 if [ $(p).get <link> ] = shared && [ $(p).get <runtime-link> ] = static
570                    && [ $(p).get <toolset> ] != cw
571                 {
572                     # Skip this
573                 }
574                 else
575                 {
576                     filtered += $(p) ;
577                 }
578             }            
579             return [ build-multiple $(filtered) ] ;            
580         }
581         else
582         {
583             errors.error "Unknown build type" ; 
584         }               
585     }
586     
587     rule build-multiple ( property-sets * )
588     {
589         local usage-requirements = [ property-set.empty ] ;
590         local result ;
591         for local p in $(property-sets)
592         {
593             local r = [ alias-target-class.generate $(p) ] ;
594             if $(r)
595             {
596                 usage-requirements = [ $(usage-requirements).add $(r[1]) ] ;
597                 result += $(r[2-]) ;
598             }
599         }
600         return $(usage-requirements) [ sequence.unique $(result) ] ;
601     }
602     
605 targets.create-metatarget top-level-target : [ project.current ]
606   : install
607   : install-proper install-unversioned 
608   ;
609 targets.create-metatarget top-level-target : [ project.current ]
610   : stage
611   : stage-proper stage-unversioned 
612   ;
614 explicit install ;
615 explicit stage ;
617 stage-abs = [ path.native [ path.root $(stage-locate)/lib [ path.pwd ] ] ] ;
619 # This target is built by default, and will forward to 'stage'
620 # after producing some explanations.
621 targets.create-metatarget top-level-target : [ project.current ]
622   : forward
623   : explain stage
624   ;
627 message explain :
628 "\nBuilding C++ Boost.
630 After the build, the headers will be located at
631   
632     $(BOOST_ROOT)
633     
634 The libraries will be located at  
635     
636     $(stage-abs)
637      
638 Use 'bjam install --prefix=<path>' if you wish to install headers and 
639 libraries to a different location and remove the source tree.\n\n"
640   ;
643 # Just build the libraries, don't install them anywhere. This is what happens
644 # with just "bjam --v2".
645 alias build_all : libs/$(libraries)/build ;
648 # This rule should be called from libraries' Jamfiles and will create two
649 # targets, "install" and "stage", that will install or stage that library. The
650 # --prefix option is respected, but --with and --without options, naturally, are
651 # ignored.
653 # - libraries -- list of library targets to install.
655 rule boost-install ( libraries * )
657     package.install install
658         : <dependency>/boost//install-proper-headers $(install-requirements)
659         : # No binaries
660         : $(libraries)
661         : # No headers, it is handled by the dependency.
662     ;
664     install stage : $(libraries) : <location>$(BOOST_STAGE_LOCATE) ;
666     local c = [ project.current ] ;
667     local project-module = [ $(c).project-module ] ;
668     module $(project-module)
669     {
670         explicit stage ;
671         explicit install ;
672     }
676 # Make project ids of all libraries known.
677 for local l in $(all-libraries)
679     use-project /boost/$(l) : libs/$(l)/build ;