Christiaan Maks
Christiaan Maks

Reputation: 3798

Pyinstaller ImportError with scipy: DLL load failed

I have this Python script I want to turn into an EXE file with Pyinstaller.

This is my spec file:

# -*- mode: python ; coding: utf-8 -*-

# work-around for https://github.com/pyinstaller/pyinstaller/issues/4064
import distutils
if distutils.distutils_path.endswith('__init__.py'):
    distutils.distutils_path = os.path.dirname(distutils.distutils_path)

block_cipher = None

a = Analysis(['hello-world.py'],
             pathex=['C:\\Users\\Testuser\\workspace\\hello-world'],
             binaries=[],
             datas=[ ('lib/*', '.') ],
             hiddenimports=[
               'distutils',
               'scipy._lib.messagestream',
               'sklearn.neighbors.typedefs',
               'sklearn.neighbors.quad_tree',
               'sklearn.tree',
               'sklearn.tree._utils'
             ],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='hello-world',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               upx_exclude=[],
               name='hello-world')

But I get this error when running it in a Win 10 64bit virtual machine:

Traceback (most recent call last):
  File "hello-world.py", line 11, in <module>
  File "c:\users\testuser\workspace\hello-world\.venv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 627, in exec_module
  File "site-packages\sklearn\__init__.py", line 76, in <module>
  File "c:\users\testuser\workspace\hello-world\.venv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 627, in exec_module
  File "site-packages\sklearn\base.py", line 16, in <module>
  File "c:\users\testuser\workspace\hello-world\.venv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 627, in exec_module
  File "site-packages\sklearn\utils\__init__.py", line 13, in <module>
  File "c:\users\testuser\workspace\hello-world\.venv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 627, in exec_module
  File "site-packages\scipy\sparse\__init__.py", line 230, in <module>
  File "c:\users\testuser\workspace\hello-world\.venv\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 627, in exec_module
  File "site-packages\scipy\sparse\csr.py", line 13, in <module>
ImportError: DLL load failed: The specified module could not be found.

The EXE runs fine on the machine I built it with. Copying the folder into the VM results in the above error. I'm not sure what DLL the error is referring to.

I'm guessing it has something to do with the paths in the error, as c:\users\testuser\workspace\hello-world does not exist in the VM. Is there a Pyinstaller option I'm missing here? Is the resulting EXE supposed to reference my old path?

Upvotes: 3

Views: 2202

Answers (1)

Christiaan Maks
Christiaan Maks

Reputation: 3798

It was because I didn't have the MKL versions of Numpy and SciPy installed.

After installing them I added the missing DLL files to the spec file:

datas=[
    ('lib/*', '.'),
    ('.venv/Lib/site-packages/numpy/DLLs/mkl_intel_thread.dll', '.'),
    ('.venv/Lib/site-packages/numpy/DLLs/mkl_core.dll', '.'),
    ('.venv/Lib/site-packages/numpy/DLLs/mkl_def.dll', '.'),
    ('.venv/Lib/site-packages/numpy/DLLs/libiomp5md.dll', '.')
],

And now it works in my virtual machine.

Hope this helps someone!

Upvotes: 4

Related Questions