Je suis nouveau avec les applications python. J'essaie de créer mon application graphique python avec pyinstaller . Mon application dépend des packages suivants: PyQt4, numpy, pyqtgraph, h5py . Je travaille avec WinPython-32bit-3.4.4.1.
Je construis l'application avec cette commande:
pyinstaller --hidden-import=h5py.defs --hidden-import=h5py.utils --hidden-import=h5py.h5ac --hidden-import=h5py._proxy VOGE.py
Je lance mon application avec le fichier exe dans le répertoire dist créé par pyinstaller et il semble bien fonctionner jusqu'à ce que le programme appelle numpy et plante avec cette erreur:
Intel MKL FATAL ERROR: Impossible de charger mkl_intel_thread.dll
Le fichier mkl_intel_thread.dll n'est pas présent dans le répertoire du logiciel; mais avec le fichier copié dans le répertoire racine du programme, j'ai la même erreur
Merci de votre aide
J'ai créé un hook-numpy.py
pour traiter ce problème:
from PyInstaller import log as logging
from PyInstaller import compat
from os import listdir
libdir = compat.base_prefix + "/lib"
mkllib = filter(lambda x : x.startswith('libmkl_'), listdir(libdir))
if mkllib <> []:
logger = logging.getLogger(__name__)
logger.info("MKL installed as part of numpy, importing that!")
binaries = map(lambda l: (libdir + "/" + l, ''), mkllib)
Dans mon cas, conda
installe les bibliothèques mkl pour accélérer numpy
et scipy
.
J'ai eu le même problème en utilisant Pyinstaller et Numpy. Par défaut, pyinstaller ne semble pas prendre en compte les fichiers binaires numpy, vous devez donc le spécifier manuellement. Vous pouvez ajouter les fichiers en modifiant la variable "binaires" du fichier ".spec", mais cela ne fonctionnera que pour votre programme actuel. Si vous voulez que cela fonctionne pour tous les programmes que vous avez bloqués, vous devez créer un "hook" et l'enregistrer dans C:\Python3 *\Lib\site-packages\PyInstaller\hooks.
J'ai dû adapter le code de LeonidR pour que le Numpy-hook fonctionne. Je l'ai réécrit en utilisant une approche plus moderne, Pythonic, en utilisant des compréhensions de liste:
from PyInstaller import log as logging
from PyInstaller import compat
from os import listdir
mkldir = compat.base_prefix + "/Lib/site-packages/numpy/core"
logger = logging.getLogger(__name__)
logger.info("MKL installed as part of numpy, importing that!")
binaries = [(mkldir + "/" + mkl, '') for mkl in listdir(mkldir) if mkl.startswith('mkl_')]
"Binaires" est une liste de tuples. Le deuxième élément du tuple correspond au dossier dans lequel vous voulez placer les 'dlls'. Dans ce cas, il est vide, il les copie directement dans le dossier principal où se trouve votre '.exe'.
Je viens de rencontrer le même problème. Comme solution de contournement, j'ai copié la DLL manuellement, comme décrit dans https://stackoverflow.com/a/34893933/4089081
J'essaie de trouver une meilleure solution cependant.
Je viens de mettre à jour numpy + mkl vers la dernière version, vous pouvez télécharger numpy + mkl depuis ici
La réponse de j4n7 a été très utile. Cependant, elle peut être ou non boguée. compat.base_prefix
utilise des barres obliques inverses (du moins pour moi), mais elles sont ensuite concaténées avec "/Lib/site-packages/numpy/core"
(barres obliques).
>>> from PyInstaller import compat
>>> compat.base_prefix
'C:\\Python34'
>>> mkldir = compat.base_prefix + "/Lib/site-packages/numpy/core"
>>> mkldir
'C:\\Python34/Lib/site-packages/numpy/core'
Comme vous pouvez le constater, cela produit des barres obliques dans un chemin.
Voici mes étapes qui m'ont permis de regrouper les fichiers numpy mkl dans un fichier. Notez que mon application particulière utilise matplotlib et que le problème que je rencontrais était chaque fois que je cliquais sur un bouton (tkinter) pour exécuter le tracé, l'application se bloquait.
Pas
First : Construisez votre application à l'aide de:
pyinstaller --onefile --windowed yourpythonappnamehere.py
Second : Ouvrez le fichier .spec
et ajoutez-le. Évidemment, assurez-vous que les fichiers ci-dessous existent réellement en premier. Vous n’avez peut-être pas Python34
, c’est un avertissement amical pour ne pas copier à l’aveugle.
mkl_dlls = [('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_avx.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_avx2.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_avx512.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_core.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_def.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_intel_thread.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_mc.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_mc3.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_rt.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_sequential.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_tbb_thread.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_vml_avx.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_vml_avx2.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_vml_avx512.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_vml_cmpt.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_vml_def.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_vml_mc.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_vml_mc2.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\mkl_vml_mc3.dll', ''),
('C:\\Python34\\Lib\\site-packages\\numpy\\core\\libiomp5md.dll', '')]
Troisième : où il est écrit binaries=None
, passez à binaries=mkl_dlls
.
a = Analysis(['yourpythonappnamehere.py'],
pathex=['C:\\Users\\...\\Documents\\...'],
binaries=mkl_dlls,
datas=None,
....
Quatrième : Relancez le premier étape. Une fois votre application créée, accédez au dossier dist
et lancez votre application. J'espère que cela fonctionne pour vous!
UPDATE: Si vous obtenez Intel MKL FATAL ERROR: Impossible de charger mkl_intel_thread.dll mais vous pouvez voir clairement que mkl_intel_thread.dll IS DANS votre répertoire de programme, accédez à numpy/core et Copiez littéralement tous les fichiers avec les extensions .dll que vous n'avez pas et collez-les dans le répertoire de votre programme, puis réexécutez-les. Si cela fonctionne, très bien, mais vous pouvez en supprimer un à la fois pour déterminer ceux dont vous avez besoin et ceux dont vous n'avez pas besoin.
J'avais 2 versions de Python installées. Une version de base de Python et une autre installée par Anaconda. Lors de l'exécution de mon script d'apprentissage machine, la même erreur s'est produite. Lorsque j'ai désinstallé l'une des deux versions (dans mon cas, j'ai supprimé Anaconda), tout fonctionne à nouveau correctement. J'utilise deeplearning4j comme bibliothèque et apparemment, il a du mal à résoudre cette dll car plusieurs installations Python ont été installées.
J'ai mis à jour l'extrait de code pour le faire fonctionner avec mon installation d'Anaconda (le chemin est différent):
from PyInstaller import log as logging
from PyInstaller import compat
from os import listdir
from os.path import join
mkldir = join(compat.base_prefix, "Library", "bin")
binaries = [(join(mkldir, mkl), '') for mkl in listdir(mkldir) if mkl.startswith('mkl_')]
Update: Cela ne fonctionne que pour Windows. J'ai également vu qu'il y a un PR sur github avec un correctif plus précis. Voir ceci Commit