无法在 python 可执行文件上加载 mkl_intel_thread.dll

Cannot load mkl_intel_thread.dll on python executable

我正在尝试创建一个可在 windows 上运行但未安装 python 的可执行 python 程序,为此我正在使用 cx_Freeze。但是我收到以下错误:"Cannot load mkl_intel_thread.dll"

在我安装了 python (miniconda3) 的 PC 上,我使用 cx_Freeze 构建了可执行文件,当我 运行 可执行文件时,我也会得到 "Cannot load mkl_intel_thread.dll".我通过转到我的 python 文件夹 Library\bin 并将 mkl_intel_thread.dll 文件复制到放置可执行文件的位置来修复此问题。问题是,当将整个文件夹移动到另一台 PC(未安装 python)时,此错误再次出现,即使 mkl_intel_thread.dll 在文件夹中。

我要分发的文件 (plot.py):

import matplotlib.pyplot as plt

a = [0, 1, 2]
b = [0, 2, 0]
plt.fill(a, b, 'b')
plt.show()

cx_Freeze 安装文件 (setup.py):

import cx_Freeze
import sys
import matplotlib
import numpy
import os

os.environ['TCL_LIBRARY'] = "C:\Miniconda3\tcl\tcl8.6"
os.environ['TK_LIBRARY'] = "C:\Miniconda3\tcl\tk8.6"


executables = [cx_Freeze.Executable("plot.py")]


build_exe_options = {"includes":['numpy.core._methods',
        'numpy.lib.format', 'matplotlib.backends.backend_tkagg']}

cx_Freeze.setup(
    name = "script",
    options = {"build_exe": build_exe_options},
    version = "0.0",
    description = "A basic example",
    executables = executables)

编辑:

  1. 尝试将在 Library\binnumpy\core 下找到的所有以 mkl 开头的文件复制到构建文件夹中,以及 libiomp5md.dll,参见 Python Pyinstaller 3.1 Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll and

    一旦您找到需要手动复制的文件,您可以使用 include_files 列表让 cx_Freeze 包含必要的文件build_exe 选项(参见下面的代码片段)。如有必要,您可以使用元组 (source, destination) 作为 include_files 列表中的项目,让 cx_Freeze 将文件从 source 复制到特定的 destination 到构建中目录,请参阅 cx_Freezedocumentation

  2. 我发现您在问题中发布的设置脚本还有更多潜在问题:

    • 使用 build_exe 选项的 packages 列表包含整个 numpy 包,这样更容易也可能更安全
    • 动态找出 TCL/TK DLLs
    • 的位置更安全
    • 对于 cx_Freeze 5.1.1,TCL/TK DLL 需要包含在构建目录的 lib 子目录中

综上所述,尽量使用

PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')

build_exe_options = {'packages': ['numpy'],
                     'includes': ['matplotlib.backends.backend_tkagg'],
                     'include_files': [(os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'),
                                        os.path.join('lib', 'tcl86t.dll')),
                                       (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'),
                                        os.path.join('lib', 'tk86t.dll'))
                                       # add here further files which need to be included as described in 1.
                                      ]}

在您的设置脚本中。

只需将这四个文件复制到cx_freeze生成的构建文件夹

mkl_core.dll
mkl_def.dll
mkl_intel_thread.dll
mkl_mc3.dll

类似的问题影响 cx_Freeze 6.1 或 6.2:可执行文件无法启动,没有错误消息或有

INTEL MKL ERROR: The specified module could not be found. mkl_intel_thread.dll.
Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll.

配置:

Python 3.6.8 或更早版本的 numpy 也可以观察到这种情况,例如1.18.4+mkl 或 1.19.0+mkl.

我观察到 cx_Freeze 在构建目录的子目录 lib\numpy\core 中包含 3 个 DLL mkl_rt.dllpython38.dllvcruntime140.dll,而原始安装在子目录 site-packages\numpy\core 中不包含任何 DLL(所有 DLL 都在 site-packages\numpy\DLLs 中)。如果我在使用 cx_Freeze 构建应用程序后手动从构建目录的子目录 lib\numpy\core 中删除 mkl_rt.dll,问题就会消失并且应用程序可以运行。

可以通过在 setup.py 脚本末尾添加以下代码来实现此解决方案:

numpy_core_dir = os.path.join(dist_dir, 'lib', 'numpy', 'core')
for file_name in os.listdir(numpy_core_dir):
    if file_name.lower().endswith('.dll'):
        file_path = os.path.join(numpy_core_dir, file_name)
        os.remove(file_path)

其中 dist_dir 是由 cx_Freeze 生成的构建目录(传递给 build_exe 选项)。

设法通过在使用 cx_Freeze==6.5.3 时将 numpy==1.18.2 从 numpy==1.19.1 降级来找到解决方案。