3 votes

Boost.Python échoue avec les bibliothèques statiques

Je n'arrive pas à faire fonctionner l'exemple simple hello.cpp dans Boost.Python.

hello.cpp :

char const* greet()
{
   return "hello, world";
}

BOOST_PYTHON_MODULE(hello_ext)
{
    using namespace boost::python;
    def("greet", greet);
}

J'utilise cmake avec mingw-w64 et je ne suis pas tout à fait sûr de la différence entre l'utilisation des bibliothèques statiques et partagées de boost. Si l'extension est liée à la bibliothèque partagée, la bibliothèque de l'extension devra-t-elle être distribuée avec la bibliothèque boost également ? J'aimerais n'avoir à distribuer qu'une seule dll. Quelle est la différence entre Boost_USE_STATIC_LIBS y Boost_USE_STATIC_RUNTIME ? Si l'un de ces drapeaux a la valeur ON la compilation suivante échouera avec des symboles non définis. S'ils sont tous deux définis sur OFF, un fichier appelé libhello_ext.dll est créé. Cependant, je ne parviens pas à faire en sorte que python l'utilise avec l'une ou l'autre des options suivantes import hello_ext o import libhello_ext .

Voici mon fichier CMakeLists.txt :

cmake_minimum_required(VERSION 3.12)
project(hello VERSION 1.0)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wextra -pedantic -g")

set(BOOST_LIBRARYDIR C:/boost_1_67_0/stage/x64/lib)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME ON)
find_package(Boost 1.67.0 REQUIRED python37)
if (Boost_FOUND)
    message(" Boost include directory found at ${Boost_INCLUDE_DIRS}")
    message(" Boost libraries found at ${Boost_LIBRARIES}")
else()
    message(" Boost not found")
    return()
endif()

find_package(PythonLibs 3.7 REQUIRED)
if (PYTHONLIBS_FOUND)
    message(" Python include directory found at ${PYTHON_INCLUDE_DIRS}")
    message(" Python libraries found at ${PYTHON_LIBRARIES}")
else()
    message(" Python not found")
endif()

set(SOURCE_FILES hello.cpp)
add_library(hello_ext SHARED ${SOURCE_FILES})

target_include_directories(hello_ext SYSTEM PRIVATE  ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
target_link_libraries(hello_ext ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})

Voici le résultat de mingw32-make :

[ 50%] Linking CXX shared library libhello_ext.dll
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `PyInit_hello_ext':
C:/boost_1_67_0/libs/python/example/tutorial/hello.cpp:15: undefined reference to `__imp__ZN5boost6python6detail11init_moduleER11PyModuleDefPFvvE'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `boost::python::type_info::name() const':
C:/boost_1_67_0/boost/python/type_id.hpp:160: undefined reference to `__imp__ZN5boost6python6detail12gcc_demangleEPKc'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `boost::python::to_python_value<char const* const&>::operator()(char const* const&) const':
C:/boost_1_67_0/boost/python/converter/builtin_converters.hpp:157: undefined reference to `__imp__ZN5boost6python9converter19do_return_to_pythonEPKc'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `void boost::python::def<char const* (*)()>(char const*, char const* (*)())':
C:/boost_1_67_0/boost/python/def.hpp:91: undefined reference to `__imp__ZN5boost6python6detail17scope_setattr_docEPKcRKNS0_3api6objectES3_'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `boost::python::api::object boost::python::detail::make_function_aux<char const* (*)(), boost::python::default_call_policies, boost::mpl::vector1<char const*> >(char const* (*)(), boost::python::default_call_policies const&, boost::mpl::vector1<char const*> const&)':
C:/boost_1_67_0/boost/python/make_function.hpp:38: undefined reference to `__imp__ZN5boost6python7objects15function_objectERKNS1_11py_functionE'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `boost::python::objects::py_function_impl_base::py_function_impl_base()':
C:/boost_1_67_0/boost/python/object/py_function.hpp:20: undefined reference to `__imp__ZTVN5boost6python7objects21py_function_impl_baseE'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `boost::python::objects::caller_py_function_impl<boost::python::detail::caller<char const* (*)(), boost::python::default_call_policies, boost::mpl::vector1<char const*> > >::~caller_py_function_impl()':
C:/boost_1_67_0/boost/python/object/py_function.hpp:30: undefined reference to `__imp__ZN5boost6python7objects21py_function_impl_baseD2Ev'
CMakeFiles\hello_ext.dir/objects.a(hello.cpp.obj): In function `boost::python::converter::expected_pytype_for_arg<char const*>::get_pytype()':
C:/boost_1_67_0/boost/python/converter/pytype_function.hpp:67: undefined reference to `__imp__ZN5boost6python9converter8registry5queryENS0_9type_infoE'
C:/boost_1_67_0/boost/python/converter/pytype_function.hpp:70: undefined reference to `__imp__ZNK5boost6python9converter12registration25expected_from_python_typeEv'
collect2.exe: error: ld returned 1 exit status
mingw32-make[2]: *** [CMakeFiles\hello_ext.dir\build.make:88: libhello_ext.dll] Error 1
mingw32-make[1]: *** [CMakeFiles\Makefile2:72: CMakeFiles/hello_ext.dir/all] Error 2
mingw32-make: *** [Makefile:83: all] Error 2

0voto

A. Palma Points 37

Pour une raison étrange, la convention de nommage doit être forcée pour Boost Python (et seulement pour Boost Python, les autres modules Boost n'en ont pas besoin) sous Windows (pas sous Linux ni MacOSX).

En résumé, vous devez ajouter :

add_definitions(/DBOOST_PYTHON_STATIC_LIB)

dans votre fichier de configuration CMake. Sinon, votre éditeur de liens essaiera d'utiliser boost_python37-vc141-mt-x64-1_70.lib (la bibliothèque d'importation associée à la DLL, boost_python37-vc141-mt-x64-1_70.dll ) au lieu de libboost_python37-vc141-mt-x64-1_70.lib qui est la "vraie" bibliothèque statique (Stupide Windows et sa convention bizarre d'utiliser la même extension pour les bibliothèques d'importation et les bibliothèques statiques).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X