C’è un modo per build Qt statico con OpenSSL statico?

La domanda originale era leggermente diversa ma faceva parte di una domanda più importante.

Sto cercando di build Qt 5.2 come statico con OpenSSL statico su Windows.

Il mio objective finale è spedire un singolo binario senza la necessità di fornire libeay32.dll e ssleay32.dll con esso. Tuttavia, mi sembra che questo sia imansible. Ho costruito Qt statico con librerie openssl statiche, ma sembra che Qt stia completamente ignorando le librerie fornite e cerca sempre le DLL.

Questa risposta suggerisce anche che QtNetwork cerca sempre DLL e ignora tutto il resto, ma afferma anche che “due opzioni sono la compilazione di OpenSSL in Qt …” ma questo non sembra essere il caso.

Qualcuno può fornire una risposta definitiva?

Questo è il mio Qt configure (interruzioni di riga aggiunte per la leggibilità):

configure -static -qmake -opensource -nomake examples -opengl desktop -platform win32-msvc2010 -openssl -IC:\git\openssl\build\include -LC:\git\openssl\build\lib OPENSSL_LIBS="-llibeay32 -lssleay32 -lgdi32" 

C’è un modo per build Qt statico con OpenSSL statico?

Certo, è necessario utilizzare la seguente opzione quando si configura Qt:

 -openssl-linked 

Il motivo è che QtNetwork utilizza la class QLibrary per impostazione predefinita per l’apertura dynamic della libreria per ottenere i simboli necessari.

Questa è l’opzione per dire a Qt di non farlo, e rispettare le normali regole di collegamento.

Detto questo, non è consigliabile utilizzare il collegamento statico per openssl se gli aggiornamenti di sicurezza devono essere disponibili per l’utente finale senza il tuo coinvolgimento. Considera per un momento cosa succede se non ci sei più, non lavori più su questo progetto, ecc.

Inoltre, questa configurazione non viene testata frequentemente, quindi potresti riscontrare alcuni problemi che dovrebbero essere risolti a monte, ma questa è la progettazione della soluzione per il caso d’uso in questione.

Disclaimer: dato che SO riguarda la programmazione, sto ignorando le conseguenze della licenza per il collegamento statico a Qt, quindi vorrei semplicemente ricordare che sei consapevole dell’uso corretto per non entrare nei problemi legali.

OPENSSL_LIBS = “- llibeay32 -lssleay32” …

Evita -l tutto (e -L , e -Wl,-Bstatic ). Il linker a volte ignora la richiesta di collegamento statico (Apple), ea volte uno script lo modifica (non posso dirti quanti script di build personalizzati mi hanno morso).

Invece, utilizzare un archivio completamente specificato proprio come si farebbe con un file object. Nel tuo LDLIBS aggiungi quanto segue in modo che non ci sia possibilità che uno script rovini le cose o che il linker ignori la tua richiesta:

 /usr/local/ssl/lib/libssl.a /usr/local/ssl/lib/libcrypto.a 

Ovviamente, dovresti cambiare il percorso di libssl.a e libcrypto.a in modo che corrisponda all’installazione.

Se non si dispone di un LDLIBS , aggiungerlo a LDFLAGS (o “altri flag del linker” nell’IDE).

In Qt, sembra che sarebbe QMAKE_LFLAGS o LIBS . Oppure puoi provare questo post: Come aggiungere “Dipendenze aggiuntive” (Impostazioni Linker) .

Lo stesso trucco si applica anche agli oggetti condivisi (ma i linker preferiscono gli oggetti condivisi, quindi di solito non diventa un problema). Cioè, puoi specificare:

 /usr/local/ssl/lib/libssl.so /usr/local/ssl/lib/libcrypto.so 

La cosa da ricordare quando si specifica un object condiviso come sopra è che bisogna specificare un rpath per assicurarsi che il linker di runtime ottenga il messaggio. Cioè, dovresti aggiungere quanto segue a LDFLAGS o “altre opzioni di linker”:

 -Wl,-rpath=/usr/local/ssl/lib 

