From 23bfb84e38a65a720d37d29cebc7c417c76ce233 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 29 May 2002 20:32:49 +0000 Subject: [PATCH] Finally, it works on AIX! [SVN r14061] --- Jamfile | 9 ++ .../boost/python/detail/aix_init_module.hpp | 24 +++ include/boost/python/detail/config.hpp | 8 - include/boost/python/detail/module_init.hpp | 50 +++++++ include/boost/python/module.hpp | 1 + include/boost/python/module_builder.hpp | 1 + include/boost/python/type_id.hpp | 26 +++- src/aix_init_module.cpp | 140 ++++++++++++++++++ src/converter/registry.cpp | 12 +- 9 files changed, 258 insertions(+), 13 deletions(-) create mode 100644 include/boost/python/detail/aix_init_module.hpp create mode 100644 include/boost/python/detail/module_init.hpp create mode 100644 src/aix_init_module.cpp diff --git a/Jamfile b/Jamfile index 73a0a047..19b269b0 100644 --- a/Jamfile +++ b/Jamfile @@ -4,8 +4,16 @@ subproject libs/python ; SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; +local bpl-ldflags ; + +if $(UNIX) && ( $(OS) = AIX ) +{ + bpl-linkflags = "-e initlibbpl" ; +} + dll bpl : + src/aix_init_module.cpp src/converter/from_python.cpp src/converter/registry.cpp src/converter/type_id.cpp @@ -22,4 +30,5 @@ dll bpl : $(BOOST_PYTHON_V2_PROPERTIES) BOOST_PYTHON_SOURCE + $(bpl-linkflags) ; diff --git a/include/boost/python/detail/aix_init_module.hpp b/include/boost/python/detail/aix_init_module.hpp new file mode 100644 index 00000000..e73210d5 --- /dev/null +++ b/include/boost/python/detail/aix_init_module.hpp @@ -0,0 +1,24 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef AIX_INIT_MODULE_DWA2002529_HPP +# define AIX_INIT_MODULE_DWA2002529_HPP +# ifdef _AIX +# include +# include + +namespace boost { namespace python { namespace detail { + +extern "C" +{ + typedef PyObject* (*so_load_function)(char*,char*,FILE*); +} + +void aix_init_module(so_load_function, void (*init_module)()); + +}}} // namespace boost::python::detail +# endif + +#endif // AIX_INIT_MODULE_DWA2002529_HPP diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index cd0377b5..1867b4f3 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -62,14 +62,6 @@ # define BOOST_CSTD_ std # endif -# ifndef BOOST_PYTHON_MODULE_INIT -# if defined(_WIN32) || defined(__CYGWIN__) -# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name() -# else -# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name() -# endif -# endif - /***************************************************************************** * * Set up dll import/export options: diff --git a/include/boost/python/detail/module_init.hpp b/include/boost/python/detail/module_init.hpp new file mode 100644 index 00000000..5b5ce9f5 --- /dev/null +++ b/include/boost/python/detail/module_init.hpp @@ -0,0 +1,50 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MODULE_INIT_DWA2002529_HPP +# define MODULE_INIT_DWA2002529_HPP + +# ifndef BOOST_PYTHON_MODULE_INIT + +# if defined(_WIN32) || defined(__CYGWIN__) + +# define BOOST_PYTHON_MODULE_INIT(name) \ +void init_module_##name(); \ +extern "C" __declspec(dllexport) void init##name() \ +{ \ + boost::python::handle_exception(&init_module_##name); \ +} \ +void init_module_##name() + +# elif defined(_AIX) + +# include +# define BOOST_PYTHON_MODULE_INIT(name) \ +void init_module_##name(); \ +extern "C" \ +{ \ + extern PyObject* _PyImport_LoadDynamicModule(char*, char*, FILE *); \ + void init##name() \ + { \ + boost::python::detail::aix_init_module(_PyImport_LoadDynamicModule, &init_module_##name); \ + } \ +} \ +void init_module_##name() + +# else + +# define BOOST_PYTHON_MODULE_INIT(name) \ +void init_module_##name(); \ +extern "C" void init##name() \ +{ \ + boost::python::handle_exception(&init_module_##name); \ +} \ +void init_module_##name() + +# endif + +# endif + +#endif // MODULE_INIT_DWA2002529_HPP diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 7df183d5..c05d1032 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -12,6 +12,7 @@ # include # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/module_builder.hpp b/include/boost/python/module_builder.hpp index 180a6200..222b28d7 100644 --- a/include/boost/python/module_builder.hpp +++ b/include/boost/python/module_builder.hpp @@ -13,6 +13,7 @@ # include # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/type_id.hpp b/include/boost/python/type_id.hpp index fbceec66..3573239c 100755 --- a/include/boost/python/type_id.hpp +++ b/include/boost/python/type_id.hpp @@ -10,13 +10,16 @@ # include # include # include +# include +# include +# include namespace boost { namespace python { // for this compiler at least, cross-shared-library type_info // comparisons don't work, so use typeid(x).name() instead. It's not // yet clear what the best default strategy is. -# if defined(__GNUC__) && __GNUC__ >= 3 +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(_AIX) # define BOOST_PYTHON_TYPE_ID_NAME # endif @@ -56,6 +59,27 @@ inline type_info type_id(boost::type* = 0) ); } +# if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ <= 245 +// KCC on this platform seems to mistakenly distinguish "int" from +// "signed int", etc., but only in typeid() expressions. However +// though int == signed int, the "signed" decoration is propagated +// down into template instantiations. Explicit specialization stops +// that from taking hold. + +# define BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(T) \ +template <> \ +inline type_info type_id(boost::type*) \ +{ \ + return type_info(typeid(T)); \ +} + +BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(short) +BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(int) +BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long) +# undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID +# endif + + inline type_info::type_info(std::type_info const& id) : m_base_type( # ifdef BOOST_PYTHON_TYPE_ID_NAME diff --git a/src/aix_init_module.cpp b/src/aix_init_module.cpp new file mode 100644 index 00000000..61422e6b --- /dev/null +++ b/src/aix_init_module.cpp @@ -0,0 +1,140 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifdef _AIX +#include +#include + +extern "C" +{ +#include +#include +} + +# include +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +namespace +{ + extern "C" void initlibbpl() + { + static PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; + Py_InitModule("libbpl", initial_methods); + } + + struct find_and_open_file + { + FILE* fp; + std::string libpath; // -- search path + std::string filename; // -- filename to look for + std::string fullpath; // -- full path to file + + find_and_open_file( + const std::string& libpath_env + , const std::string& file); + }; + + find_and_open_file::find_and_open_file( + const std::string& libpath_env + , const std::string& file) + : fp(0) + { + char* value = std::getenv(libpath_env.c_str()); + + if(value == 0) + return; + + libpath = value; + + if (libpath == "") + return; + + std::string::size_type pos = 0, prev_pos = 0; + + // -- loop through all search paths looking for file + while((pos = libpath.find_first_of(":",pos)) != std::string::npos) + { + fullpath = libpath.substr(prev_pos,pos - prev_pos) + "/" + file; + if (::access(fullpath.c_str(), R_OK) == 0) + { + struct stat filestat; + ::stat(fullpath.c_str(), &filestat); + if (!S_ISDIR(filestat.st_mode)) + { + fp = std::fopen(fullpath.c_str(), "r"); + if (fp) + { + filename = file; + } + return; + } + } + prev_pos = ++pos; + } + + // -- mop up odd path + if (libpath.find_first_of(":", prev_pos) == std::string::npos) + { + fullpath = libpath.substr(prev_pos, libpath.size() - prev_pos) + "/" + file; + if (::access(fullpath.c_str(), R_OK) == 0) + { + struct stat filestat; + ::stat(fullpath.c_str(),&filestat); + if (!S_ISDIR(filestat.st_mode)) + { + fp = std::fopen(fullpath.c_str(), "r"); + filename = file; + } + } + } + } +} + +void aix_init_module( + so_load_function load_dynamic_module + , void (*init_module)()) +{ + static bool initialized; + if (!initialized) + { + char const* const name = "libbpl.so"; + find_and_open_file dynlib("LIBPATH", name); + if (dynlib.fp == 0) + { + fprintf(stderr, " Error: could not find %s\n", name); + return; + } + + std::string::size_type pos = pos = dynlib.filename.find_first_of(".so",0); + if (pos == std::string::npos) + { + fprintf(stderr, "dynamic library %s must end with .so\n", dynlib.filename.c_str()); + return; + } + + PyObject* m = + load_dynamic_module( + const_cast(dynlib.filename.substr(0,pos).c_str()), + const_cast(dynlib.fullpath.c_str()), + dynlib.fp); + + if (m == 0) + { + fprintf(stderr, "failed to load library %s\n", name); + return; + } + Py_DECREF(m); + + initialized = true; + } + python::handle_exception(init_module); +} + +}}} // namespace boost::python +#endif diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index 3e0afdc2..d1ba57df 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -35,8 +35,8 @@ namespace // registry_t& entries() { static registry_t registry; - -#ifdef BOOST_PYTHON_DYNAMIC_LIB // this conditional should go away eventually. + +# ifdef BOOST_PYTHON_DYNAMIC_LIB // this conditional should go away eventually. static bool builtin_converters_initialized = false; if (!builtin_converters_initialized) { @@ -46,13 +46,17 @@ namespace // initialize_builtin_converters(); } -#endif +# endif return registry; } entry* find(type_info type) { - return &entries()[type]; + registry_t& assoc = entries(); + registry_t::iterator p = assoc.find(type); + return p != assoc.end() + ? &p->second + : &assoc[type]; } entry::entry()