# Copyright David Abrahams 2001-2006. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

import os ;
import indirect ;
import modules ;
import feature ;
import property ;

import python ;

if ! [ python.configured ] && ! ( --without-python in  [ modules.peek : ARGV ] )
{
    # Attempt default configuration of python
    import toolset : using ;
    using python ;
}

if [ python.configured ] || ( --without-python in  [ modules.peek : ARGV ] )
{
    alias config-warning ;
}
else
{
    message config-warning
        : "warning: No python installation configured and autoconfiguration"
        : "note: failed.  See http://www.boost.org/libs/python/doc/building.html"
        : "note: for configuration instructions or pass --without-python to"
        : "note: suppress this message and silently skip all Boost.Python targets"
        ;
}

py2-version = [ py-version 2 ] ;
py3-version = [ py-version 3 ] ;

project boost/python
  : source-location ../src
  ;

rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
local rule eq ( a : b ) { if $(a) = $(b) { return 1 ; } }

lib_boost_python(2) = boost_python ;
lib_boost_python(3) = boost_python3 ;

lib_boost_python($(py2-version)) = $(lib_boost_python(2)) ;
lib_boost_python($(py3-version)) = $(lib_boost_python(3)) ;

rule lib_boost_python ( version )
{
    lib $(lib_boost_python($(version)))
        : # sources
        list.cpp
        long.cpp
        dict.cpp
        tuple.cpp
        str.cpp
        slice.cpp

        converter/from_python.cpp
        converter/registry.cpp
        converter/type_id.cpp
        object/enum.cpp
        object/class.cpp
        object/function.cpp
        object/inheritance.cpp
        object/life_support.cpp
        object/pickle_support.cpp
        errors.cpp
        module.cpp
        converter/builtin_converters.cpp
        converter/arg_to_python_base.cpp
        object/iterator.cpp
        object/stl_iterator.cpp
        object_protocol.cpp
        object_operators.cpp
        wrapper.cpp
        import.cpp
        exec.cpp
        object/function_doc_signature.cpp
        :   # requirements
            <link>static:<define>BOOST_PYTHON_STATIC_LIB 
            <define>BOOST_PYTHON_SOURCE
          
            # On Windows, all code using Python has to link to the Python
            # import library.
            #
            # On *nix we never link libboost_python to libpython.  When
            # extending Python, all Python symbols are provided by the
            # Python interpreter executable.  When embedding Python, the
            # client executable is expected to explicitly link to
            # /python//python (the target representing libpython) itself.
            #
            # python_for_extensions is a target defined by Boost.Build to
            # provide the Python include paths, and on Windows, the Python
            # import library, as usage requirements.
            [ cond [ python.configured ] : <library>/python//python_for_extensions ]
            
            # we prevent building when there is no python available
            # as it's not possible anyway, and to cause dependents to
            # fail to build
            [ unless [ python.configured ] : <build>no ]
            <dependency>config-warning

            <python-debugging>on:<define>BOOST_DEBUG_PYTHON
            <python>$(version)

            -<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
            <tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).python-tag

            <conditional>@python.require-py

        :   # default build
            <link>shared
        :   # usage requirements
            <link>static:<define>BOOST_PYTHON_STATIC_LIB
            <python-debugging>on:<define>BOOST_DEBUG_PYTHON
        ;
}

lib_boost_numpy(2) = boost_numpy ;
lib_boost_numpy(3) = boost_numpy3 ;

lib_boost_numpy($(py2-version)) = $(lib_boost_numpy(2)) ;
lib_boost_numpy($(py3-version)) = $(lib_boost_numpy(3)) ;

rule lib_boost_numpy ( version )
{
    numpy-include = [ python.numpy-include ] ;
    lib $(lib_boost_numpy($(version)))
        : # sources
        numpy/dtype.cpp
        numpy/matrix.cpp
        numpy/ndarray.cpp
        numpy/numpy.cpp
        numpy/scalars.cpp
        numpy/ufunc.cpp
        :   # requirements
            <link>static:<define>BOOST_NUMPY_STATIC_LIB 
            <define>BOOST_NUMPY_SOURCE
            [ cond [ python.numpy ] : <library>/python//python_for_extensions ]
            [ unless [ python.numpy ] : <build>no ]
            <include>$(numpy-include)
            <library>$(lib_boost_python($(version)))
            <python-debugging>on:<define>BOOST_DEBUG_PYTHON
            <python>$(version)

            -<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
            <tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).python-tag

            <conditional>@python.require-py

        :   # default build
            <link>shared
        :   # usage requirements
			<link>static:<define>BOOST_NUMPY_STATIC_LIB
            <python-debugging>on:<define>BOOST_DEBUG_PYTHON
        ;
}

libraries = ;

for local N in 2 3
{
    if $(py$(N)-version)
    {
        lib_boost_python $(py$(N)-version) ;
        libraries += $(lib_boost_python($(py$(N)-version))) ;
    }
    else
    {
        alias $(lib_boost_python($(N))) ;
    }
    if $(py$(N)-version) && [ python.numpy ]
    {
        lib_boost_numpy $(py$(N)-version) ;
        libraries += $(lib_boost_numpy($(py$(N)-version))) ;
    }
    else
    {
        alias $(lib_boost_numpy($(N))) ;
    }
}

boost-install $(libraries) ;
