• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2008 - 2013 Roland Schwarz
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# Boost library support module.
7#
8# This module allows to use the boost library from boost-build projects. The
9# location of a boost source tree or the path to a pre-built version of the
10# library can be configured from either site-config.jam or user-config.jam. If
11# no location is configured the module looks for a BOOST_ROOT environment
12# variable, which should point to a boost source tree. As a last resort it tries
13# to use pre-built libraries from the standard search path of the compiler.
14#
15# If the location to a source tree is known, the module can be configured from
16# the *-config.jam files:
17#
18# using boost : 1.35 : <root>/path-to-boost-root ;
19#
20# If the location to a pre-built version is known:
21#
22# using boost : 1.34
23#   : <include>/usr/local/include/boost_1_34
24#     <library>/usr/local/lib
25#   ;
26#
27# It is legal to configure more than one boost library version in the config
28# files. The version identifier is used to disambiguate between them. The first
29# configured version becomes the default.
30#
31# To use a boost library you need to put a 'use' statement into your Jamfile:
32#
33# import boost ;
34#
35# boost.use-project 1.35 ;
36#
37# If you do not care about a specific version you just can omit the version
38# part, in which case the default is picked up:
39#
40# boost.use-project ;
41#
42# The library can be referenced with the project identifier '/boost'. To
43# reference the program_options you would specify:
44#
45# exe myexe : mysrc.cpp : <library>/boost//program_options ;
46#
47# Note that the requirements are automatically transformed into suitable tags to
48# find the correct pre-built library.
49#
50
51import common ;
52import modules ;
53import numbers ;
54import project ;
55import property-set ;
56import regex ;
57import toolset ;
58
59.boost.auto_config = [ property-set.create <layout>system ] ;
60
61if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
62{
63    .debug-configuration = true ;
64}
65
66# Configuration of the boost library to use.
67#
68# This can either be a boost source tree or pre-built libraries. The 'version'
69# parameter must be a valid boost version number, e.g. 1.35, if specifying a
70# pre-built version with versioned layout. It may be a symbolic name, e.g.
71# 'trunk' if specifying a source tree. The options are specified as named
72# parameters (like properties). The following parameters are available:
73#
74# <root>/path-to-boost-root            : Specify a source tree.
75# <include>/path-to-include            : The include directory to search.
76# <library>/path-to-library            : The library directory to search.
77# <layout>system or <layout>versioned  : Built library layout.
78# <build-id>my_build_id                : The custom build id to use.
79#
80rule init
81(
82    version     # Version identifier.
83    : options * # Set the option properties.
84)
85{
86    if $(.boost.$(version))
87    {
88        import errors ;
89        errors.user-error Boost $(version) already configured. ;
90    }
91    else
92    {
93        if $(.debug-configuration)
94        {
95            if ! $(.boost_default)
96            {
97                echo notice\: configuring default boost library $(version) ;
98            }
99            echo notice\: configuring boost library $(version) ;
100        }
101        .boost_default ?= $(version) ; # the first configured is default
102        .boost.$(version) = [ property-set.create $(options) ] ;
103    }
104}
105
106# Use a certain version of the library.
107#
108# The use-project rule causes the module to define a boost project of searchable
109# pre-built boost libraries, or references a source tree of the boost library.
110# If the 'version' parameter is omitted either the configured default (first in
111# config files) is used or an auto configuration will be attempted.
112#
113rule use-project
114(
115    version ? # The version of the library to use.
116)
117{
118    project.push-current [ project.current ] ;
119    version ?= $(.boost_default) ;
120    version ?= auto_config ;
121
122    if $(.initialized)
123    {
124        if $(.initialized) != $(version)
125        {
126            import errors ;
127            errors.user-error Attempt to use $(__name__) with different
128                parameters. ;
129        }
130    }
131    else
132    {
133        if $(.boost.$(version))
134        {
135            local opt  = $(.boost.$(version)) ;
136            local root = [ $(opt).get <root> ] ;
137            local inc  = [ $(opt).get <include> ] ;
138            local lib  = [ $(opt).get <library> ] ;
139
140            if $(.debug-configuration)
141            {
142                echo notice\: using boost library $(version) [ $(opt).raw ] ;
143            }
144
145            .layout = [ $(opt).get <layout> ] ;
146            .layout ?= versioned ;
147            .build_id = [ $(opt).get <build-id> ] ;
148            .version_tag = [ regex.replace $(version) "[*\\/:.\"\' ]" "_" ] ;
149            .initialized = $(version) ;
150
151            if ( $(root) && $(inc) )
152                || ( $(root) && $(lib) )
153                || ( $(lib) && ! $(inc) )
154                || ( ! $(lib) && $(inc) )
155            {
156                import errors ;
157                errors.user-error Ambiguous parameters, use either <root> or
158                    <include> with <library>. ;
159            }
160            else if ! $(root) && ! $(inc)
161            {
162                root = [ modules.peek : BOOST_ROOT ] ;
163            }
164
165            local prj = [ project.current ] ;
166            local mod = [ $(prj).project-module ] ;
167
168            if $(root)
169            {
170                modules.call-in $(mod) : use-project boost : $(root) ;
171            }
172            else
173            {
174                project.initialize $(__name__) ;
175                # It is possible to override the setup of the searched libraries
176                # per version. The (unlikely) 0.0.1 tag is meant as an example
177                # template only.
178                switch $(version)
179                {
180                    case 0.0.1 : boost_0_0_1 $(inc) $(lib) ;
181                    case * : boost_std $(inc) $(lib) ;
182                }
183            }
184        }
185        else
186        {
187            import errors ;
188            errors.user-error Reference to unconfigured boost version. ;
189        }
190    }
191    project.pop-current ;
192}
193
194local rule boost_lib_std ( id : shared-lib-define )
195{
196    lib $(id) : : : : <link>shared:<define>$(shared-lib-define) ;
197}
198
199rule boost_std ( inc ? lib ? )
200{
201#   The default definitions for pre-built libraries.
202
203    project boost
204        : usage-requirements <include>$(inc) <define>BOOST_ALL_NO_LIB
205        : requirements <tag>@tag_std <search>$(lib)
206        ;
207
208    alias headers ;
209    boost_lib_std chrono              : BOOST_CHRONO_DYN_LINK ;
210    boost_lib_std container           : BOOST_CONTAINER_DYN_LINK ;
211    boost_lib_std date_time           : BOOST_DATE_TIME_DYN_LINK ;
212    boost_lib_std filesystem          : BOOST_FILE_SYSTEM_DYN_LINK ;
213    boost_lib_std graph               : BOOST_GRAPH_DYN_LINK ;
214    boost_lib_std graph_parallel      : BOOST_GRAPH_DYN_LINK ;
215    boost_lib_std iostreams           : BOOST_IOSTREAMS_DYN_LINK ;
216    boost_lib_std locale              : BOOST_LOCALE_DYN_LINK ;
217    boost_lib_std log                 : BOOST_LOG_DYN_LINK  ;
218    boost_lib_std log_setup           : BOOST_LOG_SETUP_DYN_LINK  ;
219    boost_lib_std math_c99            : BOOST_MATH_TR1_DYN_LINK ;
220    boost_lib_std math_c99f           : BOOST_MATH_TR1_DYN_LINK ;
221    boost_lib_std math_c99l           : BOOST_MATH_TR1_DYN_LINK ;
222    boost_lib_std math_tr1            : BOOST_MATH_TR1_DYN_LINK ;
223    boost_lib_std math_tr1f           : BOOST_MATH_TR1_DYN_LINK ;
224    boost_lib_std math_tr1l           : BOOST_MATH_TR1_DYN_LINK ;
225    boost_lib_std mpi                 : BOOST_MPI_DYN_LINK  ;
226    boost_lib_std prg_exec_monitor    : BOOST_TEST_DYN_LINK ;
227    boost_lib_std program_options     : BOOST_PROGRAM_OPTIONS_DYN_LINK ;
228    boost_lib_std python              : BOOST_PYTHON_DYN_LINK ;
229    boost_lib_std python3             : BOOST_PYTHON_DYN_LINK ;
230    boost_lib_std random              : BOOST_RANDOM_DYN_LINK ;
231    boost_lib_std regex               : BOOST_REGEX_DYN_LINK  ;
232    boost_lib_std serialization       : BOOST_SERIALIZATION_DYN_LINK ;
233    boost_lib_std signals             : BOOST_SIGNALS_DYN_LINK  ;
234    boost_lib_std system              : BOOST_SYSTEM_DYN_LINK  ;
235    boost_lib_std test_exec_monitor   : BOOST_TEST_DYN_LINK ;
236    boost_lib_std thread              : BOOST_THREAD_DYN_DLL  ;
237    boost_lib_std timer               : BOOST_TIMER_DYN_DLL  ;
238    boost_lib_std unit_test_framework : BOOST_TEST_DYN_LINK  ;
239    boost_lib_std wave                : BOOST_WAVE_DYN_LINK  ;
240    boost_lib_std wserialization      : BOOST_SERIALIZATION_DYN_LINK ;
241}
242
243# Example placeholder for rules defining Boost library project & library targets
244# for a specific Boost library version. Copy under a different name and model
245# after the boost_std rule. Please note that it is also possible to have a per
246# version taging rule in case the tagging algorithm changes between versions.
247#
248rule boost_0_0_1 ( inc ? lib ? )
249{
250    echo "You are trying to use an example placeholder for boost libs." ;
251}
252
253rule tag_std ( name : type ? : property-set )
254{
255    name = boost_$(name) ;
256    if  ( [ $(property-set).get <link> ] in static ) &&
257        ( [ $(property-set).get <target-os> ] in windows )
258    {
259        name = lib$(name) ;
260    }
261
262    local result ;
263    if $(.layout) = system
264    {
265        local version = [ MATCH "^([0-9]+)_([0-9]+)" : $(.version_tag) ] ;
266        if $(version[1]) = "1" && [ numbers.less $(version[2]) 39 ]
267        {
268            result = [ tag_tagged $(name) : $(type) : $(property-set) ] ;
269        }
270        else
271        {
272            result = [ tag_system $(name) : $(type) : $(property-set) ] ;
273        }
274    }
275    else if $(.layout) = tagged
276    {
277        result = [ tag_tagged $(name) : $(type) : $(property-set) ] ;
278    }
279    else if $(.layout) = versioned
280    {
281        result = [ tag_versioned $(name) : $(type) : $(property-set) ] ;
282    }
283    else
284    {
285        import errors ;
286        errors.error Missing layout. ;
287    }
288
289    return $(result) ;
290}
291
292rule tag_system ( name : type ? : property-set )
293{
294    return [ common.format-name <base> -$(.build_id) : $(name) : $(type) :
295        $(property-set) ] ;
296}
297
298rule tag_tagged ( name : type ? : property-set )
299{
300    return [ common.format-name <base> <threading> <runtime> -$(.build_id) :
301        $(name) : $(type) : $(property-set) ] ;
302}
303
304rule tag_versioned ( name : type ? : property-set )
305{
306    return [ common.format-name <base> <toolset> <threading> <runtime>
307        -$(.version_tag) -$(.build_id) : $(name) : $(type) : $(property-set) ] ;
308}
309