Сразу же, извините за длину вопроса, но это связано со всеми дополнительными деталями, которые я предоставляю, и надеюсь, что это может помочь решить проблему быстрее
Чего я пытаюсь достичь?
Мне нужно создать портативное (все-в-одном) приложение с поддержкой SSL.
В чем проблема?
Итак, основная проблема, с которой я сталкиваюсь, заключается в том, чтобы включить поддержку SSL в мое двоичное / переносное приложение.
A MCVE приложения просто:
Проект .pro
Файл
QT -= gui
QT += network
CONFIG += c++11 console
CONFIG -= app_bundle
SOURCES += \
main.cpp
INSTALLS += target
Проект main.cpp
#include <QCoreApplication>
#include <QSslSocket>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "Is SSL Enabled? " << QSslSocket::supportsSsl();
qDebug() << "SSL Library Build Version (Qt compiled against): " << QSslSocket::sslLibraryBuildVersionString();
qDebug() << "SSL Library Version String (available locally): " << QSslSocket::sslLibraryVersionString();
return a.exec();
}
Вывод на мой DEV-аппарат :
Is SSL Enabled? true
SSL Library Build Version (Qt compiled against): "OpenSSL 1.1.1d 10 Sep 2019"
SSL Library Version String (available locally): "OpenSSL 1.1.1d 10 Sep 2019"
Информация о Dev Machine
C:\Users\cybex>echo %PATH%
C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Strawberry\c\bin;C:\Strawberry\perl\site\bin;C:\Strawberry\perl\bin
C:\Users\cybex>openssl
WARNING: can't open config file: /z/extlib/_openssl_/ssl/openssl.cnf
OpenSSL> version
OpenSSL 1.0.2g 1 Mar 2016
Запуск того же двоичного файла на новой машине с Windows 10 x86 приводит к:
Is SSL Enabled? false
SSL Library Build Version (Qt compiled against): "OpenSSL 1.1.1d 10 Sep 2019"
SSL Library Version String (available locally): ""
Информация о тестовой машине (Совершенно новая установка - Windows 10 x86)
C:\Users\cybex>echo %PATH%
C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\
C:\Users\cybex>openssl
'openssl' is not recognized as an internal or external command,
operable program or batch file.
Запуск того же двоичного файла на новой машине с Windows 7 x64 приводит к:
Is SSL Enabled? false
SSL Library Build Version (Qt compiled against): "OpenSSL 1.1.1d 10 Sep 2019"
SSL Library Version String (available locally): ""
Информация о тестовой машине (ноутбук с Windows 7 x64 с установленными драйверами)
C:\Users\Home>echo %PATH%
C:\Program Files (x86)\OpenSSL\libs;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files (x86)\OpenSSL\libs;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\
C:\Users\Home>openssl
'openssl' is not recognized as an internal or external command, operable program or batch file.
Посмотрев на приведенные выше результаты, я пришел к выводучто установка OpenSSL решает проблему. Хорошо, но я хочу, чтобы он был включен в мое портативное приложение.
Для достижения этого мне необходимо
Статическая компиляция Qt с поддержкой OpenSSL
Я сделал это с помощью этого сценария , адаптированного из ps1
сценария powershell найденного здесь, на вики Qt . Я сделал дополнения для:
OpenSSL home $OPENSSL_HOME
количество потоков $threads
и
тип архитектуры $arch
, который будет использоваться.
Детали компиляции Qt и информация OpenSSL
Компилятор: mingw32
находится в C:\Qt\Qt5.13.1\Tools\mingw730_32\bin
mkspec: win32-g++
(если это имеет какое-то значение).
Версия OpenSSL (32бит): 1.1.1d
Конфигурация следующая :
cmd /C "configure.bat -static -debug-and-release -platform win32-g++ -prefix $QtDir `
-qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype -opengl desktop -sql-sqlite -ssl -openssl -I $($OPENSSL_HOME)\include -L$($OPENSSL_HOME)\lib\MinGW`
-opensource -confirm-license `
-make libs -nomake tools -nomake examples -nomake tests -v"
cmd /C "mingw32-make -k -j$($threads)"
Примечание 1:
Я использую -openssl
, а не -openssl-linked
. Я пробовал несколько вариантов сборки Qt с -openssl
и -openssl-linked
. -openssl-linked
никогда не смог бы успешно построить, см. этот пост Я объяснил причину.
Примечание 2:
Единственная успешная статическая компиляция Qt, с которой я работал, была с -ssl -openssl
включенными флагами конфигурации
Установка OpenSSL (только на компьютере DEV) находится на
`$OPENSSL_HOME = "C:\OpenSSL-Win32"`
, где я использую статически скомпилированные MinGW
библиотеки для OpenSSL, найденные в
`$OPENSSL_HOME = "C:\OpenSSL-Win32\lib\MinGW",`
Содержимое файла C:\OpenSSL-Win32\lib\MinGW
:
Directory: C:\OpenSSL-Win32\lib\MinGW
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2019/09/11 18:11 3347286 libcrypto.a
-a---- 2019/09/11 18:10 109020 libcrypto.def
-a---- 2019/09/11 18:11 385126 libssl.a
-a---- 2019/09/11 18:10 14033 libssl.def
Добавление проекта ссылки .pro в библиотеки OpenSSL
Я добавил библиотеки OpenSSL в файл .pro
, используя 2 метода (библиотеки - это статически скомпилированные библиотеки MinGW OpenSSL, найденныеat C:\OpenSSL-Win32\lib\MinGW
)
Ручной ввод библиотек в файл .pro
QT -= gui
QT += network
# OpenSSL static .a libraries
INCLUDEPATH += "C:\OpenSSL-Win32\include"
LIBS += -L"C:\OpenSSL-Win32\lib\MinGW\libssl.a"
LIBS += -L"C:\OpenSSL-Win32\lib\MinGW\libcrypto.a"
CONFIG += c++11 console
CONFIG -= app_bundle
SOURCES += \
main.cpp
INSTALLS += target
Примечание 3
Двоичный размер с ибез вышеупомянутых связанных библиотек остается тот же самый размер
Вывод LDD двоичного файла (на моем компьютере разработчика) с добавленными выше библиотеками:
Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module
Size(K) ModuleName FileName
------- ---------- --------
6280 SSL-Test.exe C:\Users\cybex\QtProjects\build-SSL-Test-Desktop_Qt_Op...
1512 ntdll.dll C:\Windows\SYSTEM32\ntdll.dll
596 KERNEL32.DLL C:\Windows\system32\KERNEL32.DLL
1500 KERNELBASE.dll C:\Windows\system32\KERNELBASE.dll
Вывод LDD изБинарный файл (на моем тестовом компьютере с Windows 10 x86) с добавленными выше библиотеками:
Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module
Size(K) ModuleName FileName
------- ---------- --------
6280 SSL-Test.exe C:\Users\cybex\Desktop\SSL-Test.exe
1512 ntdll.dll C:\Windows\SYSTEM32\ntdll.dll
596 KERNEL32.DLL C:\Windows\system32\KERNEL32.DLL
1500 KERNELBASE.dll C:\Windows\system32\KERNELBASE.dll
Импорт библиотеки Qt в файл .pro
Импорт с использованием (External Library
> Импорт .a
файл> Static
& Windows
только параметры с суффиксом no debug
QT -= gui
QT += network
CONFIG += c++11 console
CONFIG -= app_bundle
SOURCES += \
main.cpp
INSTALLS += target
win32: LIBS += -L$$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/ -lssl
INCLUDEPATH += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW
DEPENDPATH += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW
win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/ssl.lib
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/libssl.a
win32: LIBS += -L$$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/ -lcrypto
INCLUDEPATH += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW
DEPENDPATH += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW
win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/crypto.lib
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/libcrypto.a
Используя автоматический импорт двоичных файлов, вывод двоичного файла LDD (на моем устройствемашина) с библиотеками, добавленными выше:
Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module
Size(K) ModuleName FileName
------- ---------- --------
6280 SSL-Test.exe C:\Users\cybex\QtProjects\build-SSL-Test-Desktop_Qt_Op...
1512 ntdll.dll C:\Windows\SYSTEM32\ntdll.dll
596 KERNEL32.DLL C:\Windows\system32\KERNEL32.DLL
1500 KERNELBASE.dll C:\Windows\system32\KERNELBASE.dll
И при использовании автоматического импорта библиотеки вывод двоичного файла LDD (на моем тестовом компьютере с Windows 10 x86) с добавленными выше библиотеками:
Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module
Size(K) ModuleName FileName
------- ---------- --------
6280 SSL-Test.exe C:\Users\cybex\Desktop\SSL-Test.exe
1512 ntdll.dll C:\Windows\SYSTEM32\ntdll.dll
596 KERNEL32.DLL C:\Windows\system32\KERNEL32.DLL
1500 KERNELBASE.dll C:\Windows\system32\KERNELBASE.dll
Выходные данные приложения для машины dev: SSL enabled
как упоминалось ранее в моем посте (как для ручной, так и для автоматической записи в библиотеку):
Is SSL Enabled? true
SSL Library Build Version (Qt compiled against): "OpenSSL 1.1.1d 10 Sep 2019"
SSL Library Version String (available locally): "OpenSSL 1.1.1d 10 Sep 2019"
Выходные данные приложения для тестовых машин (без установленного OpenSSL) такие же, как и ранее (для обеих инструкций вручную). и автоматическая запись в библиотеку):
Is SSL Enabled? false
SSL Library Build Version (Qt compiled against): "OpenSSL 1.1.1d 10 Sep 2019"
SSL Library Version String (available locally): ""
Таким образом, если библиотека OpenSSL отсутствует, она вызывает приведенную ниже ошибку при запросе соединения SSL на компьютерах не-Dev (свежая / клиентская):
QSslSocket :: connectToHostEncrypted: инициализация TLS завершилась неудачно
, что является результатом того, что библиотека OpenSSL не включена в двоичный файл как зависимость. Поэтому в принципе добавление статической библиотеки OpenSSL в файл проекта не работает или я что-то делаю неправильно где-то внизу.
Примечание 4: Почему вопрос не озаглавлен: Как импортировать статическую библиотеку в Qt?
Импорт статической библиотеки прост и не сложен. Я предполагаю, что где-то допустил ошибку в статической компиляции Qt с включенной поддержкой SSL.
Будем весьма признательны за советы по решению этой проблемы.
Обновление 1
Я решил проблему с -openssl-linked
. Причина (или скорее исправление) состоит в том, чтобы не устанавливать OpenSSL на ваш компьютер. Скорее, распакуйте директории .a
& include
в отдельный каталог. Так что все то же самое, за исключением того, что у вас есть lib
s & include
без установки.
Затем используйте стандартную конфигурацию (упомянутую выше), заменив -openssl
на -openssl-linked
, и у вас должна получиться успешная компиляция.
Обновленная проблема
При сборке и запуске моего приложения с новым Linked OpenSSL Qt kit я получаю сообщение:
Выполнение кода не может быть продолжено, поскольку libcrypto.dll не был найден. Переустановка программы может решить эту проблему.
За этим следует другое диалоговое окно
Невозможно продолжить выполнение кода, так как libssl.dll не был найден. Переустановка программы может решить эту проблему
Требования LDD:
Start-Process -PassThru .\MyAwesomeApp.exe | Get-Process -Module
Size(K) ModuleName FileName
------- ---------- --------
22708 MyAwesomeApp.exe C:\Users\CybeX\QtProjects\build-MyAwesomeApp-Desktop_Qt_OpenSSL_Linked_5_13_1_MinGW_32bit-Release\release\MyAwesomeApp.exe
1924 ntdll.dll C:\WINDOWS\SYSTEM32\ntdll.dll
328 wow64.dll C:\WINDOWS\System32\wow64.dll
480 wow64win.dll C:\WINDOWS\System32\wow64win.dll
40 wow64cpu.dll C:\WINDOWS\System32\wow64cpu.dll
Протестировали это с и без .pro LIBS
& INCLUDEPATH
. Оба результата приводят к отсутствию dll
.