Package nur binär kompilierte .so-Dateien einer mit Cython kompilierten Python-Bibliothek

Ich habe ein Paket mit dem Namenmypack was drinnen hat ein Modulmymod.py, und die__init__.py. Aus irgendeinem Grund, der nicht diskutiert wird, muss ich dieses kompilierte Modul packen (weder .py- noch .pyc-Dateien sind zulässig). Das heißt, das__init__.py ist die einzige Quelldatei, die in der verteilten komprimierten Datei zulässig ist.

Die Ordnerstruktur lautet:

. 
│  
├── mypack
│   ├── __init__.py
│   └── mymod.py
├── setup.py

Ich stelle fest, dass Cython dazu in der Lage ist, indem jede .py-Datei in eine .so-Bibliothek konvertiert wird, die direkt mit Python importiert werden kann.

Die Frage ist: wie diesetup.py Datei muss sein, um eine einfache Verpackung und Installation zu ermöglichen?

Das Zielsystem verfügt über eine virtuelle Umgebung, in der das Paket mit einer beliebigen Methode installiert werden muss, die eine einfache Installation und Deinstallation ermöglicht (easy_install, pip usw. sind alle willkommen).

Ich habe alles versucht, was in meiner Reichweite war. Ich lesesetuptools unddistutils -Dokumentation, alle Fragen zum Stackoverflow und Versuche mit allen Arten von Befehlen (sdist, bdist, bdist_egg usw.) mit vielen Kombinationen von setup.cfg- und MANIFEST.in-Dateieinträgen.

Das nächste, was ich bekommen habe, war mit der folgenden Setup-Datei, die den Befehl bdist_egg unterklassifizieren würde, um auch .pyc-Dateien zu entfernen, aber das bricht die Installation ab.

Eine Lösung, bei der die Dateien auf dem venv "manuell" installiert werden, ist ebenfalls gut, vorausgesetzt, alle Zusatzdateien, die in einer ordnungsgemäßen Installation enthalten sind, werden abgedeckt (ich muss @ ausführenpip freeze im venv und siehemymod==0.0.1).

Run it with:

python setup.py bdist_egg --exclude-source-files

und (versuchen) es mit @ zu installier

easy_install mymod-0.0.1-py2.7-linux-x86_64.egg

Wie Sie vielleicht bemerken, ist das Ziel Linux 64-Bit mit Python 2.7.

from Cython.Distutils import build_ext
from setuptools import setup, find_packages
from setuptools.extension import Extension
from setuptools.command import bdist_egg
from setuptools.command.bdist_egg import  walk_egg, log 
import os

class my_bdist_egg(bdist_egg.bdist_egg):

    def zap_pyfiles(self):
        log.info("Removing .py files from temporary directory")
        for base, dirs, files in walk_egg(self.bdist_dir):
            for name in files:
                if not name.endswith('__init__.py'):
                    if name.endswith('.py') or name.endswith('.pyc'):
                        # original 'if' only has name.endswith('.py')
                        path = os.path.join(base, name)
                        log.info("Deleting %s",path)
                        os.unlink(path)

ext_modules=[
    Extension("mypack.mymod", ["mypack/mymod.py"]),
]

setup(
  name = 'mypack',
  cmdclass = {'build_ext': build_ext, 
              'bdist_egg': my_bdist_egg },
  ext_modules = ext_modules,
  version='0.0.1',
  description='This is mypack compiled lib',
  author='Myself',
  packages=['mypack'],
)

AKTUALISIEREN. Nach der Antwort von @Teyras war es möglich, ein Rad zu bauen, wie in der Antwort gefordert. Dassetup.pynhalt der @ -Datei ist:

import os
import shutil
from setuptools.extension import Extension
from setuptools import setup
from Cython.Build import cythonize
from Cython.Distutils import build_ext

class MyBuildExt(build_ext):
    def run(self):
        build_ext.run(self)
        build_dir = os.path.realpath(self.build_lib)
        root_dir = os.path.dirname(os.path.realpath(__file__))
        target_dir = build_dir if not self.inplace else root_dir
        self.copy_file('mypack/__init__.py', root_dir, target_dir)

    def copy_file(self, path, source_dir, destination_dir):
        if os.path.exists(os.path.join(source_dir, path)):
            shutil.copyfile(os.path.join(source_dir, path), 
                            os.path.join(destination_dir, path))


setup(
  name = 'mypack',
  cmdclass = {'build_ext': MyBuildExt},
  ext_modules = cythonize([Extension("mypack.*", ["mypack/*.py"])]),
  version='0.0.1',
  description='This is mypack compiled lib',
  author='Myself',
  packages=[],
  include_package_data=True )

Der entscheidende Punkt war, @ zu setzpackages=[],. Das Überschreiben desbuild_ext classrun -Methode wurde benötigt, um das @ zu erhalt__init__.py Datei im Lenkrad.

Antworten auf die Frage(6)

Ihre Antwort auf die Frage