Я создаю пакет Python с расширением C ++. Я пытаюсь сделать это с помощью setuptools, так как это кажется предпочтительным решением. Учитывая, что он допускает setup_requires, install_requires, я согласен и использую его только для моих пакетов на python. Однако я не могу заставить его работать, когда у меня есть модуль расширения c ++. Тогда я прибегаю к distutils.core, чтобы заставить его работать. Я хотел бы знать, как заставить это работать, используя setuptools. Мой скрипт установки выглядит так
from setuptools import setup
import shutil
import os
# folder where .so is being build by cpp compilation
so_src = os.path.join(dir, 'cpp/build/')
# folder where .so should live in python package
so_des = os.path.join(dir, 'package_py/cpp/')
# extension module
lib_files = ['cpp_py.so']
# copy shared lib
for f in lib_files:
shutil.copyfile(so_src + f, so_des + f)
# set-up script
setup(
name=DISTNAME
, version=FULLVERSION
, description= DESCRIPTION
, author= AUTHOR
, author_email= EMAIL
, maintainer= AUTHOR
, maintainer_email= EMAIL
, long_description=LONG_DESCRIPTION
, packages=['package_py',
'package_py.cpp']
, package_dir={'package_py.cpp': 'package_py/cpp'}
, package_data={'package_py.cpp': lib_files}
)
Это приводит к файлу package_py-0.0.1-py3.6.egg в моих пакетах сайта python. Посылка только работает при использовании из папки установки.
Изменение первой строки для использования distutils.core вместо setuptools
from distutils.core import setup # only change, remainder is the same!!
import shutil
import os
# folder where .so is being build by cpp compilation
so_src = os.path.join(dir, 'cpp/build/')
# folder where .so should live in python package
so_des = os.path.join(dir, 'package_py/cpp/')
# extension module
lib_files = ['cpp_py.so']
# copy shared lib
for f in lib_files:
shutil.copyfile(so_src + f, so_des + f)
# set-up script
setup(
name=DISTNAME
, version=FULLVERSION
, description= DESCRIPTION
, author= AUTHOR
, author_email= EMAIL
, maintainer= AUTHOR
, maintainer_email= EMAIL
, long_description=LONG_DESCRIPTION
, packages=['package_py',
'package_py.cpp']
, package_dir={'package_py.cpp': 'package_py/cpp'}
, package_data={'package_py.cpp': lib_files}
)
Я получаю папку package_py (с файлом .so) и package_py-0.0.1-py3.6.egg-info в пакетах сайта. Теперь модуль работает во всех папках.
Поскольку я хотел бы расширить пакет python, чтобы он также использовал setup_requires, instal_requires, я хочу действительно использовать setuptools. Как я могу заставить пакет работать во всех папках, используя setuptools вместо distutils.core
Если вы используете расширение C, вы должны использовать Extension
от любого setuptools
или же distutils
Кроме того, это не пакет Python, поэтому я удивлен, что ему даже удается установить. Если вы планируете распространять пакет среди других, вам не следует предварительно скомпилировать расширение, а скомпилировать его во время установки пакета, чтобы система пользователя скомпилировала его соответствующим образом (т.е. .so
файл не помогает пользователю Windows, который нуждается в его компиляции в .dll
файл и т. д.).
Попробуйте что-то вроде этого:
from setuptools import setup, Extension
import shutil
import os
# I don't know how you want to build your extension or your file structure,
# so removing the build stuff.
your_modulename=Extension('_extensionname',
sources=['path/to/extension.cpp', 'more/file/paths'],
language='c'
)# set-up script
setup(
name=DISTNAME
, version=FULLVERSION
, description= DESCRIPTION
, author= AUTHOR
, author_email= EMAIL
, maintainer= AUTHOR
, maintainer_email= EMAIL
, long_description=LONG_DESCRIPTION
, ext_modules=[your_modulename]
, packages=['package_py']
)
Надеюсь, это поможет или, по крайней мере, приведет вас на правильный путь.
Других решений пока нет …