New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libeay32.dll and ssleay32.dll needs to be manually bundled to use PyQt5.QNetwork with SSL #3511

Closed
remyroy opened this Issue May 11, 2018 · 5 comments

Comments

Projects
None yet
3 participants
@remyroy
Contributor

remyroy commented May 11, 2018

If you are having errors like:

qt.network.ssl: QSslSocket: cannot call unresolved function SSLv23_client_method
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_CTX_new
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_library_init
qt.network.ssl: QSslSocket: cannot call unresolved function ERR_get_error
qt.network.ssl: QSslSocket: cannot call unresolved function ERR_get_error

with PyInstaller and PyQt5 on Windows, you need to manually add libeay32.dll and ssleay32.dll from your PyQt5 site-packages (probably located somewhere in PyQt5\Qt\bin\) to your output dir or your frozen binary in a similar path.

In my final specfile, it looks like this:

# -*- mode: python -*-

block_cipher = None


a = Analysis(['cddagl\\launcher.py'],
             pathex=['C:\\Program Files (x86)\\Windows Kits\\10\\Redist\\ucrt\\DLLs\\x86\\', 'C:\\Users\\remy\\Projects\\CDDA-Game-Launcher'],
             binaries=[('C:\\Users\\remy\\VirtualEnvs\\CDDA-Game-Launcher\\lib\\site-packages\\PyQt5\\Qt\\bin\\libeay32.dll', 'PyQt5\\Qt\\bin'), ('C:\\Users\\remy\\VirtualEnvs\\CDDA-Game-Launcher\\lib\\site-packages\\PyQt5\\Qt\\bin\\ssleay32.dll', 'PyQt5\\Qt\\bin')],
             datas=[('alembic', 'alembic'), ('bin/updated.bat', '.'), ('data', 'data'), ('cddagl/resources', 'cddagl/resources'), ('C:\\Users\\remy\\AppData\\Local\\Programs\\Python\\Python36-32\\unrar.exe', '.'), ('cddagl/locale/en/LC_MESSAGES/cddagl.mo', 'cddagl/locale/en/LC_MESSAGES'), ('cddagl/locale/fr/LC_MESSAGES/cddagl.mo', 'cddagl/locale/fr/LC_MESSAGES'), ('cddagl/locale/it/LC_MESSAGES/cddagl.mo', 'cddagl/locale/it/LC_MESSAGES'), ('cddagl/locale/ru/LC_MESSAGES/cddagl.mo', 'cddagl/locale/ru/LC_MESSAGES')],
             hiddenimports=['lxml.cssselect', 'babel.numbers'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='launcher',
          debug=True,
          strip=False,
          upx=False,
          runtime_tmpdir=None,
          console=True , icon='cddagl\\resources\\launcher.ico')

I'm not sure how this can be improved, but this solution should work if you are having a similar issue. This was tested with PyInstaller==3.4.dev0+1033a8770

@remyroy

This comment has been minimized.

Contributor

remyroy commented May 11, 2018

With the latest PyQt5 PyPI wheel, I did inspect the various PyQt DLLs with Dependency Walker and they don't seem to be linked to libeay32.dll and ssleay32.dll. This might be the reason why it is not detected by PyInstaller.

@bjones1 bjones1 self-assigned this May 11, 2018

@bjones1

This comment has been minimized.

Member

bjones1 commented May 11, 2018

Thanks for reporting this. Would you provide a simple test script that demonstrates this? I can then integrate this into the functional tests. Or, if you can, add a test similar to https://github.com/pyinstaller/pyinstaller/blob/develop/tests/functional/test_libraries.py#L247.

I'm guessing that https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/hooks/hook-PyQt5.QtNetwork.py should look something like:

from PyInstaller.utils.hooks import add_qt5_dependencies, pyqt5_library_info
from PyInstaller.compat import is_win

hiddenimports, binaries, datas = add_qt5_dependencies(__file__)

if is_win:
    rel_data_path = ['PyQt5', 'Qt']
    binaries += [
        (os.path.join(pyqt5_library_info.location['LibraryPath'], 'libeay32.dll'),
         os.path.join(*rel_data_path)),
        (os.path.join(pyqt5_library_info.location['LibraryPath'], 'ssleay32.dll'),
         os.path.join(*rel_data_path))
    ]

Would you mind testing/debugging this?

@remyroy

This comment has been minimized.

Contributor

remyroy commented May 11, 2018

I'll test this and I'll check if you I can add a functional test.

@remyroy

This comment has been minimized.

Contributor

remyroy commented May 11, 2018

I believe rel_data_path should be slightly different in your change. I believe it should be like:

rel_data_path = ['PyQt5', 'Qt', 'bin']
@bjones1

This comment has been minimized.

Member

bjones1 commented May 11, 2018

Good catch -- yes, that's correct. Thanks for the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment