使用py2exe生成的EXE调用绘图程序时无法加载intel_mkl_thread.dll求助
我之前也碰到过一模一样的情况——用py2exe打包了主GUI和几个子EXE,本地跑完全没问题,部署到其他机器上调用子EXE就报Intel MKL Fatal Error: Cannot load intel_mkl_thread.dll,明明DLL都在每个dist文件夹里。给你几个亲测有效的解决思路:
指定子EXE的工作目录
主GUI调用子EXE时,子进程默认的工作目录是主GUI的运行目录,而不是子EXE所在的dist文件夹,导致它找不到自己目录下的MKL DLL。调用子进程时明确指定工作目录为子EXE的所在路径就行,比如用subprocess的话:import subprocess import os # 替换成你的绘图EXE实际路径 drawing_exe_path = os.path.join(os.getcwd(), "sub_dist", "drawing_exe.exe") subprocess.Popen( [drawing_exe_path], # 关键:设置工作目录为子EXE所在文件夹 cwd=os.path.dirname(drawing_exe_path) )共享MKL DLL到主目录
既然每个dist都有重复的MKL DLL,不如把所有MKL相关的核心DLL(比如intel_mkl_thread.dll、mkl_core.dll、libiomp5md.dll等)统一放到主GUI的dist文件夹里,然后让子EXE共享这些DLL。打包子EXE时可以修改setup.py,跳过复制这些DLL:from distutils.core import setup import py2exe setup( console=["drawing_exe.py"], options={ "py2exe": { # 排除已在主程序目录的MKL DLL "dll_excludes": ["intel_mkl_thread.dll", "mkl_core.dll", "libiomp5md.dll"] } } )这样既减少了打包体积,又能让子EXE从主程序目录找到依赖的DLL。
临时修改PATH环境变量
在调用子EXE之前,把子EXE所在的dist目录添加到系统PATH的最前面,让系统优先搜索这个路径下的DLL:import os import subprocess drawing_exe_dir = os.path.join(os.getcwd(), "sub_dist") original_path = os.environ.get("PATH", "") # 把子EXE目录加到PATH最前面 os.environ["PATH"] = f"{drawing_exe_dir};{original_path}" # 调用子EXE subprocess.Popen([os.path.join(drawing_exe_dir, "drawing_exe.exe")]) # 可选:调用完成后恢复原来的PATH os.environ["PATH"] = original_path统一Python环境与MKL版本
有时候不同EXE打包时用了不同的Python环境,导致MKL版本不兼容,也会出现加载失败。确保所有程序都是用同一个Python环境打包的,且该环境下的MKL是完整安装的。另外可以检查一下子EXE的dist目录里,是否缺少MKL依赖的其他辅助DLL(比如libiomp5md.dll这类OpenMP相关的文件),如果有的话补上就行。
内容的提问来源于stack exchange,提问作者Novice

