takluyver / pynsist

Build Windows installers for Python applications
https://pynsist.readthedocs.io/
Other
896 stars 119 forks source link

PyQt5 dll not found #145

Closed MartinGrignard closed 6 years ago

MartinGrignard commented 6 years ago

Hi,

I'm currently programming an app using several libraries such as PyQt5, numpy, scipy, matplotlib,... I get no error while building with pynsist but when I try to launch the app after installation, this message shows up in the log file in %APPDATA%:

File "NameOfFile.py", line 1, in <module> 
     from PyQt5 import QtGui
ImportError: DLL load failed: The specified module could not be found.

I build on a Windows 10 64bit and try to install on a Windows 7 32bit and here is my installer.cfg file:

[Application]
name=Name of my app
version=1.0
publisher=Sirris
entry_point=mypackage.main:main
console=True
license_file=mypackage/resources/licence.txt

[Python]
version=3.6.3
format=bundled
bitness=32

[Include]
packages=mypackage
pypi_wheels=PyQt5==5.10.1
    numpy==1.14.1
    scipy==1.0.0
    numpy==1.14.1
    matplotlib==2.2.0rc1
files=mypackage/resources

[Build]
directory=Some directory

I found lots of threads on the internet talking about concrt140.dll and msvcp140.dll missing but in my case they are included with PyQt5 5.10.1. I tried everything I found, but nothing seems to help...

Do you have any idea of what could be causing this issue?

Thanks, Cirn3co

takluyver commented 6 years ago

I don't know off the top of my head what might be missing, but I'd recommend having a play with Dependency walker. Using that on the PyQt DLLs should help you figure out what other DLLs they need and what's missing.

These problems often seem to come down to different parts of the Microsoft C runtime. I can never properly remember how all the different bits go together.

takluyver commented 6 years ago

cc @zooba this is probably wishful thinking, but is there any way Python could give a more meaningful error message when loading an extension module fails because of a missing DLL? It would be much easier to resolve problems like this if the error message could tell you what was missing, like:

DLL load failed: foobar.dll could not be found.
MartinGrignard commented 6 years ago

Thanks for your quick answer! I used dependency walker on QtGui.dll and here is the result: dependency walker I'm a newbie with this tool, it looks like some imports are missing, but I don't find anything when googling the names... Does it mean something for you?

takluyver commented 6 years ago

All those ones that start with API-MS-... are parts of the C runtime. If the installer doesn't find the runtime on your computer, it should install those files into the Python folder under your install directory, alongside Python itself.

Can you check:

  1. Are there any api-ms-... DLLs in that folder? If not, then it means the installer has decided it doesn't need to install them.
  2. Are all the ones that show up in dependency walker there? If not, they're missing from Pynsist.

If they're all there, then it must be something else, but I'm not really sure what. I haven't used dependency walker much myself.

zooba commented 6 years ago

Dependency Walker is not really a good enough tool for this any more, unfortunately... it doesn't handle API sets (all those api-ms-* files) properly, and it's so slow.

I keep meaning to write a tool that can take dumpbin.exe and parse the output to trace dependencies. I think someone at Anaconda did this, but it's not quite a substitute for the (incredibly unreliable) live profiling that Dependency Walker could do, or just attaching a native debugger and watching what fails.

And yeah, it's pretty wishful thinking :) The failure comes from the kernel (module loader), and as far as I know it doesn't raise any of that info higher up.

takluyver commented 6 years ago

Thanks Steve. Do you know of any handy tutorials for non C programmers to attach a debugger to investigate this?

MartinGrignard commented 6 years ago

@takluyver all the dll in red in dependency wlaker seem to be in the /msvrt folder created by pynsist so they are installed.

@zooba thanks for these bits of information :)

It looks like attaching a debugger to the project is very difficult... Sadly I don't have any clue of what to do next, I can't just redo everything in another language, it would be too long and scipy.io is too useful to interact with the .mat files I have to deal with... If someone has an idea, I would be very thankful :p

takluyver commented 6 years ago

Unless @zooba has any other ideas on how to investigate it, the only thing I can suggest is that you try a tool like Pyinstaller instead of Pynsist, and hope that it doesn't have the same problem.

MartinGrignard commented 6 years ago

@takluyver okay, I'll try that, but I read that those freezing things didn't do well with PyQt and other C++ interfaced libraries, fingers crossed!

takluyver commented 6 years ago

Hang on, something just occurred to me. All the PyQt5 examples in this repo specify sip in the pypi_wheels list. Have you tried that?

The PyQt5 5.10.1 wheel has a dependency on sip (>=4.19.4, <4.20) . So the latest version should work: sip==4.19.8.

MartinGrignard commented 6 years ago

Oh I didn't realize! I try that, thanks for not giving up! :D EDIT: This seems to fix the problem with Qt, I now get new errors of the same type for matplotlib. I'm adding dependencies one at a time, it's slow but it looks like it's the right way to go. I'll keep you informed if I manage to launch it! Once again thank you @takluyver :)

MartinGrignard commented 6 years ago

Ok, it works, I had to add several dependencies (matplotlib needs four of them) and now it works like a charm!

takluyver commented 6 years ago

Hooray!

I decided that Pynsist would need every module to include listed explicitly; it doesn't try to resolve dependencies at all. I know that can be inconvenient, but I was coming from tools that tried to do it by analysing import statements, which IMO doesn't work very well. I'm working on a tool called kartoffel that can identify the dependencies by running the application. I'll have to check if it would pick up sip in this case.

MartinGrignard commented 6 years ago

I totaly understand that, it's just the first time I try to share a Python app so I'm not used to those problems yet :) By the way, Pynsist is really a great tool! Now that it works, I realize how useful it can be to deploy apps like that, with all the needed tools embeded in it like with .NET. I'll keep an eye on kartoffel then! :D Keep on the great work!

zooba commented 6 years ago

And just to round up - I don't have any good tutorials on using a debugger for this kind of thing. And it really is far too advanced for the average-to-expert Python developer to want to be messing with (even the average-to-good C developer doesn't deal with this stuff often enough to "just know" how to do it - this is my favourite blog for making me feel like I don't know anything :) )

takluyver commented 6 years ago

Thanks @zooba ! Glancing at that blog, it does look pretty intimidating.

If you do find time to make some tooling to help us non-experts figure out what DLL is missing in cases like this, I'd love to hear about it. :-)