Sono stato morso alcuni quando si specificavano oggetti condivisi quando si utilizzava la libreria Captive OpenSSL FIPS che risiede in /usr/local/ssl/lib perché il linker di runtime utilizza l’OpenSSL della distribuzione in /usr/lib o /usr/lib64 . La libreria FIPS FIPS_mode_set OpenSSL è quella che si chiama FIPS_mode_set .

Puoi anche rimuovere (o rinominare) l’object condiviso dalla posizione, lasciando solo l’archivio statico. Ho dovuto usare questa tecnica in passato quando costruivo sotto Xcode per iPhone. Xcode si è rifiutato di utilizzare l’archivio statico, anche se posizionato in modo corretto -Bstatic . (Cross-compilers e toolchain modificati sono alcuni dei peggiori da usare a volte). Non penso che dovresti modificare le directory di installazione, quindi generalmente non lo uso.

Per riassumere, non lasciare nulla al caso ed evitare -l , -L , -Wl,-Bstatic . Specificare completamente ciò che si desidera e utilizzare il nome del percorso della libreria completo e utilizzarli come file object. Utilizzare un rpath se si specifica un object condiviso.

Questo è il modo in cui costruisco Qt 5.7.1 con supporto SSL su Windows utilizzando MSVC 2013 :

  • Scarica e installa: Perl versione 5.12 o successiva
  • Scarica e installa: Python versione 2.7 o successiva
  • Scarica e installa: Ruby versione 1.9.3 o successiva

Assicurati che Perl, Python e Ruby si trovino nella variabile d’ambiente PATH.

  • Scarica e installa: Win32 OpenSSL v1.0.2L

Scarica Qt dal repository github:

 cd C:\Qt git clone https://github.com/qt/qt5.git cd C:\Qt\qt5 git checkout 5.7 

Assicurati di fare il checkout con commit 36e7cff94fbb4af5d8de6739e66164c6e6873586 . In questo momento, il check-out 5.7 fa esattamente questo.

Inserire il contenuto di seguito in qt5vars.bat situato in C:\Qt\qt5 . Apporta le modifiche se è necessario:

 @echo off REM Set up \Microsoft Visual Studio 2015, where  is \c amd64, \c x86, etc. CALL "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86 REM Edit this location to point to the source code of Qt SET _ROOT=C:\Qt\qt5 SET PATH=%_ROOT%\qtbase\bin;%_ROOT%\gnuwin32\bin;%PATH% REM Uncomment the below line when using a git checkout of the source repository SET PATH=%_ROOT%\qtrepotools\bin;%PATH% REM Uncomment the below line when building with OpenSSL enabled. If so, make sure the directory points REM to the correct location (binaries for OpenSSL). SET PATH=C:\OpenSSL-Win32\bin;%PATH% REM When compiling with ICU, uncomment the lines below and change  appropriately: REM SET INCLUDE=\include;%INCLUDE% REM SET LIB=\lib;%LIB% REM SET PATH=\lib;%PATH% REM Contrary to earlier recommendations, do NOT set QMAKESPEC. SET _ROOT= REM Keeps the command line open when this script is run. cmd /k 

Dopodiché, esegui questo file e avvia correttamente il repository:

 qt5vars.bat perl init-repository 

Infine, per configurare e compilare correttamente la libreria (con versioni di debug e release), assicurarsi che i percorsi a cui fa riferimento configure siano validi anche sul proprio sistema:

 configure -static -static-runtime -debug-and-release -ssl -openssl -openssl-linked -opengl dynamic -platform win32-msvc2013 -prefix C:\Qt\qt5.7-msvc2013-static -nomake tests -nomake examples -I "C:\OpenSSL-Win32\include" -L "C:\OpenSSL-Win32\lib\VC\static" OPENSSL_LIBS="-lUser32 -lAdvapi32 -lGdi32 -lCrypt32" OPENSSL_LIBS_DEBUG="-lssleay32MTd -llibeay32MTd" OPENSSL_LIBS_RELEASE="-lssleay32MT -llibeay32MT" nmake nmake install 

Tutto così lontano dovrebbe essere eseguito senza intoppi e splendidamente. Ora si tratta di configurare Qt Creator per rilevare questa nuova versione di Qt e creare un nuovo utilizzo del kit sui progetti: