@ -56,7 +56,7 @@ bool deployLibrary = false;
using std : : cout ;
using std : : cout ;
using std : : endl ;
using std : : endl ;
QString qtPathToBeBundled = " " ;
QMap < QString , QString > qtToBeBundledInfo ;
bool operator = = ( const LibraryInfo & a , const LibraryInfo & b )
bool operator = = ( const LibraryInfo & a , const LibraryInfo & b )
{
{
@ -645,6 +645,7 @@ DeploymentInfo deployQtLibraries(QList<LibraryInfo> libraries,
QStringList copiedLibraries ;
QStringList copiedLibraries ;
DeploymentInfo deploymentInfo ;
DeploymentInfo deploymentInfo ;
deploymentInfo . useLoaderPath = useLoaderPath ;
deploymentInfo . useLoaderPath = useLoaderPath ;
deploymentInfo . pluginPath = qtToBeBundledInfo . value ( " QT_INSTALL_PLUGINS " ) ;
QSet < QString > rpathsUsed ;
QSet < QString > rpathsUsed ;
while ( libraries . isEmpty ( ) = = false ) {
while ( libraries . isEmpty ( ) = = false ) {
@ -699,6 +700,21 @@ DeploymentInfo deployQtLibraries(QList<LibraryInfo> libraries,
return deploymentInfo ;
return deploymentInfo ;
}
}
static QString captureOutput ( const QString & command )
{
QProcess process ;
process . start ( command , QIODevice : : ReadOnly ) ;
process . waitForFinished ( ) ;
if ( process . exitStatus ( ) ! = QProcess : : NormalExit ) {
LogError ( ) < < command < < " crashed: " < < process . readAllStandardError ( ) ;
} else if ( process . exitCode ( ) ! = 0 ) {
LogError ( ) < < command < < " exited with " < < process . exitCode ( ) < < " : " < < process . readAllStandardError ( ) ;
}
return process . readAllStandardOutput ( ) ;
}
DeploymentInfo deployQtLibraries ( const QString & appDirPath , const QStringList & additionalExecutables )
DeploymentInfo deployQtLibraries ( const QString & appDirPath , const QStringList & additionalExecutables )
{
{
AppDirInfo applicationBundle ;
AppDirInfo applicationBundle ;
@ -710,33 +726,31 @@ DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &a
// Determine the location of the Qt to be bundled
// Determine the location of the Qt to be bundled
LogDebug ( ) < < " Using qmake to determine the location of the Qt to be bundled " ;
LogDebug ( ) < < " Using qmake to determine the location of the Qt to be bundled " ;
QProcess qmake ;
QString output = captureOutput ( " qmake -query " ) ;
qmake . start ( " qmake -v " ) ;
qmake . waitForFinished ( ) ;
if ( qmake . exitStatus ( ) ! = QProcess : : NormalExit | | qmake . exitCode ( ) ! = 0 ) {
LogError ( ) < < " qmake: " < < qmake . readAllStandardError ( ) ;
}
static const QRegularExpression regexp ( QStringLiteral ( " ^Using Qt version .+ in (.+) " )) ;
QString output = qmake . readAllStandardOutput ( ) ;
QStringList outputLines = output . split ( " \n " , QString : : SkipEmptyParts ) ;
QStringList outputLines = output . split ( " \n " , QString : : SkipEmptyParts ) ;
foreach ( QString outputLine , outputLines ) {
foreach ( const QString & outputLine , outputLines ) {
LogDebug ( ) < < " qmake outputLine: " < < outputLine ;
int colonIndex = outputLine . indexOf ( QLatin1Char ( ' : ' ) ) ;
const auto match = regexp . match ( outputLine ) ;
if ( colonIndex ! = - 1 ) {
if ( ( match . hasMatch ( ) ) and ( QFileInfo ( match . captured ( 1 ) ) . absoluteDir ( ) . exists ( ) ) ) {
QString name = outputLine . left ( colonIndex ) ;
qtPathToBeBundled = QFileInfo ( match . captured ( 1 ) ) . absolutePath ( ) ;
QString value = outputLine . mid ( colonIndex + 1 ) ;
LogDebug ( ) < < " Qt path determined from qmake: " < < qtPathToBeBundled ;
qtToBeBundledInfo . insert ( name , value ) ;
QProcessEnvironment env = QProcessEnvironment : : systemEnvironment ( ) ;
QString oldPath = env . value ( " LD_LIBRARY_PATH " ) ;
QString newPath = qtPathToBeBundled + " /lib " + " : " + oldPath ; // FIXME: If we use a ldd replacement, we still need to observe this path
// FIXME: Directory layout might be different for system Qt; cannot assume lib/ to always be inside the Qt directory
LogDebug ( ) < < " Changed LD_LIBRARY_PATH: " < < newPath ;
setenv ( " LD_LIBRARY_PATH " , newPath . toUtf8 ( ) . constData ( ) , 1 ) ;
}
}
}
}
if ( qtPathToBeBundled = = " " ) {
QString qtLibsPath = qtToBeBundledInfo . value ( " QT_INSTALL_LIBS " ) ;
if ( qtLibsPath . isEmpty ( ) | | ! QFile : : exists ( qtLibsPath ) ) {
LogError ( ) < < " Qt path could not be determined from qmake on the $PATH " ;
LogError ( ) < < " Qt path could not be determined from qmake on the $PATH " ;
LogError ( ) < < " Make sure you have the correct Qt on your $PATH " ;
LogError ( ) < < " Make sure you have the correct Qt on your $PATH " ;
LogError ( ) < < " You can check this with qmake -v " ;
LogError ( ) < < " You can check this with qmake -v " ;
} else {
LogDebug ( ) < < " Qt libs path determined from qmake: " < < qtLibsPath ;
QProcessEnvironment env = QProcessEnvironment : : systemEnvironment ( ) ;
QString oldPath = env . value ( " LD_LIBRARY_PATH " ) ;
QString newPath = qtLibsPath + " : " + oldPath ; // FIXME: If we use a ldd replacement, we still need to observe this path
// FIXME: Directory layout might be different for system Qt; cannot assume lib/ to always be inside the Qt directory
LogDebug ( ) < < " Changed LD_LIBRARY_PATH: " < < newPath ;
setenv ( " LD_LIBRARY_PATH " , newPath . toUtf8 ( ) . constData ( ) , 1 ) ;
}
}
changeIdentification ( " $ORIGIN/ " + bundleLibraryDirectory , applicationBundle . binaryPath ) ;
changeIdentification ( " $ORIGIN/ " + bundleLibraryDirectory , applicationBundle . binaryPath ) ;
@ -952,7 +966,7 @@ bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo,
LogNormal ( ) < < " Application QML file search path(s) is " < < qmlDirs ;
LogNormal ( ) < < " Application QML file search path(s) is " < < qmlDirs ;
// Use qmlimportscanner from QLibraryInfo::BinariesPath
// Use qmlimportscanner from QLibraryInfo::BinariesPath
QString qmlImportScannerPath = QDir : : cleanPath ( qtPath ToBeBundled ) + " /bin /qmlimportscanner" ;
QString qmlImportScannerPath = QDir : : cleanPath ( qtToBeBundledInfo . value ( " QT_INSTALL_BINS " ) ) + " /qmlimportscanner " ;
LogDebug ( ) < < " Looking for qmlimportscanner at " < < qmlImportScannerPath ;
LogDebug ( ) < < " Looking for qmlimportscanner at " < < qmlImportScannerPath ;
// Fallback: Look relative to the linuxdeployqt binary
// Fallback: Look relative to the linuxdeployqt binary
@ -975,8 +989,7 @@ bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo,
argumentList . append ( " -rootPath " ) ;
argumentList . append ( " -rootPath " ) ;
argumentList . append ( qmlDir ) ;
argumentList . append ( qmlDir ) ;
}
}
QString qmlImportsPath = QDir : : cleanPath ( qtPathToBeBundled ) + " /qml " ;
QString qmlImportsPath = qtToBeBundledInfo . value ( " QT_INSTALL_QML " ) ;
// FIXME: Directory layout might be different for system Qt; cannot assume qml/ to always be inside the Qt directory
LogDebug ( ) < < " qmlImportsPath candidate: " < < qmlImportsPath ;
LogDebug ( ) < < " qmlImportsPath candidate: " < < qmlImportsPath ;
// Verify that we found a valid qmlImportsPath
// Verify that we found a valid qmlImportsPath