gpt4 book ai didi

c++ - python distutils 不包括 SWIG 生成的模块

转载 作者:IT老高 更新时间:2023-10-28 21:04:21 26 4
gpt4 key购买 nike

我正在使用 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 = 'magyarvladimir@gmail.com',
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 包。但问题是,当我在 C++ 源代码上运行 SWIG 时,它会创建一个包装二进制 _module.cpython32-mu.so 文件的 module.py 文件,它是使用 module_wrap.cpp 文件创建,并且它没有复制到 my_module 目录。

我必须向 setup.py 文件写入什么来自动复制 SWIG 生成的 python 模块?

我还有另一个问题:当我安装 rpm 包时,我希望在 /usr/bin 左右创建一个可执行文件来运行应用程序(例如,如果my_module/my_module1.py 是应用程序的启动脚本,然后我可以在 bash 中运行:$ my_module1)。

最佳答案

问题在于 build_py(将 python 源代码复制到构建目录)在运行 SWIG 的 build_ext 之前。

您可以轻松地将构建命令子类化并交换顺序,因此 build_extbuild_py 尝试复制它之前生成 module1.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 install 命令实际上并没有先运行 build 命令,它运行的是 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 会运行两次。

关于c++ - python distutils 不包括 SWIG 生成的模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12491328/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com