Я использую distutils для создания rpm из моего проекта. У меня есть это дерево каталогов:
project/
my_module/
data/file.dat
my_module1.py
my_module2.py
src/
header1.h
header2.h
ext_module1.cpp
ext_module2.cpp
swig_module.i
setup.py
MANIFEST.in
MANIFEST
мой setup.py
:
from distutils.core import setup, Extension
module1 = Extension('my_module._module',
sources=['src/ext_module1.cpp',
'src/ext_module2.cpp',
'src/swig_module.i'],
swig_opts=['-c++', '-py3'],
include_dirs=[...],
runtime_library_dirs=[...],
libraries=[...],
extra_compile_args=['-Wno-write-strings'])
setup( name = 'my_module',
version = '0.6',
author = 'microo8',
author_email = '[email protected]',
description = '',
license = 'GPLv3',
url = '',
platforms = ['x86_64'],
ext_modules = [module1],
packages = ['my_module'],
package_dir = {'my_module': 'my_module'},
package_data = {'my_module': ['data/*.dat']} )
мой MANIFEST.in
файл:
include src/header1.h
include src/header2.h
MANIFEST
файл автоматически генерируется python3 setup.py sdist
, И когда я бегу python3 setup.py bdist_rpm
он компилирует и создает правильные пакеты rpm. Но проблема в том, что когда я запускаю SWIG на источнике C ++, он создает module.py
файл, который упаковывает двоичный файл _module.cpython32-mu.so
файл, он создается с module_wrap.cpp
файл, и он не копируется в my_module
каталог.
Что я должен написать setup.py
файл для автоматического копирования генерируемых SWIG модулей Python?
А также у меня есть еще один вопрос: когда я устанавливаю пакет rpm, я хочу, чтобы исполняемый файл был создан в /usr/bin
или так, чтобы запустить приложение (например, если my_module/my_module1.py
это стартовый скрипт приложения, тогда я могу запустить в bash: $ my_module1
).
Проблема в том, что build_py
(который копирует исходники Python в каталог сборки) build_ext
, который работает SWIG.
Вы можете легко создать подкласс команды build и поменять местами порядок, так что build_ext
производит module1.py
до build_py
пытается скопировать это.
from distutils.command.build import build
class CustomBuild(build):
sub_commands = [
('build_ext', build.has_ext_modules),
('build_py', build.has_pure_modules),
('build_clib', build.has_c_libraries),
('build_scripts', build.has_scripts),
]
module1 = Extension('_module1', etc...)
setup(
cmdclass={'build': CustomBuild},
py_modules=['module1'],
ext_modules=[module1]
)
Однако есть одна проблема: если вы используете setuptools, а не просто distutils, python setup.py install
не будет запускать пользовательскую команду сборки. Это связано с тем, что команда установки setuptools сначала не запускает команду сборки, она запускает egg_info, затем install_lib, которая запускает build_py, а затем build_ext напрямую.
Поэтому, возможно, лучшим решением будет создание подкласса команд build и install и обеспечение запуска build_ext в начале обоих.
from distutils.command.build import build
from setuptools.command.install import install
class CustomBuild(build):
def run(self):
self.run_command('build_ext')
build.run(self)class CustomInstall(install):
def run(self):
self.run_command('build_ext')
self.do_egg_install()
setup(
cmdclass={'build': CustomBuild, 'install': CustomInstall},
py_modules=['module1'],
ext_modules=[module1]
)
Не похоже, что вам нужно беспокоиться о запуске build_ext дважды.
Это не полный ответ, потому что у меня нет полного решения.
Причина, по которой модуль не копируется в каталог установки, заключается в том, что его не было, когда процесс установки пытался скопировать его. Последовательность событий:
running install
running build
running build_py
file my_module.py (for module my_module) not found
file vcanmapper.py (for module vcanmapper) not found
running build_ext
Если вы запускаете второй раз python setup.py install
это будет делать то, что вы хотели в первую очередь. Официальная документация SWIG для Python предлагает вам запустить в первую очередь swig
создать файл обтекания, а затем запустить setup.py install
сделать фактическую установку.
Это выглядит как Вы должны добавить py_modules
вариант, например:
setup(...,
ext_modules=[Extension('_foo', ['foo.i'],
swig_opts=['-modern', '-I../include'])],
py_modules=['foo'],
)
Использование rpm для установки системных скриптов в Linux, вам придется изменить свой файл спецификации. %files
раздел рассказывает rpm
куда поместить файлы, которые вы можете переместить или на которые ссылаетесь в %post
, но такой может быть определяется в setup.py
с помощью:
options = {'bdist_rpm':{'post_install':'post_install', 'post_uninstall':'post_uninstall'}},
Запуск скриптов Python в Bash может быть сделано с обычной первой строкой, как #!/usr/bin/python
и исполняемый бит в файле с помощью chmod +x filename
,