Есть такая конфигурация:
boost 1.33.1 — собрано всё кроме питона
Intel C++ Compiler 8.1.018 for Windows
Python 2.5
Сейчас пытаюсь докомпилировать boost_python. Делаю это такми батником:
SET INTEL_BASE_MSVC_TOOLSET=vc-7_1
SET TOOLS=intel-win32
SET INTEL_PATH=c:\Install\Intel\CPP\Compiler80\Ia32
SET INTEL_VERSION=81
SET PYTHON_VERSION= 2.5
SET PYTHON_ROOT=C:\Install\Python25
bjam --prefix=C:\prg\boost --with-python install 1>icc_python.log 2>icc_python.err
В результате вываливаются такие ошибки:
C:\prg\boost_1_33_1\boost/python/converter/pyobject_traits.hpp(33): error: expression must have a constant value
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Type);
^
detected during instantiation of class "boost::python::converter::pyobject_traits<PyTypeObject>" at line 33
C:\prg\boost_1_33_1\boost/python/converter/pyobject_traits.hpp(34): error: expression must have a constant value
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(List);
^
detected during instantiation of class "boost::python::converter::pyobject_traits<PyListObject>" at line 34
C:\prg\boost_1_33_1\boost/python/converter/pyobject_traits.hpp(35): error: expression must have a constant value
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Int);
^
detected during instantiation of class "boost::python::converter::pyobject_traits<PyIntObject>" at line 35
Ошибки возникают в файле pyobject_traits.hpp. Вот кусок кода из него:
# define BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(T) \
template <> struct pyobject_traits<Py##T##Object> \
: pyobject_type<Py##T##Object, &Py##T##_Type> {}
// This is not an exhaustive list; should be expanded.
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Type); //line 33
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(List); //line 34
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Int); //line 35
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Long);
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Dict);
BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Tuple);
Здесь идёт специализация шаблона pyobject_traits типами PyTypeObject, PyListObject... и
адресами переменных PyType_Type, PyList_Type, PyInt_Type и т. д. Эти переменные имеют тип PyTypeObject и объявлены в заголовочных файлах идущих с самим питоном. Объявления выглядят так:
PyAPI_DATA(PyTypeObject) PyList_Type;
PyAPI_DATA — это макрос который разворачивается в зависимости от того собираем ли мы динамическую либу, билдим ли мы ядро или наоборот подключаем его используем ли Cygwin. В общем сам макрос определён в файле %PYTHON_ROOT%\include\pyport.h следующим оборазом:
/* only get special linkage if built as shared or platform is Cygwin */
#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__)
# if defined(HAVE_DECLSPEC_DLL)
# ifdef Py_BUILD_CORE
# define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE
# else /* Py_BUILD_CORE */
/* Building an extension module, or an embedded situation */
/* public Python functions and data are imported */
# define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE
# endif /* Py_BUILD_CORE */
# endif /* HAVE_DECLSPEC */
#endif /* Py_ENABLE_SHARED */
/* If no external linkage macros defined by now, create defaults */
#ifndef PyAPI_DATA
# define PyAPI_DATA(RTYPE) extern RTYPE
#endif
Там ещё много чего определено, но я оставил только то, что касается PyAPI_DATA.
В моём случае всё это чудо разворачивается в такое определение интересующих нас переменных:
extern __declspec(dllimport) PyTypeObject PyList_Type;
адрес которых потом передаётся в качестве параметра шаблонна.
В общем-то, если войти в положение компилятора, то его понять можно. Как, спрашивается, в компайл-тайме получить адрес переменной, которая будет импортированна из dll'ки? Но о чём тогда думали создатели boost_python? И как вообще это у остальных собирается? На сколько я знаю MSVC в данном вопросе будет солдидарен c ICL.
З.Ы. Сейчас попробую в ручную добавить define Py_BUILD_CORE. Хотя думаю, что этот дефайн должен быть определён только при сборке самого питона.