Ошибка линковки библотеки (связка C++, boost, python)

188
23 февраля 2019, 08:00

Собственно следовал по пути автора с целью получить библиотеку с расчетной частью на С++ и всем остальным на Python. Пользуюсь Clion 2018.1.6, MinGW-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0, cкачал CMake 3.13.0-rc1-, Python 3.7 (x86_64) (проверил разрядность, выдало все таки 64), boost 1.68.0 собрал следующим образом:

bootstrap
b2 -j12 --stagedir=lib\x64 architecture=x86 address-model=64 --with-python --build-type=complete stage

Получил заветные либы, но при сборке мне почему то выдало win-32 (Пересобирал несколько раз из под C:\Windows\SysWOW64\cmd.exe, и другими опциями). Так и не могу определить под какую разрядность собралось.

Далее начал собирать тестовый проект: CMakeList.txt

cmake_minimum_required(VERSION 3.13)
project(pylibtest)
set(CMAKE_CXX_STANDARD 17)
set(GCC_COVERAGE_COMPILE_FLAGS "-march=native -O2 -m64 -D_hypot=hypot -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )
message(STATUS "start running cmake...")
set(Boost_USE_MULTITHREADED ON)
find_package(Boost 1.68.0)# COMPONENTS system filesystem REQUIRED)
if(Boost_FOUND)
    message(STATUS "Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
    set(Boost_LIBRARY_DIR "${Boost_Path}/lib/x64/lib")
    message(STATUS "Boost_LIBRARIES: ${Boost_LIBRARY_DIR}")
    message(STATUS "Boost_VERSION: ${Boost_VERSION}")
    include_directories(${Boost_INCLUDE_DIRS})
    link_directories(${Boost_LIBRARIES})
endif()
find_package(PythonInterp 3.7 REQUIRED)
find_package(PythonLibs 3.7 REQUIRED)
if(PYTHONLIBS_FOUND)
    message(STATUS "PYTHON_LIBRARIES = ${PYTHON_LIBRARIES}")
    message(STATUS "PYTHON_EXECUTABLE = ${PYTHON_EXECUTABLE}")
    message(STATUS "PYTHON_INCLUDE_DIRS = ${PYTHON_INCLUDE_DIRS}")
    include_directories(${PYTHON_INCLUDE_DIRS})
    link_directories(${PYTHON_LIBRARIES})
endif()
add_library(pylibtest SHARED library.cpp library.h)
if(Boost_FOUND AND PYTHONLIBS_FOUND)
    target_include_directories(pylibtest SYSTEM PRIVATE  ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
    target_link_libraries(pylibtest ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
endif()

library.cpp

#include "library.h"
#include <iostream>
void hello() {
    std::cout << "Hello, World!" << std::endl;
}
#include "library.h"
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(hello_ext)
{
    using namespace boost::python;
    def("hello", hello);
}

Собственно в ответ на Build получаю:

"C:\Program Files\CMake\bin\cmake.exe" --build "C:\ESI Cloud\Prog\Test\pylibtest\cmake-build-debug" --target pylibtest -- -j 6
Scanning dependencies of target pylibtest
[ 50%] Building CXX object CMakeFiles/pylibtest.dir/library.cpp.obj
[100%] Linking CXX shared library libpylibtest.dll
CMakeFiles\pylibtest.dir/objects.a(library.cpp.obj):C:/PROGRA~1/boost/BOOST_~1/boost/python/make_function.hpp:38: undefined reference to `__imp__ZN5boost6python7objects15function_objectERKNS1_11py_functionE'
CMakeFiles\pylibtest.dir/objects.a(library.cpp.obj):C:/PROGRA~1/boost/BOOST_~1/boost/python/def.hpp:91: undefined reference to `__imp__ZN5boost6python6detail17scope_setattr_docEPKcRKNS0_3api6objectES3_'
CMakeFiles\pylibtest.dir/objects.a(library.cpp.obj): In function `PyInit_hello_ext':
C:/ESI Cloud/Prog/Test/pylibtest/library.cpp:13: undefined reference to `__imp__ZN5boost6python6detail11init_moduleER11PyModuleDefPFvvE'
CMakeFiles\pylibtest.dir/objects.a(library.cpp.obj):C:/PROGRA~1/boost/BOOST_~1/boost/python/type_id.hpp:160: undefined reference to `__imp__ZN5boost6python6detail12gcc_demangleEPKc'
CMakeFiles\pylibtest.dir/objects.a(library.cpp.obj): In function `boost::python::converter::expected_pytype_for_arg<void>::get_pytype()':
C:/PROGRA~1/boost/BOOST_~1/boost/python/converter/pytype_function.hpp:67: undefined reference to `__imp__ZN5boost6python9converter8registry5queryENS0_9type_infoE'
C:/PROGRA~1/boost/BOOST_~1/boost/python/converter/pytype_function.hpp:70: undefined reference to `__imp__ZNK5boost6python9converter12registration25expected_from_python_typeEv'
CMakeFiles\pylibtest.dir/objects.a(library.cpp.obj): In function `boost::python::objects::caller_py_function_impl<boost::python::detail::caller<void (*)(), boost::python::default_call_policies, boost::mpl::vector1<void> > >::~caller_py_function_impl()':
C:/PROGRA~1/boost/BOOST_~1/boost/python/object/py_function.hpp:30: undefined reference to `__imp__ZN5boost6python7objects21py_function_impl_baseD2Ev'
CMakeFiles\pylibtest.dir/objects.a(library.cpp.obj):C:/PROGRA~1/boost/BOOST_~1/boost/python/object/py_function.hpp:30: undefined reference to `__imp__ZN5boost6python7objects21py_function_impl_baseD2Ev'
CMakeFiles\pylibtest.dir/objects.a(library.cpp.obj):library.cpp:(.rdata$_ZTVN5boost6python7objects23caller_py_function_implINS0_6detail6callerIPFvvENS0_21default_call_policiesENS_3mpl7vector1IvEEEEEE[_ZTVN5boost6python7objects23caller_py_function_implINS0_6detail6callerIPFvvENS0_21default_call_policiesENS_3mpl7vector1IvEEEEEE]+0x30): undefined reference to `boost::python::objects::py_function_impl_base::max_arity() const'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [CMakeFiles\pylibtest.dir\build.make:87: libpylibtest.dll] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:72: CMakeFiles/pylibtest.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:84: CMakeFiles/pylibtest.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:117: pylibtest] Error 2

Перелопатил реально много материала решая предыдущие ошибки с hypot и т.д., нашел разве что похожие вопросы без ответа на англоязчном стаке и багрепорты в boost и CMake. Уважаемое сообщество, если у вас есть какие-либо идеи по решению этой проблемы, пожалуйста поделись - я, к сожалению, свои уже исчерпал =(

UPD_1 Действительно, оно того стоило - find_package(Boost 1.68.0 REQUIRED python) и set(Boost_DEBUG ON) дали понимание того что ищется, а именно:

Searching for PYTHON_LIBRARY_RELEASE: libboost_python-mgw81-mt-1_68;libboost_python-mgw81-mt;libboost_python-mt-1_68;libboost_python-mt;libboost_python

Из чего стало ясно что, сборка либ предыдущим способом сформировала либы для msvc. Стал пересобирать boost следующим образом:

bootstrap.bat gcc
b2 toolset=gcc --build-type=complete address-model=64 --with-python stage -j12

Архитектура теперь определяется нормально (x64), однако проблемой стало то, что boost не собирается, информируя меня о куче ошибкок, как то:

...failed gcc.compile.c++ bin.v2\libs\python\build\gcc-8.1.0\debug\threading-multi\wrapper.o...
gcc.compile.c++ bin.v2\libs\python\build\gcc-8.1.0\debug\threading-multi\exec.o
In file included from C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/math.h:36,
                 from C:\Program Files\Python37\Include/pyport.h:191,
                 from C:\Program Files\Python37\Include/Python.h:53,
                 from ./boost/python/detail/wrap_python.hpp:151,
                 from ./boost/python/detail/prefix.hpp:13,
                 from ./boost/python/ssize_t.hpp:9,
                 from ./boost/python/object.hpp:8,
                 from ./boost/python/exec.hpp:8,
                 from libs\python\src\exec.cpp:6:
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/cmath:1121:11: error: '::hypot' has not been declared
   using ::hypot;
           ^~~~~
In file included from ./boost/python/detail/is_xxx.hpp:8,
                 from ./boost/python/detail/is_auto_ptr.hpp:9,
                 from ./boost/python/detail/copy_ctor_mutates_rhs.hpp:8,
                 from ./boost/python/detail/value_arg.hpp:7,
                 from ./boost/python/object/forward.hpp:10,
                 from ./boost/python/object/pointer_holder.hpp:16,
                 from ./boost/python/to_python_indirect.hpp:10,
                 from ./boost/python/converter/arg_to_python.hpp:10,
                 from ./boost/python/call.hpp:15,
                 from ./boost/python/object_core.hpp:14,
                 from ./boost/python/object.hpp:9,
                 from ./boost/python/exec.hpp:8,
                 from libs\python\src\exec.cpp:6:
./boost/python/detail/is_auto_ptr.hpp:17:40: warning: 'template<class> class std::auto_ptr' is deprecated [-Wdeprecated-declarations]
 BOOST_PYTHON_IS_XXX_DEF(auto_ptr, std::auto_ptr, 1)
                                        ^~~~~~~~
./boost/detail/is_xxx.hpp:20:4: note: in definition of macro 'BOOST_DETAIL_IS_XXX_DEF'
    qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, T) >        \
    ^~~~~~~~~~~~~~
./boost/python/detail/is_auto_ptr.hpp:17:1: note: in expansion of macro 'BOOST_PYTHON_IS_XXX_DEF'
 BOOST_PYTHON_IS_XXX_DEF(auto_ptr, std::auto_ptr, 1)
 ^~~~~~~~~~~~~~~~~~~~~~~
In file included from C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/memory:80,
                 from ./boost/config/no_tr1/memory.hpp:21,
                 from ./boost/get_pointer.hpp:14,
                 from ./boost/python/object/pointer_holder.hpp:11,
                 from ./boost/python/to_python_indirect.hpp:10,
                 from ./boost/python/converter/arg_to_python.hpp:10,
                 from ./boost/python/call.hpp:15,
                 from ./boost/python/object_core.hpp:14,
                 from ./boost/python/object.hpp:9,
                 from ./boost/python/exec.hpp:8,
                 from libs\python\src\exec.cpp:6:
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/unique_ptr.h:53:28: note: declared here
   template<typename> class auto_ptr;
                            ^~~~~~~~

Пересобрал раз 5 с разными опциями (bjam, b2, install и без него) в надежде что само пройдет, но неумолимо получаю:

...skipped <pbin.v2\libs\python\build\gcc-8.1.0\release\link-static\threading-multi>libboost_python37-mgw81-mt-x64-1_68.a(clean) for lack of <pbin.v2\libs\python\build\gcc-8.1.0\release\link-static\threading-multi>list.o...
...skipped <pbin.v2\libs\python\build\gcc-8.1.0\release\link-static\threading-multi>libboost_python37-mgw81-mt-x64-1_68.a for lack of <pbin.v2\libs\python\build\gcc-8.1.0\release\link-static\threading-multi>list.o...
...skipped <pstage\lib>libboost_python37-mgw81-mt-x64-1_68.a for lack of <pbin.v2\libs\python\build\gcc-8.1.0\release\link-static\threading-multi>libboost_python37-mgw81-mt-x64-1_68.a...
...skipped <pbin.v2\libs\python\build\gcc-8.1.0\release\link-static\threading-multi>libboost_python37-mgw81-mt-s-x64-1_68.a(clean) for lack of <pbin.v2\libs\python\build\gcc-8.1.0\release\link-static\threading-multi>list.o...
...skipped <pbin.v2\libs\python\build\gcc-8.1.0\release\link-static\threading-multi>libboost_python37-mgw81-mt-s-x64-1_68.a for lack of <pbin.v2\libs\python\build\gcc-8.1.0\release\link-static\threading-multi>list.o...
...skipped <pstage\lib>libboost_python37-mgw81-mt-s-x64-1_68.a for lack of <pbin.v2\libs\python\build\gcc-8.1.0\release\link-static\threading-multi>libboost_python37-mgw81-mt-s-x64-1_68.a...
...failed updating 108 targets...
...skipped 20 targets...

Есть ли у кого примеры, как все же правильно собирать boost под mingw-w64, возможно кто-нибудь уже сталкивался с подобными ошибками?

UPD_2

Собрал boost вот с такими ключами, вроде бы без ошибок, файлы либ появились:

bootstrap gcc 
b2 -j12 toolset=gcc runtime-link=shared architecture=x86 address-model=64 --with-python cxxflags="-D__int64=\"long long int\" -DBOOST_REGEX_MATCH_EXTRA -D__NO_INLINE__ -D_hypot=hypot"  --build-type=complete --layout=tagged stage

в CMakeList.txt внёс изменения:

set(Boost_DEBUG                 ON)
set(Boost_USE_STATIC_LIBS       ON)
set(Boost_USE_MULTITHREADED     ON)
set(Boost_USE_STATIC_RUNTIME    ON)
find_package(Boost 1.68.0 COMPONENTS python37 REQUIRED)

Ошибка с undefined reference to никуда не исчезла =(

UPD_Last

Всем спасибо, библиотека собирается и корректно работает без опций set(Boost_USE_STATIC_LIBS ON) и set(Boost_USE_STATIC_RUNTIME ON), почему так происходит - неизвестно на англоязычном стаке есть вопрос на эту тему, но он остался без ответа. Возможно требуется пересобрать boost с параметрами link=static и тогда эти флаги заработают, может и нет. Пока что обошелся тем, что собранные либы из stage/lib скопировал к генерируемой либе.pyd

READ ALSO
unicode символы в переменных

unicode символы в переменных

Можно ли как-то в gcc использовать названия переменных с unicode символами? Разрешено ли это стандартом?

140
К каким объектам можно применять moveToThread

К каким объектам можно применять moveToThread

Допустимо ли применять moveToThread к объекту, созданному на стеке? Например, так:

139
Узнать индекс элемента контейнера

Узнать индекс элемента контейнера

Хочу написать параллельный for_each, но внутри мне нужно знать индекс текущего обрабатываемого элементаКак его узнать без data race?

172
QLayout не изменяет размеры виджета

QLayout не изменяет размеры виджета

При изменении размеров родительского окна, меняется размер только у одного виджетаНеобходимо, чтобы они изменялись одновременно

156