Ответ 1
Попробуйте шаблон манифеста:
http://docs.python.org/distutils/sourcedist.html#specifying-the-files-to-distribute
Быстрый сегодня: я изучаю библиотеку distutils из Pythons и из нее, и я хотел бы добавить модуль расширения python (.pyd) с моим пакетом. Я знаю, конечно, что рекомендуемый способ заключается в том, чтобы distutils скомпилировал расширение на момент создания пакета, но это довольно сложное расширение, охватывающее множество исходных файлов и ссылающееся на несколько внешних библиотек, поэтому он собирается провести значительную игру, чтобы получить все право на работу.
Тем временем у меня есть известная рабочая сборка расширения, выходящего из Visual Studio, и хотела бы использовать ее в установщике как временное решение, позволяющее мне сосредоточиться на других проблемах. Однако я не могу указать его как модуль, поскольку они, очевидно, должны иметь явное расширение .py. Как я могу указать в моей setup.py, что я хочу включить предварительно скомпилированный модуль расширения?
(Python 3.1, если это имеет значение)
Попробуйте шаблон манифеста:
http://docs.python.org/distutils/sourcedist.html#specifying-the-files-to-distribute
Я решил это, переопределив Extension.build_extension:
setup_args = { ... }
if platform.system() == 'Windows':
class my_build_ext(build_ext):
def build_extension(self, ext):
''' Copies the already-compiled pyd
'''
import shutil
import os.path
try:
os.makedirs(os.path.dirname(self.get_ext_fullpath(ext.name)))
except WindowsError, e:
if e.winerror != 183: # already exists
raise
shutil.copyfile(os.path.join(this_dir, r'..\..\bin\Python%d%d\my.pyd' % sys.version_info[0:2]), self.get_ext_fullpath(ext.name))
setup_args['cmdclass'] = {'build_ext': my_build_ext }
setup(**setup_args)
Попробуйте использовать package_data: http://docs.python.org/distutils/setupscript#installing-package-data
Я столкнулся с этой же проблемой при создании библиотеки расширений с использованием Python 3.7, CMake 3.15.3 и Swig 4.0.1 с Visual Studio 2017. Система сборки создает три файла: mymodule.py, _mymodule.lib и _mymodule.pyd. После множества проб и ошибок я нашел следующую комбинацию:
[metadata]
name = mymodule
version = 1.0
[options]
include_package_data = True
package_dir=
=src
packages=mymodule
python_requires '>=3.7'
[options.package_data]
* = *.pyd
setup.py
setup.cfg
src/
mymodule/
__init__.py
_mymodule.pyd
setup()
Для этого необходимо, чтобы CMake переименовал выходной файл mymodule.py в init.py. Я сделал это с помощью команды 'install' в CMake:
install (TARGETS ${SWIG_MODULE_${PROJECT_NAME}_REAL_NAME} DESTINATION "${CMAKE_BINARY_DIR}/dist/src/${PROJECT_NAME}")
install (FILES
setup.py
setup.cfg
DESTINATION "${CMAKE_BINARY_DIR}/dist"
)
install (FILES
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.py
DESTINATION "${CMAKE_BINARY_DIR}/dist/src/${PROJECT_NAME}"
RENAME "__init__.py"
Я полагаю, что ключевой секрет этой работы заключался в том, чтобы реструктурировать выходные данные сборки в виде пакета Python вместо того, чтобы пытаться заставить установку использовать выходные данные сборки по умолчанию в качестве сценария Python.