#c #python-3.x #visual-studio #pybind11
#c #python-3.x #visual-studio #pybind11
Вопрос:
У меня есть модуль C , который я успешно предоставил python с помощью Pybind11.
Проблема в том, что я компилирую его под Windows 10 с помощью VS2019, и я хотел бы, чтобы модуль работал с Windows 7.
К сожалению, при установке модуля в том же чистом дистрибутиве python на компьютерах с Windows 7 я получаю ImportError: DLL load failed
сообщение об ошибке.
Когда я повторяю процедуру в Windows 10, все идет так, как ожидалось. Поэтому я полагаю, что это связано с каким-то параметром VS, чтобы сделать dll ретро-совместимой или что-то в этом роде.
Мой setup.py
файл такой:
import os
import re
import pathlib
import numpy
import sys
from sysconfig import get_paths
from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext as build_ext_orig
class CMakeExtension(Extension):
def __init__(self, name):
# don't invoke the original build_ext for this special extension
super().__init__(name, sources=[])
class build_ext(build_ext_orig):
def run(self):
# Add numpy headers to include_dirs
# self.include_dirs.append(numpy.get_include())
for ext in self.extensions:
# ext.include_dirs.insert(0, numpy.get_include())
self.build_cmake(ext)
super().run()
def build_cmake(self, ext):
# add the numpy include folder of associated to the numpy installed in the python executing this script
ext.include_dirs.insert(0, numpy.get_include())
cwd = pathlib.Path().absolute()
# these dirs will be created in build_py, so if you don't have
# any python sources to bundle, the dirs will be missing
build_temp = pathlib.Path(self.build_temp)
build_temp.mkdir(parents=True, exist_ok=True)
# extdir = pathlib.Path(self.get_ext_fullpath(ext.name))
extdir = pathlib.Path(pathlib.PurePath(self.get_ext_fullpath(ext.name)).with_suffix(''))
extdir.mkdir(parents=True, exist_ok=True)
# example of cmake args
config = 'Debug' if self.debug else 'Release'
path_info = get_paths()
cmake_args = [
'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' str(extdir.parent.absolute()), # LIBRARY_OUTPUT_DIRECTORY
'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE=' str(extdir.parent.absolute()), # LIBRARY_OUTPUT_DIRECTORY
'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG=' str(extdir.parent.absolute()), # LIBRARY_OUTPUT_DIRECTORY
'-DWITH_PYTHON_MODULE=ON',
'-DCMAKE_BUILD_TYPE=' config,
# python executable path of the python that executes this script
'-DPYTHON_EXECUTABLE=' sys.executable,
# path to the python include folder of the python that executes this script
'-DPYTHON_LIBRARY=' path_info['include'],
# properly pass the numpy include (works under windows too)
'-DPython_NumPy_FOUND=True',
'-DPython_NumPy_INCLUDE_DIRS=' numpy.get_include()
]
# example of build args
build_args = [
'--config', config,
'--target', 'NewtonNative'
]
# We can handle some platform-specific settings at our discretion
if os.name == 'nt':
cmake_args = [
# These options are likely to be needed under Windows
'-DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=TRUE',
'-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_{}={}'.format(config.upper(), extdir),
# python executable path of the python that executes this script
# '-DPYTHON_EXECUTABLE=' sys.executable,
# path to the python include folder of the python that executes this script
# '-DPYTHON_LIBRARY=' path_info['include'],
]
os.chdir(str(build_temp))
self.spawn(['cmake', str(cwd)] cmake_args)
if not self.dry_run:
self.spawn(['cmake', '--build', '.'] build_args)
# Troubleshooting: if fail on line above then delete all possible
# temporary CMake files including "CMakeCache.txt" in top level dir.
os.chdir(str(cwd))
def read_version(fname):
"""
Read the version from the CMake file
:param fname: file name
:return: version string
"""
version = "0.1.0" # set a default version
with open(fname) as file:
for l in file:
if 'NewtonNative' in l and 'VERSION' in l:
version = re.search('"(.*)"', l).group(1)
return version
return version
__version__ = read_version(os.path.join('src', 'CMakeLists.txt'))
setup(name='NewtonNative',
version=__version__,
author='',
author_email='',
url='',
description='',
long_description='',
ext_modules=[CMakeExtension('NewtonNative')],
cmdclass={'build_ext': build_ext},
install_requires=['pybind11>=2.4'],
setup_requires=['pybind11>=2.4'],
include_dirs=[numpy.get_include()],
zip_safe=False)
Как я могу скомпилировать для нескольких версий Windows?
Я думаю, это должно быть возможно, поскольку numpy и другим расширениям удается иметь одну версию для всех ОС Windows и зависеть только от версии python.