编译适用于大多数Windows OS版本的pybind11 python模块

问题描述

我有一个C ++模块,我已经使用Pybind11成功地将其公开给python。

问题是我正在Windows 10下使用VS2019进行编译,我希望该模块可在Windows 7下使用。

不幸的是,在Windows 7计算机上的同一干净的python发行版中安装模块时,出现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版本。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)