blob: e256fe9658ef229a88057947f017aa58b344f23e [file] [log] [blame]
# $Id: boost.jam 62249 2010-05-26 19:05:19Z steven_watanabe $
# Copyright 2008 Roland Schwarz
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
# Boost library support module.
#
# This module allows to use the boost library from boost-build projects.
# The location of a boost source tree or the path to a pre-built
# version of the library can be configured from either site-config.jam
# or user-config.jam. If no location is configured the module looks for
# a BOOST_ROOT environment variable, which should point to a boost source
# tree. As a last resort it tries to use pre-built libraries from the standard
# search path of the compiler.
#
# If the location to a source tree is known, the module can be configured
# from the *-config.jam files:
#
# using boost : 1.35 : <root>/path-to-boost-root ;
#
# If the location to a pre-built version is known:
#
# using boost : 1.34
# : <include>/usr/local/include/boost_1_34
# <library>/usr/local/lib
# ;
#
# It is legal to configure more than one boost library version in the config
# files. The version identifier is used to disambiguate between them.
# The first configured version becomes the default.
#
# To use a boost library you need to put a 'use' statement into your
# Jamfile:
#
# import boost ;
#
# boost.use-project 1.35 ;
#
# If you don't care about a specific version you just can omit the version
# part, in which case the default is picked up:
#
# boost.use-project ;
#
# The library can be referenced with the project identifier '/boost'. To
# reference the program_options you would specify:
#
# exe myexe : mysrc.cpp : <library>/boost//program_options ;
#
# Note that the requirements are automatically transformed into suitable
# tags to find the correct pre-built library.
#
import re
import bjam
from b2.build import alias, property, property_set, feature
from b2.manager import get_manager
from b2.tools import builtin, common
from b2.util import bjam_signature, regex
# TODO: This is currently necessary in Python Port, but was not in Jam.
feature.feature('layout', ['system', 'versioned', 'tag'], ['optional'])
feature.feature('root', [], ['optional', 'free'])
feature.feature('build-id', [], ['optional', 'free'])
__initialized = None
__boost_auto_config = property_set.create([property.Property('layout', 'system')])
__boost_configured = {}
__boost_default = None
__build_id = None
__debug = None
def debug():
global __debug
if __debug is None:
__debug = "--debug-configuration" in bjam.variable("ARGV")
return __debug
# Configuration of the boost library to use.
#
# This can either be a boost source tree or
# pre-built libraries. The 'version' parameter must be a valid boost
# version number, e.g. 1.35, if specifying a pre-built version with
# versioned layout. It may be a symbolic name, e.g. 'trunk' if specifying
# a source tree. The options are specified as named parameters (like
# properties). The following paramters are available:
#
# <root>/path-to-boost-root: Specify a source tree.
#
# <include>/path-to-include: The include directory to search.
#
# <library>/path-to-library: The library directory to search.
#
# <layout>system or <layout>versioned.
#
# <build-id>my_build_id: The custom build id to use.
#
def init(version, options = None):
assert(isinstance(version,list))
assert(len(version)==1)
version = version[0]
if version in __boost_configured:
get_manager().errors()("Boost {} already configured.".format(version));
else:
global __boost_default
if debug():
if not __boost_default:
print "notice: configuring default boost library {}".format(version)
print "notice: configuring boost library {}".format(version)
if not __boost_default:
__boost_default = version
properties = []
for option in options:
properties.append(property.create_from_string(option))
__boost_configured[ version ] = property_set.PropertySet(properties)
projects = get_manager().projects()
rules = projects.project_rules()
# Use a certain version of the library.
#
# The use-project rule causes the module to define a boost project of
# searchable pre-built boost libraries, or references a source tree
# of the boost library. If the 'version' parameter is omitted either
# the configured default (first in config files) is used or an auto
# configuration will be attempted.
#
@bjam_signature(([ "version", "?" ], ))
def use_project(version = None):
projects.push_current( projects.current() )
if not version:
version = __boost_default
if not version:
version = "auto_config"
global __initialized
if __initialized:
if __initialized != version:
get_manager().errors()('Attempt to use {} with different parameters'.format('boost'))
else:
if version in __boost_configured:
opts = __boost_configured[ version ]
root = opts.get('<root>' )
inc = opts.get('<include>')
lib = opts.get('<library>')
if debug():
print "notice: using boost library {} {}".format( version, opt.raw() )
global __layout
global __version_tag
__layout = opts.get('<layout>')
if not __layout:
__layout = 'versioned'
__build_id = opts.get('<build-id>')
__version_tag = re.sub("[*\\/:.\"\' ]", "_", version)
__initialized = version
if ( root and inc ) or \
( root and lib ) or \
( lib and not inc ) or \
( not lib and inc ):
get_manager().errors()("Ambiguous parameters, use either <root> or <inlude> with <library>.")
elif not root and not inc:
root = bjam.variable("BOOST_ROOT")
module = projects.current().project_module()
if root:
bjam.call('call-in-module', module, 'use-project', ['boost', root])
else:
projects.initialize(__name__)
if version == '0.0.1':
boost_0_0_1( inc, lib )
else:
boost_std( inc, lib )
else:
get_manager().errors()("Reference to unconfigured boost version.")
projects.pop_current()
rules.add_rule( 'boost.use-project', use_project )
def boost_std(inc = None, lib = None):
# The default definitions for pre-built libraries.
rules.project(
['boost'],
['usage-requirements'] + ['<include>{}'.format(i) for i in inc] + ['<define>BOOST_ALL_NO_LIB'],
['requirements'] + ['<search>{}'.format(l) for l in lib])
# TODO: There should be a better way to add a Python function into a
# project requirements property set.
tag_prop_set = property_set.create([property.Property('<tag>', tag_std)])
attributes = projects.attributes(projects.current().project_module())
attributes.requirements = attributes.requirements.refine(tag_prop_set)
alias('headers')
def boost_lib(lib_name, dyn_link_macro):
if (isinstance(lib_name,str)):
lib_name = [lib_name]
builtin.lib(lib_name, usage_requirements=['<link>shared:<define>{}'.format(dyn_link_macro)])
boost_lib('date_time' , 'BOOST_DATE_TIME_DYN_LINK' )
boost_lib('filesystem' , 'BOOST_FILE_SYSTEM_DYN_LINK' )
boost_lib('graph' , 'BOOST_GRAPH_DYN_LINK' )
boost_lib('graph_parallel' , 'BOOST_GRAPH_DYN_LINK' )
boost_lib('iostreams' , 'BOOST_IOSTREAMS_DYN_LINK' )
boost_lib('locale' , 'BOOST_LOG_DYN_LINK' )
boost_lib('log' , 'BOOST_LOG_DYN_LINK' )
boost_lib('log_setup' , 'BOOST_LOG_DYN_LINK' )
boost_lib('math_tr1' , 'BOOST_MATH_TR1_DYN_LINK' )
boost_lib('math_tr1f' , 'BOOST_MATH_TR1_DYN_LINK' )
boost_lib('math_tr1l' , 'BOOST_MATH_TR1_DYN_LINK' )
boost_lib('math_c99' , 'BOOST_MATH_TR1_DYN_LINK' )
boost_lib('math_c99f' , 'BOOST_MATH_TR1_DYN_LINK' )
boost_lib('math_c99l' , 'BOOST_MATH_TR1_DYN_LINK' )
boost_lib('mpi' , 'BOOST_MPI_DYN_LINK' )
boost_lib('program_options' , 'BOOST_PROGRAM_OPTIONS_DYN_LINK')
boost_lib('python' , 'BOOST_PYTHON_DYN_LINK' )
boost_lib('python3' , 'BOOST_PYTHON_DYN_LINK' )
boost_lib('random' , 'BOOST_RANDOM_DYN_LINK' )
boost_lib('regex' , 'BOOST_REGEX_DYN_LINK' )
boost_lib('serialization' , 'BOOST_SERIALIZATION_DYN_LINK' )
boost_lib('wserialization' , 'BOOST_SERIALIZATION_DYN_LINK' )
boost_lib('signals' , 'BOOST_SIGNALS_DYN_LINK' )
boost_lib('system' , 'BOOST_SYSTEM_DYN_LINK' )
boost_lib('unit_test_framework' , 'BOOST_TEST_DYN_LINK' )
boost_lib('prg_exec_monitor' , 'BOOST_TEST_DYN_LINK' )
boost_lib('test_exec_monitor' , 'BOOST_TEST_DYN_LINK' )
boost_lib('thread' , 'BOOST_THREAD_DYN_DLL' )
boost_lib('wave' , 'BOOST_WAVE_DYN_LINK' )
def boost_0_0_1( inc, lib ):
print "You are trying to use an example placeholder for boost libs." ;
# Copy this template to another place (in the file boost.jam)
# and define a project and libraries modelled after the
# boost_std rule. Please note that it is also possible to have
# a per version taging rule in case they are different between
# versions.
def tag_std(name, type, prop_set):
name = 'boost_' + name
if 'static' in prop_set.get('<link>') and 'windows' in prop_set.get('<target-os>'):
name = 'lib' + name
result = None
if __layout == 'system':
versionRe = re.search('^([0-9]+)_([0-9]+)', __version_tag)
if versionRe and versionRe.group(1) == '1' and int(versionRe.group(2)) < 39:
result = tag_tagged(name, type, prop_set)
else:
result = tag_system(name, type, prop_set)
elif __layout == 'tagged':
result = tag_tagged(name, type, prop_set)
elif __layout == 'versioned':
result = tag_versioned(name, type, prop_set)
else:
get_manager().errors()("Missing layout")
return result
def tag_maybe(param):
return ['-{}'.format(param)] if param else []
def tag_system(name, type, prop_set):
return common.format_name(['<base>'] + tag_maybe(__build_id), name, type, prop_set)
def tag_tagged(name, type, prop_set):
return common.format_name(['<base>', '<threading>', '<runtime>'] + tag_maybe(__build_id), name, type, prop_set)
def tag_versioned(name, type, prop_set):
return common.format_name(['<base>', '<toolset>', '<threading>', '<runtime>'] + tag_maybe(__version_tag) + tag_maybe(__build_id),
name, type, prop_set)