Расширение C ++ для Python с библиотеками stati c - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь разработать расширение Python, используя Boost. Python. Когда я пытаюсь запустить результирующую библиотеку в какой-то системе, она жалуется на некоторые отсутствующие библиотеки (libboost_ python3 -py36.so ... & libboost_numpy3-py36.so ....) - после установки этих библиотек на система, все работает отлично. Однако я предпочел бы устранить эту зависимость и подумал, что связывание отсутствующих библиотек надстройки - статически - решит мою проблему.

Первый вопрос: будет ли связывание с stati c обеспечивать такое желаемое поведение, чтобы расширение Python работало без необходимости устанавливать библиотеки boost в целевой системе? Или есть другой, возможно, более элегантный подход?

Следуя советам, данным в StackOverflow и в документации CMake , я предложил следующий подход:

CMakeLists.txt:

cmake_minimum_required(VERSION 3.13)
project(PythonTest)

set(CMAKE_VERBOSE_MAKEFILE ON)

set(CMAKE_CXX_FLAGS "-O3")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Taken from StackOverflow answer
add_definitions(-DBOOST_PYTHON_STATIC_LIB)

# Taken from findpython documentation
#set(Python3_USE_STATIC_LIBS TRUE)
#set(Python3_ROOT_DIR "/usr/local/lib/python3.7")
set (CMAKE_FIND_FRAMEWORK NEVER)
find_package(Python3 3.7 EXACT COMPONENTS Development REQUIRED)
find_package(Boost COMPONENTS python3 numpy3 REQUIRED)

Python3_add_library(PythonTestExtension MODULE ${CMAKE_CURRENT_LIST_DIR}/PythonParserBinding.cpp)
target_compile_definitions(PythonTestExtension PUBLIC PYTHON_PARSER)
target_include_directories(PythonTestExtension PUBLIC ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS} ${LIBLOGFILEPARSER_INCLUDE})
target_link_libraries(PythonTestExtension PUBLIC ${Boost_LIBRARIES} ${Python3_LIBRARIES})

PythonBinding. cpp

#include <boost/python.hpp>
#include <boost/python/dict.hpp>
#include <boost/python/numpy.hpp>
#include <string>
#include <iostream>

namespace np = boost::python::numpy;

boost::python::dict testFunction(const std::string input){
    boost::python::dict result;
    return result;
}

BOOST_PYTHON_MODULE(PyLogFileParser) {
  Py_Initialize();
  np::initialize();
  boost::python::def("testFunction", testFunction);
}

Когда я компилирую код, как здесь дано, я все еще вижу, что полученная библиотека (PythonTestExtension. поэтому) требует две библиотеки повышения, которые я хотел связать статически - я проверил это, используя ldd PythonTestExtension.so. Я делаю что-то не так в своем файле CMake, что каким-то образом мешает компоновщику использовать библиотеки stati c?

Если я использую флаг Python3_USE_STATIC_LIBS из CMake, возникает несколько ошибок типа

error: /usr/lib/x86_64-linux-gnu/libpython3.7m.a(dictobject.o): relocation R_X86_64_32 against symbol `PyDictValues_Type' can not be used when making a shared object; recompile with -fPIC

Чтобы убедиться, что -fPIC активирован, я установил флаг CMAKE_POSITION_INDEPENDENT_CODE. Я нашел некоторую разрозненную информацию о том, что это можно решить, построив Python с флагом --enable-shared. Однако моя проблема в том, что я не знаю, как заставить findpython использовать локально собранную библиотеку Python - это можно сделать с помощью Python3_ROOT_DIR?

Я использую Ubuntu 18.04 с CMake 3.14.1, boost 1.65.1 и Python 3.7.5.

Заранее спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...