如何用PyInstaller正确打包含ortools及.pyd依赖的Python可执行文件
问题根因
你遇到的ImportError: DLL load failed while importing _pywraplp和你推测的原因无关:
- 从本地运行日志可以确认,
_pywraplp.pyd已经被正确打包到分发包的ortools/linear_solver/目录下,不存在“未入内置归档、依赖本地路径”的问题。 - 报错的核心原因是你手动配置的打包规则不完整:只单独拷贝了
_pywraplp.pyd单个文件,没有把该文件依赖的ortools配套动态库(比如内置求解器的底层dll)一起纳入打包范围。 - 本地电脑能正常运行,是因为Python安装目录、系统PATH里存在这些依赖DLL;干净的Windows沙箱没有这些文件,加载pyd时就会因为找不到关联依赖直接失败。
注意:你之前的配置里把
_pywraplp.pyd同时加到binaries和datas列表里是完全冗余的,PyInstaller会重复打包同一个文件,既不会解决依赖缺失的问题,还会增大分发包体积。
正确配置实现
修正思路
不要再手动单独指定单个pyd文件的打包规则,改用PyInstaller提供的官方依赖收集工具,自动扫描ortools包的全量二进制、资源文件和模块导入,避免漏带依赖。
完整spec配置代码
把原有spec文件替换为如下内容:
# -*- mode: python ; coding: utf-8 -*- import os from PyInstaller.utils.hooks import collect_all block_cipher = None # 自动全量收集ortools包的所有依赖 # 收集内容包括:所有dll/pyd二进制、包内资源文件、需要导入的隐藏模块 ortools_datas, ortools_binaries, ortools_hiddenimports = collect_all('ortools') a = Analysis( ['my_program.py'], pathex=[ 'C:\\Users\\<My Name>\\<My Path>\\project_files', # 你的项目根目录路径 # 自动定位ortools所在的site-packages路径,无需手动写死 os.path.dirname(os.path.dirname(__import__('ortools').__file__)) ], binaries=ortools_binaries, # 替换原手动配置的单pyd条目 datas=ortools_datas, # 替换原手动配置的单pyd条目 hiddenimports=ortools_hiddenimports, # 替换原手动列的少量导入 hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, # 开启私有程序集配置,自动绑定VC运行库,不依赖系统全局组件 win_private_assemblies=True, cipher=block_cipher, noarchive=False ) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE( pyz, a.scripts, [('v', None, 'OPTION')], exclude_binaries=True, name='my_program', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, console=True, icon='graph_icon.ico' ) coll = COLLECT( exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, # 排除ortools目录下所有文件的UPX压缩,避免压缩破坏二进制加载 upx_exclude=['ortools\\*'], name='my_program' )
关键配置说明
collect_all('ortools')会遍历ortools安装目录下的所有文件,自动把包括_pywraplp.pyd在内的所有pyd、dll文件打包到分发包的对应目录结构下,不会遗漏任何关联依赖。win_private_assemblies=True会把程序依赖的Microsoft Visual C++ 运行库dll和程序绑定,即使沙箱没有全局安装VC++组件也能正常加载。upx_exclude=['ortools\\*']是因为UPX对包含C++符号表的求解器dll、pyd压缩后,容易出现加载失败的问题,必须排除这部分文件的压缩。
验证方法
打包完成后,不要依赖本地项目目录的任何文件,直接把整个dist/my_program文件夹拷贝到干净的Windows沙箱中运行,即可正常加载ortools的线性求解模块。
内容的提问来源于stack exchange,提问作者hkod
相关产品推荐
相关产品推荐

