20

プロジェクトからrpmを作成するためにdistutilsを使用しています。私はこのディレクトリツリーを持っています:

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.py、バイナリファイルをラップするファイル_module.cpython32-mu.soが作成され、そのファイルとともに作成module_wrap.cppされ、ディレクトリにコピーされないことmy_moduleです。

setup.pySWIGで生成されたPythonモジュールを自動的にコピーするには、ファイルに何を書き込む必要がありますか?

また、別の質問があります。rpmパッケージをインストールするときに/usr/bin、アプリケーションを実行するために実行可能ファイルを作成する必要があります(たとえば、my_module/my_module1.pyがアプリケーションの開始スクリプトである場合は、bashで実行できます。$ my_module1)。

4

3 に答える 3

12

問題は、build_py(Pythonソースをビルドディレクトリにコピーする)build_extがSWIGを実行するの前に来ることです。

ビルドコマンドを簡単にサブクラス化して順序を入れ替えることができるため、コピーを試みる前にをbuild_ext生成します。module1.pybuild_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]
)

ただし、これには1つの問題があります。単なるdistutilsではなくsetuptoolsを使用している場合、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が2回実行されることを心配する必要はないようです。

于 2014-01-20T14:08:09.497 に答える
1

私には完全な解決策がないので、それは完全な答えではありません。モジュールがインストールディレクトリにコピーされない理由は、セットアッププロセスがモジュールをコピーしようとしたときにモジュールが存在しなかったためです。イベントのシーケンスは次のとおりです。

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

2回目に実行するpython setup.py installと、最初に必要な処理が実行されます。Pythonの公式SWIGドキュメントでは、最初に実行swigしてラップファイルを生成し、次に実行setup.py installして実際のインストールを実行することを提案しています。

于 2013-04-08T15:25:24.453 に答える
0

オプションを追加する必要があるよう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'}},

BashでPythonスクリプトを実行するには、ファイルの通常の最初の行#!/usr/bin/pythonと実行可能ビットを使用して実行できますchmod +x filename

于 2012-09-19T09:56:01.177 に答える