setup.py не устанавливает модуль расширения swig - PullRequest
3 голосов
/ 12 июня 2019

Я пытаюсь понять, как скопировать оболочку, сгенерированную swig на том же уровне, что и разделяемая библиотека swig. Рассмотрим эту древовидную структуру:

│   .gitignore
│   setup.py
│
├───hello
├───src
│       hello.c
│       hello.h
│       hello.i
│
└───test
        test_hello.py

и этот setup.py:

import os
import sys

from setuptools import setup, find_packages, Extension
from setuptools.command.build_py import build_py as _build_py


class build_py(_build_py):
    def run(self):
        self.run_command("build_ext")
        return super().run()


setup(
    name='hello_world',
    version='0.1',
    cmdclass={'build_py': build_py},
    packages=["hello"],
    ext_modules=[
        Extension(
            'hello._hello',
            [
                'src/hello.i',
                'src/hello.c'
            ],
            include_dirs=[
                "src",
            ],
            depends=[
                'src/hello.h'
            ],
        )
    ],
    py_modules=[
        "hello"
    ],
)

Когда я сделаю pip install ., я получу этот контент в пакетах сайта:

>tree /f d:\virtual_envs\py364_32\Lib\site-packages\hello                            
D:\VIRTUAL_ENVS\PY364_32\LIB\SITE-PACKAGES\HELLO                                                                 
    _hello.cp36-win32.pyd                                                                                        


>tree /f d:\virtual_envs\py364_32\Lib\site-packages\hello_world-0.1.dist-info        
D:\VIRTUAL_ENVS\PY364_32\LIB\SITE-PACKAGES\HELLO_WORLD-0.1.DIST-INFO                                             
    INSTALLER                                                                                                    
    METADATA                                                                                                     
    RECORD                                                                                                       
    top_level.txt                                                                                                
    WHEEL  

Как видите, hello.py (файл, созданный swig) не был скопирован в site-packages.

Дело в том, что я уже перепробовал много ответов из постов, подобных ниже:

К сожалению, вопрос все еще остается нерешенным.

ВОПРОС: Как исправить мой текущий файл setup.py, чтобы оболочка swig копировалась на том же уровне, что и файл .pyd?

1 Ответ

0 голосов
/ 21 июня 2019

setuptools не может сделать это так, как вы хотите: он будет искать py_modules только там, где setup.py. Самый простой способ IMHO - сохранить модули SWIG там, где вы хотите, в структуре пространства имен / каталогов: переименуйте src в hello и добавьте hello/__init__.py (может быть пустым или просто включать все, начиная с hello.hello), оставляя вас с этим деревом:

$ tree .
.
├── hello
│   ├── __init__.py
│   ├── _hello.cpython-37m-darwin.so
│   ├── hello.c
│   ├── hello.h
│   ├── hello.i
│   ├── hello.py
│   └── hello_wrap.c
└── setup.py

Удалить py_modules из setup.py. "hello" в списке package заставит setuptools забрать весь пакет, включая __init__.py и сгенерированный hello.py:

import os
import sys

from setuptools import setup, find_packages, Extension
from setuptools.command.build_py import build_py as _build_py


class build_py(_build_py):
    def run(self):
        self.run_command("build_ext")
        return super().run()


setup(
    name='hello_world',
    version='0.1',
    cmdclass={'build_py': build_py},
    packages = ["hello"],
    ext_modules=[
        Extension(
            'hello._hello',
            [
                'hello/hello.i',
                'hello/hello.c'
            ],
            include_dirs=[
                "hello",
            ],
            depends=[
                'hello/hello.h'
            ],
        )
    ],
)

Таким образом, также .egg-link пакет работает (python setup.py develop), так что вы можете связать разрабатываемый пакет в venv или около того. Это также является причиной того, как работает setuptoolsdistutils): песочница для разработчиков должна быть структурирована таким образом, чтобы можно было запускать код непосредственно из нее, не перемещая модули.

Сгенерированный SWIG hello.py и сгенерированное расширение _hello будут жить в hello:

>>> from hello import hello, _hello
>>> print(hello)
<module 'hello.hello' from '~/so56562132/hello/hello.py'>
>>> print(_hello)
<module 'hello._hello' from '~/so56562132/hello/_hello.cpython-37m-darwin.so'>

(как вы можете видеть из расширения имени файла, я сейчас нахожусь на Mac, но в Windows это работает точно так же)

Кроме того, помимо руководства, в руководстве SWIG есть более полезная информация о пространствах имен и пакетах SWIG и Python: http://swig.org/Doc4.0/Python.html#Python_nn72

...