1 # Copyright 2002, 2003, 2004, 2005 Dave Abrahams
2 # Copyright 2002, 2005, 2006, 2007, 2010 Rene Rivera
3 # Copyright 2006 Juergen Hunold
4 # Copyright 2005 Toon Knapen
5 # Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus
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 # Defines standard features and rules.
13 import "class" : new ;
31 import types/register ;
33 import virtual-target ;
37 # FIXME: the following generate module import is not needed here but removing it
38 # too hastily will break using code (e.g. the main Boost library Jamroot file)
39 # that forgot to import the generate module before calling the generate rule.
43 .os-names = aix android appletv bsd cygwin darwin freebsd haiku hpux iphone linux netbsd
44 openbsd osf qnx qnxnto sgi solaris unix unixware windows vms
45 elf # Not actually an OS -- used for targeting bare metal where object
46 # format is ELF. This catches both -elf and -eabi gcc targets and well
47 # as other compilers targeting ELF. It is not clear how often we need
48 # the 'elf' key as opposed to other bare metal targets, but let us
49 # stick with gcc naming.
52 # Feature used to determine which OS we're on. New <target-os> and <host-os>
53 # features should be used instead.
54 local os = [ modules.peek : OS ] ;
55 feature.feature os : $(os) : propagated link-incompatible ;
58 # Translates from bjam current OS to the os tags used in host-os and target-os,
59 # i.e. returns the running host-os.
61 local rule default-host-os ( )
64 if [ os.name ] in $(.os-names:U)
66 host-os = [ os.name ] ;
72 case NT : host-os = windows ;
73 case AS400 : host-os = unix ;
74 case MINGW : host-os = windows ;
75 case BSDI : host-os = bsd ;
76 case COHERENT : host-os = unix ;
77 case DRAGONFLYBSD : host-os = bsd ;
78 case IRIX : host-os = sgi ;
79 case HAIKU : host-os = haiku ;
80 case MACOSX : host-os = darwin ;
81 case KFREEBSD : host-os = freebsd ;
82 case LINUX : host-os = linux ;
83 case VMS : host-os = vms ;
85 ECHO "SunOS is not a supported operating system." ;
86 ECHO "We believe last version of SunOS was released in 1992, " ;
87 ECHO "so if you get this message, something is very wrong with configuration logic. " ;
88 ECHO "Please report this as a bug. " ;
90 case * : host-os = unix ;
97 # The two OS features define a known set of abstract OS names. The host-os is
98 # the OS under which bjam is running. Even though this should really be a fixed
99 # property we need to list all the values to prevent unknown value errors. Both
100 # set the default value to the current OS to account for the default use case of
101 # building on the target OS.
102 feature.feature host-os : $(.os-names) ;
103 feature.set-default host-os : [ default-host-os ] ;
105 feature.feature target-os : $(.os-names) : propagated link-incompatible ;
106 feature.set-default target-os : [ default-host-os ] ;
109 feature.feature toolset : : implicit propagated symmetric ;
110 feature.feature stdlib : native : propagated composite ;
111 feature.feature link : shared static : propagated ;
112 feature.feature runtime-link : shared static : propagated ;
113 feature.feature runtime-debugging : on off : propagated ;
114 feature.feature optimization : off speed space : propagated ;
115 feature.feature profiling : off on : propagated ;
116 feature.feature inlining : off on full : propagated ;
117 feature.feature threading : single multi : propagated ;
118 feature.feature rtti : on off : propagated ;
119 feature.feature exception-handling : on off : propagated ;
121 # Whether there is support for asynchronous EH (e.g. catching SEGVs).
122 feature.feature asynch-exceptions : off on : propagated ;
124 # Whether all extern "C" functions are considered nothrow by default.
125 feature.feature extern-c-nothrow : off on : propagated ;
127 feature.feature debug-symbols : on off : propagated ;
128 # Controls whether the binary should be stripped -- that is have
129 # everything not necessary to running removed. This option should
130 # not be very often needed. Also, this feature will show up in
131 # target paths of everything, not just binaries. Should fix that
132 # when implementing feature relevance.
133 feature.feature strip : off on : propagated ;
134 feature.feature define : : free ;
135 feature.feature undef : : free ;
136 feature.feature "include" : : free path ; #order-sensitive ;
137 feature.feature cflags : : free ;
138 feature.feature cxxflags : : free ;
139 feature.feature fflags : : free ;
140 feature.feature asmflags : : free ;
141 feature.feature linkflags : : free ;
142 feature.feature archiveflags : : free ;
143 feature.feature version : : free ;
144 feature.feature mflags : : free ;
145 feature.feature mmflags : : free ;
147 # Generic, i.e. non-language specific, flags for tools.
148 feature.feature flags : : free ;
149 feature.feature location-prefix : : free ;
152 # The following features are incidental since they have no effect on built
153 # products. Not making them incidental will result in problems in corner cases,
156 # unit-test a : a.cpp : <use>b ;
159 # Here, if <use> is not incidental, we would decide we have two targets for
160 # a.obj with different properties and complain about it.
162 # Note that making a feature incidental does not mean it is ignored. It may be
163 # ignored when creating a virtual target, but the rest of build process will use
165 feature.feature use : : free dependency incidental ;
166 feature.feature dependency : : free dependency incidental ;
167 feature.feature implicit-dependency : : free dependency incidental ;
169 feature.feature warnings :
170 on # Enable default/"reasonable" warning level for the tool.
171 all # Enable all possible warnings issued by the tool.
172 off # Disable all warnings issued by the tool.
173 : incidental propagated ;
175 feature.feature warnings-as-errors :
176 off # Do not fail the compilation if there are warnings.
177 on # Fail the compilation if there are warnings.
178 : incidental propagated ;
180 # Feature that allows us to configure the maximal template instantiation depth
181 # level allowed by a C++ compiler. Applies only to C++ toolsets whose compilers
182 # actually support this configuration setting.
184 # Note that Boost Build currently does not allow defining features that take any
185 # positive integral value as a parameter, which is what we need here, so we just
186 # define some of the values here and leave it up to the user to extend this set
187 # as he needs using the feature.extend rule.
189 # TODO: This should be upgraded as soon as Boost Build adds support for custom
190 # validated feature values or at least features allowing any positive integral
191 # value. See related Boost Build related trac ticket #194.
193 feature.feature c++-template-depth
195 [ numbers.range 64 1024 : 64 ]
196 [ numbers.range 20 1000 : 10 ]
197 # Maximum template instantiation depth guaranteed for ANSI/ISO C++
198 # conforming programs.
201 incidental optional propagated ;
203 feature.feature source : : free dependency incidental ;
204 feature.feature library : : free dependency incidental ;
205 feature.feature file : : free dependency incidental ;
206 feature.feature find-shared-library : : free ; #order-sensitive ;
207 feature.feature find-static-library : : free ; #order-sensitive ;
208 feature.feature library-path : : free path ; #order-sensitive ;
211 feature.feature library-file : : free dependency ;
213 feature.feature name : : free ;
214 feature.feature tag : : free ;
215 feature.feature search : : free path ; #order-sensitive ;
216 feature.feature location : : free path ;
217 feature.feature dll-path : : free path ;
218 feature.feature hardcode-dll-paths : true false : incidental ;
221 # An internal feature that holds the paths of all dependency shared libraries.
222 # On Windows, it is needed so that we can add all those paths to PATH when
223 # running applications. On Linux, it is needed to add proper -rpath-link command
225 feature.feature xdll-path : : free path ;
227 # Provides means to specify def-file for windows DLLs.
228 feature.feature def-file : : free dependency ;
230 feature.feature suppress-import-lib : false true : incidental ;
232 # Internal feature used to store the name of a bjam action to call when building
234 feature.feature action : : free ;
236 # This feature is used to allow specific generators to run. For example, QT
237 # tools can only be invoked when QT library is used. In that case, <allow>qt
238 # will be in usage requirement of the library.
239 feature.feature allow : : free ;
241 # The addressing model to generate code for. Currently a limited set only
242 # specifying the bit size of pointers.
243 feature.feature address-model : 16 32 64 32_64 : propagated optional ;
245 # Type of CPU architecture to compile for.
246 feature.feature architecture :
260 mips1 mips2 mips3 mips4 mips32 mips32r2 mips64
265 # Advanced RISC Machines
268 # Combined architectures for platforms/toolsets that support building for
269 # multiple architectures at once. "combined" would be the default multi-arch
274 : propagated optional ;
276 # The specific instruction set in an architecture to compile.
277 feature.feature instruction-set :
279 native i486 i586 i686 pentium pentium-mmx pentiumpro pentium2 pentium3
280 pentium3m pentium-m pentium4 pentium4m prescott nocona core2 corei7 corei7-avx core-avx-i
281 conroe conroe-xe conroe-l allendale merom merom-xe kentsfield kentsfield-xe penryn wolfdale
282 yorksfield nehalem sandy-bridge ivy-bridge haswell k6 k6-2 k6-3 athlon athlon-tbird athlon-4 athlon-xp
283 athlon-mp k8 opteron athlon64 athlon-fx k8-sse3 opteron-sse3 athlon64-sse3 amdfam10 barcelona
284 bdver1 bdver2 bdver3 btver1 btver2 winchip-c6 winchip2 c3 c3-2 atom
287 itanium itanium1 merced itanium2 mckinley
290 v7 cypress v8 supersparc sparclite hypersparc sparclite86x f930 f934
291 sparclet tsc701 v9 ultrasparc ultrasparc3
294 401 403 405 405fp 440 440fp 505 601 602 603 603e 604 604e 620 630 740 7400
295 7450 750 801 821 823 860 970 8540 power-common ec603e g3 g4 g5 power power2
296 power3 power4 power5 powerpc powerpc64 rios rios1 rsc rios2 rs64a
299 4kc 4kp 5kc 20kc m4k r2000 r3000 r3900 r4000 r4100 r4300 r4400 r4600 r4650
300 r6000 r8000 rm7000 rm9000 orion sb1 vr4100 vr4111 vr4120 vr4130 vr4300
304 700 7100 7100lc 7200 7300 8000
306 # Advanced RISC Machines
307 armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5t armv5te armv6 armv6j iwmmxt ep9312
310 : propagated optional ;
312 # Used to select a specific variant of C++ ABI if the compiler supports several.
313 feature.feature c++abi : : propagated optional ;
315 feature.feature conditional : : incidental free ;
317 # The value of 'no' prevents building of a target.
318 feature.feature build : yes no : optional ;
320 # Windows-specific features
322 feature.feature user-interface : console gui wince native auto ;
324 feature.feature variant : : implicit composite propagated symmetric ;
327 # Declares a new variant.
329 # First determines explicit properties for this variant, by refining parents'
330 # explicit properties with the passed explicit properties. The result is
331 # remembered and will be used if this variant is used as parent.
333 # Second, determines the full property set for this variant by adding to the
334 # explicit properties default values for all missing non-symmetric properties.
336 # Lastly, makes appropriate value of 'variant' property expand to the full
339 rule variant ( name # Name of the variant
340 : parents-or-properties * # Specifies parent variants, if
341 # 'explicit-properties' are given, and
342 # explicit-properties or parents otherwise.
343 : explicit-properties * # Explicit properties.
347 if ! $(explicit-properties)
349 if $(parents-or-properties[1]:G)
351 explicit-properties = $(parents-or-properties) ;
355 parents = $(parents-or-properties) ;
360 parents = $(parents-or-properties) ;
363 # The problem is that we have to check for conflicts between base variants.
366 errors.error "multiple base variants are not yet supported" ;
370 # Add explicitly specified properties for parents.
371 for local p in $(parents)
373 # TODO: This check may be made stricter.
374 if ! [ feature.is-implicit-value $(p) ]
376 errors.error "Invalid base variant" $(p) ;
379 inherited += $(.explicit-properties.$(p)) ;
381 property.validate $(explicit-properties) ;
382 explicit-properties = [ property.refine $(inherited)
383 : $(explicit-properties) ] ;
385 # Record explicitly specified properties for this variant. We do this after
386 # inheriting parents' properties so they affect other variants derived from
388 .explicit-properties.$(name) = $(explicit-properties) ;
390 feature.extend variant : $(name) ;
391 feature.compose <variant>$(name) : $(explicit-properties) ;
393 IMPORT $(__name__) : variant : : variant ;
396 variant debug : <optimization>off <debug-symbols>on <inlining>off
397 <runtime-debugging>on ;
398 variant release : <optimization>speed <debug-symbols>off <inlining>full
399 <runtime-debugging>off <define>NDEBUG ;
400 variant profile : release : <profiling>on <debug-symbols>on ;
403 class searched-lib-target : abstract-file-target
412 abstract-file-target.__init__ $(name) : SEARCHED_LIB : $(project)
415 self.shared = $(shared) ;
416 self.search = $(search) ;
421 return $(self.shared) ;
426 return $(self.search) ;
429 rule actualize-location ( target )
440 # The generator class for libraries (target type LIB). Depending on properties
441 # it will request building of the appropriate specific library type --
442 # -- SHARED_LIB, STATIC_LIB or SHARED_LIB.
444 class lib-generator : generator
446 rule __init__ ( * : * )
448 generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8)
449 : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) :
450 $(17) : $(18) : $(19) ;
453 rule run ( project name ? : property-set : sources * )
455 # The lib generator is composing, and can be only invoked with an
456 # explicit name. This check is present in generator.run (and so in
457 # builtin.linking-generator) but duplicated here to avoid doing extra
461 local properties = [ $(property-set).raw ] ;
462 # Determine the needed target type.
464 # <source>files can be generated by <conditional>@rule feature
465 # in which case we do not consider it a SEARCHED_LIB type.
466 if ! <source> in $(properties:G) &&
467 ( <search> in $(properties:G) || <name> in $(properties:G) )
469 actual-type = SEARCHED_LIB ;
471 else if <file> in $(properties:G)
475 else if <link>shared in $(properties)
477 actual-type = SHARED_LIB ;
481 actual-type = STATIC_LIB ;
483 property-set = [ $(property-set).add-raw <main-target-type>LIB ] ;
484 # Construct the target.
485 return [ generators.construct $(project) $(name) : $(actual-type)
486 : $(property-set) : $(sources) ] ;
490 rule viable-source-types ( )
497 generators.register [ new lib-generator builtin.lib-generator : : LIB ] ;
500 # The implementation of the 'lib' rule. Beyond standard syntax that rule allows
501 # simplified: "lib a b c ;".
503 rule lib ( names + : sources * : requirements * : default-build * :
504 usage-requirements * )
508 if <name> in $(requirements:G)
510 errors.user-error "When several names are given to the 'lib' rule" :
511 "it is not allowed to specify the <name> feature." ;
515 errors.user-error "When several names are given to the 'lib' rule" :
516 "it is not allowed to specify sources." ;
520 # This is a circular module dependency so it must be imported here.
523 local project = [ project.current ] ;
526 for local name in $(names)
528 local r = $(requirements) ;
529 # Support " lib a ; " and " lib a b c ; " syntax.
530 if ! $(sources) && ! <name> in $(requirements:G)
531 && ! <file> in $(requirements:G)
535 result += [ targets.main-target-alternative
536 [ new typed-target $(name) : $(project) : LIB
537 : [ targets.main-target-sources $(sources) : $(name) ]
538 : [ targets.main-target-requirements $(r) : $(project) ]
539 : [ targets.main-target-default-build $(default-build) : $(project) ]
540 : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
545 IMPORT $(__name__) : lib : : lib ;
548 class searched-lib-generator : generator
550 import property-set ;
554 # The requirements cause the generators to be tried *only* when we are
555 # building a lib target with a 'search' feature. This seems ugly --- all
556 # we want is to make sure searched-lib-generator is not invoked deep
557 # inside transformation search to produce intermediate targets.
558 generator.__init__ searched-lib-generator : : SEARCHED_LIB ;
561 rule run ( project name ? : property-set : sources * )
565 # If 'name' is empty, it means we have not been called to build a
566 # top-level target. In this case, we just fail immediately, because
567 # searched-lib-generator cannot be used to produce intermediate
570 local properties = [ $(property-set).raw ] ;
572 if <link>shared in $(properties)
577 local search = [ feature.get-values <search> : $(properties) ] ;
579 local a = [ new null-action $(property-set) ] ;
580 local lib-name = [ feature.get-values <name> : $(properties) ] ;
581 lib-name ?= $(name) ;
582 local t = [ new searched-lib-target $(lib-name) : $(project)
583 : $(shared) : $(search) : $(a) ] ;
584 # We return sources for a simple reason. If there is
585 # lib png : z : <name>png ;
586 # the 'z' target should be returned, so that apps linking to 'png'
587 # will link to 'z', too.
588 return [ property-set.create <xdll-path>$(search) ]
589 [ virtual-target.register $(t) ] $(sources) ;
594 generators.register [ new searched-lib-generator ] ;
597 class prebuilt-lib-generator : generator
599 rule __init__ ( * : * )
601 generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8)
602 : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) :
603 $(17) : $(18) : $(19) ;
606 rule run ( project name ? : property-set : sources * )
608 local f = [ $(property-set).get <file> ] ;
609 return $(f) $(sources) ;
614 [ new prebuilt-lib-generator builtin.prebuilt : : LIB : <file> ] ;
616 generators.override builtin.prebuilt : builtin.lib-generator ;
618 class preprocessed-target-class : basic-target
621 rule construct ( name : sources * : property-set )
623 local result = [ generators.construct [ project ]
624 $(name) : PREPROCESSED_CPP : $(property-set) : $(sources) ] ;
627 result = [ generators.construct [ project ]
628 $(name) : PREPROCESSED_C : $(property-set) : $(sources) ] ;
637 local p = [ project ] ;
639 "In project" [ $(p).name ] :
640 "Could not construct preprocessed file \"$(name)\" from $(s:J=, )." ;
646 rule preprocessed ( name : sources * : requirements * : default-build * :
647 usage-requirements * )
649 local project = [ project.current ] ;
650 return [ targets.main-target-alternative
651 [ new preprocessed-target-class $(name) : $(project)
652 : [ targets.main-target-sources $(sources) : $(name) ]
653 : [ targets.main-target-requirements $(requirements) : $(project) ]
654 : [ targets.main-target-default-build $(default-build) : $(project) ]
655 : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
659 IMPORT $(__name__) : preprocessed : : preprocessed ;
661 class compile-action : action
665 rule __init__ ( targets * : sources * : action-name : properties * )
667 action.__init__ $(targets) : $(sources) : $(action-name) : $(properties) ;
670 # For all virtual targets for the same dependency graph as self, i.e. which
671 # belong to the same main target, add their directories to the include path.
673 rule adjust-properties ( property-set )
675 local s = [ $(self.targets[1]).creating-subvariant ] ;
678 return [ $(property-set).add-raw
679 [ $(s).implicit-includes "include" : H ] ] ;
683 return $(property-set) ;
689 # Declare a special compiler generator. The only thing it does is changing the
690 # type used to represent 'action' in the constructed dependency graph to
691 # 'compile-action'. That class in turn adds additional include paths to handle
692 # cases when a source file includes headers which are generated themselves.
694 class C-compiling-generator : generator
696 rule __init__ ( id : source-types + : target-types + : requirements *
697 : optional-properties * )
699 generator.__init__ $(id) : $(source-types) : $(target-types) :
700 $(requirements) : $(optional-properties) ;
703 rule action-class ( )
705 return compile-action ;
710 rule register-c-compiler ( id : source-types + : target-types + : requirements *
711 : optional-properties * )
713 generators.register [ new C-compiling-generator $(id) : $(source-types) :
714 $(target-types) : $(requirements) : $(optional-properties) ] ;
717 # FIXME: this is ugly, should find a better way (we would like client code to
718 # register all generators as "generators.some-rule" instead of
719 # "some-module.some-rule".)
721 IMPORT $(__name__) : register-c-compiler : : generators.register-c-compiler ;
724 # The generator class for handling EXE and SHARED_LIB creation.
726 class linking-generator : generator
730 import property-set ;
734 composing ? : # The generator will be composing if a non-empty
735 # string is passed or the parameter is not given. To
736 # make the generator non-composing, pass an empty
743 generator.__init__ $(id) $(composing) : $(source-types)
744 : $(target-types) : $(requirements) ;
747 rule run ( project name ? : property-set : sources + )
749 sources += [ $(property-set).get <library> ] ;
751 # Add <library-path> properties for all searched libraries.
753 for local s in $(sources)
755 if [ $(s).type ] = SEARCHED_LIB
757 local search = [ $(s).search ] ;
758 extra += <library-path>$(search) ;
762 # It is possible that sources include shared libraries that did not came
763 # from 'lib' targets, e.g. .so files specified as sources. In this case
764 # we have to add extra dll-path properties and propagate extra xdll-path
765 # properties so that application linking to us will get xdll-path to
767 local extra-xdll-paths ;
768 for local s in $(sources)
770 if [ type.is-derived [ $(s).type ] SHARED_LIB ] && ! [ $(s).action ]
772 # Unfortunately, we do not have a good way to find the path to a
773 # file, so use this nasty approach.
775 # TODO: This needs to be done better. One thing that is really
776 # broken with this is that it does not work correctly with
777 # projects having multiple source locations.
778 local p = [ $(s).project ] ;
779 local location = [ path.root [ $(s).name ]
780 [ $(p).get source-location ] ] ;
781 extra-xdll-paths += [ path.parent $(location) ] ;
785 # Hardcode DLL paths only when linking executables.
786 # Pros: do not need to relink libraries when installing.
787 # Cons: "standalone" libraries (plugins, python extensions) can not
788 # hardcode paths to dependent libraries.
789 if [ $(property-set).get <hardcode-dll-paths> ] = true
790 && [ type.is-derived $(self.target-types[1]) EXE ]
792 local xdll-path = [ $(property-set).get <xdll-path> ] ;
793 extra += <dll-path>$(xdll-path) <dll-path>$(extra-xdll-paths) ;
798 property-set = [ $(property-set).add-raw $(extra) ] ;
801 local result = [ generator.run $(project) $(name) : $(property-set)
807 ur = [ extra-usage-requirements $(result) : $(property-set) ] ;
809 [ property-set.create <xdll-path>$(extra-xdll-paths) ] ] ;
811 return $(ur) $(result) ;
814 rule extra-usage-requirements ( created-targets * : property-set )
816 local result = [ property-set.empty ] ;
819 # Add appropriate <xdll-path> usage requirements.
820 local raw = [ $(property-set).raw ] ;
821 if <link>shared in $(raw)
824 local pwd = [ path.pwd ] ;
825 for local t in $(created-targets)
827 if [ type.is-derived [ $(t).type ] SHARED_LIB ]
829 paths += [ path.root [ path.make [ $(t).path ] ] $(pwd) ] ;
832 extra += $(paths:G=<xdll-path>) ;
835 # We need to pass <xdll-path> features that we've got from sources,
836 # because if a shared library is built, exe using it needs to know paths
837 # to other shared libraries this one depends on in order to be able to
838 # find them all at runtime.
840 # Just pass all features in property-set, it is theoretically possible
841 # that we will propagate <xdll-path> features explicitly specified by
842 # the user, but then the user is to blame for using an internal feature.
843 local values = [ $(property-set).get <xdll-path> ] ;
844 extra += $(values:G=<xdll-path>) ;
848 result = [ property-set.create $(extra) ] ;
853 rule generated-targets ( sources + : property-set : project name ? )
855 local sources2 ; # Sources to pass to inherited rule.
856 local properties2 ; # Properties to pass to inherited rule.
857 local libraries ; # Library sources.
859 # Searched libraries are not passed as arguments to the linker but via
860 # some option. So, we pass them to the action using a property.
861 properties2 = [ $(property-set).raw ] ;
864 for local s in $(sources)
866 if [ type.is-derived [ $(s).type ] SEARCHED_LIB ]
868 local name = [ $(s).name ] ;
883 properties2 += <find-shared-library>$(fsa:J=&&)
884 <find-static-library>$(fst:J=&&) ;
886 return [ generator.generated-targets $(sources2)
887 : [ property-set.create $(properties2) ] : $(project) $(name) ] ;
892 rule register-linker ( id composing ? : source-types + : target-types +
895 generators.register [ new linking-generator $(id) $(composing)
896 : $(source-types) : $(target-types) : $(requirements) ] ;
900 # The generator class for handling STATIC_LIB creation.
902 class archive-generator : generator
904 import property-set ;
906 rule __init__ ( id composing ? : source-types + : target-types +
910 generator.__init__ $(id) $(composing) : $(source-types)
911 : $(target-types) : $(requirements) ;
914 rule run ( project name ? : property-set : sources + )
916 sources += [ $(property-set).get <library> ] ;
918 local result = [ generator.run $(project) $(name) : $(property-set)
921 # For static linking, if we get a library in source, we can not directly
922 # link to it so we need to cause our dependencies to link to that
923 # library. There are two approaches:
924 # - adding the library to the list of returned targets.
925 # - using the <library> usage requirements.
926 # The problem with the first is:
928 # lib a1 : : <file>liba1.a ;
929 # lib a2 : a2.cpp a1 : <link>static ;
930 # install dist : a2 ;
932 # here we will try to install 'a1', even though it is not necessary in
933 # the general case. With the second approach, even indirect dependants
934 # will link to the library, but it should not cause any harm. So, return
935 # all LIB sources together with created targets, so that dependants link
937 local usage-requirements ;
938 if [ $(property-set).get <link> ] = static
940 for local t in $(sources)
942 if [ type.is-derived [ $(t).type ] LIB ]
944 usage-requirements += <library>$(t) ;
949 usage-requirements = [ property-set.create $(usage-requirements) ] ;
951 return $(usage-requirements) $(result) ;
956 rule register-archiver ( id composing ? : source-types + : target-types +
959 generators.register [ new archive-generator $(id) $(composing)
960 : $(source-types) : $(target-types) : $(requirements) ] ;
964 # Generator that accepts everything and produces nothing. Useful as a general
965 # fallback for toolset-specific actions like PCH generation.
967 class dummy-generator : generator
969 import property-set ;
971 rule run ( project name ? : property-set : sources + )
973 return [ property-set.empty ] ;
977 IMPORT $(__name__) : register-linker register-archiver
978 : : generators.register-linker generators.register-archiver ;