Improved the way Qt files are located
Using 'qmake -query' to get all information explicitly instead of parsing the output of 'qmake -v' and deriving binary path, plugin path and QML path from there. Fixes #28 Fixes #37
This commit is contained in:
@@ -38,9 +38,10 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
QString appBinaryPath;
|
QString appBinaryPath;
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1) {
|
||||||
appBinaryPath = QString::fromLocal8Bit(argv[1]);
|
appBinaryPath = QString::fromLocal8Bit(argv[1]);
|
||||||
appBinaryPath = QDir::cleanPath(appBinaryPath).trimmed();
|
appBinaryPath = QDir::cleanPath(appBinaryPath).trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
if (argc < 2 || appBinaryPath.startsWith("-")) {
|
if (argc < 2 || appBinaryPath.startsWith("-")) {
|
||||||
qDebug() << "Usage: linuxdeployqt app-binary [options]";
|
qDebug() << "Usage: linuxdeployqt app-binary [options]";
|
||||||
@@ -199,6 +200,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (plugins && !deploymentInfo.qtPath.isEmpty()) {
|
if (plugins && !deploymentInfo.qtPath.isEmpty()) {
|
||||||
|
if (deploymentInfo.pluginPath.isEmpty())
|
||||||
deploymentInfo.pluginPath = QDir::cleanPath(deploymentInfo.qtPath + "/../plugins");
|
deploymentInfo.pluginPath = QDir::cleanPath(deploymentInfo.qtPath + "/../plugins");
|
||||||
deployPlugins(appDirPath, deploymentInfo);
|
deployPlugins(appDirPath, deploymentInfo);
|
||||||
createQtConf(appDirPath);
|
createQtConf(appDirPath);
|
||||||
|
|||||||
+38
-25
@@ -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(qtPathToBeBundled) + "/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
|
||||||
|
|||||||
Reference in New Issue
Block a user