Skip to content

Commit a3a6376

Browse files
committed
Allow the qmake executable to be passed on CLI
This change adds a new command line option `qmake` to the tool which allows the user to specify the qmake executable to be used. By default, if that option is omitted, the behavior is unchanged (i.e. the tool first searches for the `qmake` executable and - if this is not successful - then for either `qmake-qt5` or `qmake-qt4`. If the new option is used, no search takes place and instead the executable provided is used as-is. This implements a part of the functionality as discussed in issue probonopd#94.
1 parent d199bb9 commit a3a6376

File tree

4 files changed

+52
-37
lines changed

4 files changed

+52
-37
lines changed

README.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Please download __linuxdeployqt-x86_64.AppImage__ from the [Releases](https://gi
2020

2121
Open in Qt Creator and build your application. Run it from the command line and inspect it with `ldd` to make sure the correct libraries from the correct locations are getting loaded, as `linuxdeployqt` will use `ldd` internally to determine from where to copy libraries into the bundle.
2222

23-
__Important:__ `linuxdeployqt` deploys the Qt instance that qmake on the $PATH points to, so make sure that it is the correct one. Verify that qmake finds the correct Qt instance like this before running the `linuxdeployqt` tool:
23+
__Important:__ By default, `linuxdeployqt` deploys the Qt instance that qmake on the $PATH points to, so make sure that it is the correct one. Verify that qmake finds the correct Qt instance like this before running the `linuxdeployqt` tool:
2424

2525
```
2626
qmake -v
@@ -29,6 +29,7 @@ QMake version 3.0
2929
Using Qt version 5.7.0 in /tmp/.mount_QtCreator-5.7.0-x86_64/5.7/gcc_64/lib
3030
```
3131
If this does not show the correct path to your Qt instance that you want to be bundled, then adjust your `$PATH` to find the correct `qmake`.
32+
Alternatively, use the `-qmake` command line option to point the tool directly to the qmake executable to be used.
3233

3334
Before running linuxdeployqt it may be wise to delete unneeded files that you do not wish to distribute from the build directory. These may be autogenerated during the build. You can delete them like so:
3435

@@ -69,8 +70,8 @@ dist: trusty
6970
before_install:
7071
- sudo add-apt-repository ppa:beineri/opt-qt58-trusty -y
7172
- sudo apt-get update -qq
72-
73-
install:
73+
74+
install:
7475
- sudo apt-get -y install qt58base
7576
- source /opt/qt*/bin/qt*-env.sh
7677
@@ -80,14 +81,14 @@ script:
8081
- make INSTALL_ROOT=appdir install ; find appdir/
8182
8283
after_success:
83-
- wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage"
84+
- wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage"
8485
- chmod a+x linuxdeployqt*.AppImage
8586
- unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH
8687
- ./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs
8788
- ./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -appimage
8889
- find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq
8990
- curl --upload-file ./APPNAME*.AppImage https://transfer.sh/APPNAME-git.$(git rev-parse --short HEAD)-x86_64.AppImage
90-
```
91+
```
9192

9293
When you save your change, then Travis CI should build and upload an AppImage for you. More likely than not, some fine-tuning will still be required.
9394

linuxdeployqt/main.cpp

+13-5
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,15 @@ int main(int argc, char **argv)
5555
qDebug() << " -executable=<path> : Let the given executable use the deployed libraries too";
5656
qDebug() << " -qmldir=<path> : Scan for QML imports in the given path";
5757
qDebug() << " -always-overwrite : Copy files even if the target file exists";
58+
qDebug() << " -qmake=<path> : The qmake executable to use";
5859
qDebug() << "";
5960
qDebug() << "linuxdeployqt takes an application as input and makes it";
6061
qDebug() << "self-contained by copying in the Qt libraries and plugins that";
6162
qDebug() << "the application uses.";
6263
qDebug() << "";
63-
qDebug() << "It deploys the Qt instance that qmake on the $PATH points to,";
64-
qDebug() << "so make sure that it is the correct one.";
64+
qDebug() << "By default it deploys the Qt instance that qmake on the $PATH points to.";
65+
qDebug() << "The '-qmake' option can be used to point to the qmake executable";
66+
qDebug() << "to be used instead.";
6567
qDebug() << "";
6668
qDebug() << "Plugins related to a Qt library are copied in with the library.";
6769
/* TODO: To be implemented
@@ -145,7 +147,7 @@ int main(int argc, char **argv)
145147
// Allow binaries next to linuxdeployqt to be found; this is useful for bundling
146148
// this application itself together with helper binaries such as patchelf
147149
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
148-
QString oldPath = env.value("PATH");
150+
QString oldPath = env.value("PATH");
149151
QString newPath = QCoreApplication::applicationDirPath() + ":" + oldPath;
150152
LogDebug() << newPath;
151153
setenv("PATH",newPath.toUtf8().constData(),1);
@@ -169,6 +171,7 @@ int main(int argc, char **argv)
169171
QStringList additionalExecutables;
170172
bool qmldirArgumentUsed = false;
171173
QStringList qmlDirs;
174+
QString qmakeExecutable;
172175

173176
/* FHS-like mode is for an application that has been installed to a $PREFIX which is otherwise empty, e.g., /path/to/usr.
174177
* In this case, we want to construct an AppDir in /path/to. */
@@ -304,7 +307,7 @@ int main(int argc, char **argv)
304307
qDebug() << "preExistingToplevelIcon:" << preExistingToplevelIcon;
305308
} else {
306309
qDebug() << "iconToBeUsed:" << iconToBeUsed;
307-
QString targetIconPath = appDirPath + "/" + QFileInfo(iconToBeUsed).fileName();
310+
QString targetIconPath = appDirPath + "/" + QFileInfo(iconToBeUsed).fileName();
308311
if (QFile::copy(iconToBeUsed, targetIconPath)){
309312
qDebug() << "Copied" << iconToBeUsed << "to" << targetIconPath;
310313
QFile::copy(targetIconPath, appDirPath + "/.DirIcon");
@@ -358,6 +361,10 @@ int main(int argc, char **argv)
358361
} else if (argument == QByteArray("-always-overwrite")) {
359362
LogDebug() << "Argument found:" << argument;
360363
alwaysOwerwriteEnabled = true;
364+
} else if (argument.startsWith("-qmake=")) {
365+
LogDebug() << "Argument found:" << argument;
366+
int index = argument.indexOf("=");
367+
qmakeExecutable = argument.mid(index+1);
361368
} else if (argument.startsWith("-")) {
362369
LogError() << "Unknown argument" << argument << "\n";
363370
return 1;
@@ -371,7 +378,8 @@ int main(int argc, char **argv)
371378
}
372379
}
373380

374-
DeploymentInfo deploymentInfo = deployQtLibraries(appDirPath, additionalExecutables);
381+
DeploymentInfo deploymentInfo = deployQtLibraries(appDirPath, additionalExecutables,
382+
qmakeExecutable);
375383

376384
// Convenience: Look for .qml files in the current directoty if no -qmldir specified.
377385
if (qmlDirs.isEmpty()) {

shared/shared.cpp

+30-26
Original file line numberDiff line numberDiff line change
@@ -99,20 +99,20 @@ inline QDebug operator<<(QDebug debug, const AppDirInfo &info)
9999
// on architecture. See "vDSO names" in the notes section of vdso(7)
100100
// for more information.
101101
static bool lddOutputContainsLinuxVDSO(const QString &lddOutput) {
102-
// aarch64, arm, mips, x86_64, x86/x32
103-
if (lddOutput.contains(QStringLiteral("linux-vdso.so.1"))) {
104-
return true;
105-
// ppc32, s390
106-
} else if (lddOutput.contains(QStringLiteral("linux-vdso32.so.1"))) {
107-
return true;
108-
// ppc64, s390x
109-
} else if (lddOutput.contains(QStringLiteral("linux-vdso64.so.1"))) {
110-
return true;
111-
// ia64, sh, i386
112-
} else if (lddOutput.contains(QStringLiteral("linux-gate.so.1"))) {
113-
return true;
114-
}
115-
return false;
102+
// aarch64, arm, mips, x86_64, x86/x32
103+
if (lddOutput.contains(QStringLiteral("linux-vdso.so.1"))) {
104+
return true;
105+
// ppc32, s390
106+
} else if (lddOutput.contains(QStringLiteral("linux-vdso32.so.1"))) {
107+
return true;
108+
// ppc64, s390x
109+
} else if (lddOutput.contains(QStringLiteral("linux-vdso64.so.1"))) {
110+
return true;
111+
// ia64, sh, i386
112+
} else if (lddOutput.contains(QStringLiteral("linux-gate.so.1"))) {
113+
return true;
114+
}
115+
return false;
116116
}
117117

118118
bool copyFilePrintStatus(const QString &from, const QString &to)
@@ -879,7 +879,7 @@ static QString captureOutput(const QString &command)
879879
return process.readAllStandardOutput();
880880
}
881881

882-
DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &additionalExecutables)
882+
DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &additionalExecutables, const QString& qmake)
883883
{
884884
AppDirInfo applicationBundle;
885885

@@ -906,15 +906,19 @@ DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &a
906906
// Determine the location of the Qt to be bundled
907907
LogDebug() << "Using qmake to determine the location of the Qt to be bundled";
908908

909-
QString qmakePath = "";
909+
// Use the qmake executable passed in by the user:
910+
QString qmakePath = qmake;
910911

911-
// The upstream name of the binary is "qmake", for Qt 4 and Qt 5
912-
qmakePath = QStandardPaths::findExecutable("qmake");
912+
// If we did not get a qmake, first try to find "qmake", which is the
913+
// upstream name of the binary in both Qt4 and Qt5:
914+
if (qmakePath.isEmpty()) {
915+
qmakePath = QStandardPaths::findExecutable("qmake");
916+
}
913917

914918
// But openSUSE has qmake for Qt 4 and qmake-qt5 for Qt 5
915919
// Qt 4 on Fedora comes with suffix -qt4
916920
// http://www.geopsy.org/wiki/index.php/Installing_Qt_binary_packages
917-
if(qmakePath == ""){
921+
if(qmakePath.isEmpty()){
918922
if(qtDetected == 5){
919923
qmakePath = QStandardPaths::findExecutable("qmake-qt5");
920924
}
@@ -1016,7 +1020,7 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath
10161020
}
10171021
} else {
10181022
pluginList.append(QStringLiteral("imageformats/") + plugin);
1019-
}
1023+
}
10201024
}
10211025
}
10221026

@@ -1026,8 +1030,8 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath
10261030
foreach (const QString &plugin, xcbglintegrationPlugins) {
10271031
pluginList.append(QStringLiteral("xcbglintegrations/") + plugin);
10281032
}
1029-
}
1030-
1033+
}
1034+
10311035
// Also deploy plugins/iconengines/libqsvgicon.so whenever libQt5Svg.so.* is about to be deployed,
10321036
// https://github.com/probonopd/linuxdeployqt/issues/36
10331037
if (containsHowOften(deploymentInfo.deployedLibraries, "libQt5Svg")) {
@@ -1069,7 +1073,7 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath
10691073

10701074
QString sourcePath;
10711075
QString destinationPath;
1072-
1076+
10731077
// Qt WebEngine if libQt5WebEngineCore is in use
10741078
// https://doc-snapshots.qt.io/qt5-5.7/qtwebengine-deploying.html
10751079
// TODO: Rather than hardcode the source paths, somehow get them dynamically
@@ -1124,7 +1128,7 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath
11241128
destinationPath = QDir::cleanPath(dstTranslations + "/qtwebengine_locales");
11251129
recursiveCopy(sourcePath, destinationPath);
11261130
}
1127-
1131+
11281132
LogNormal() << "pluginList after having detected hopefully all required plugins:" << pluginList;
11291133

11301134
foreach (const QString &plugin, pluginList) {
@@ -1143,7 +1147,7 @@ void deployPlugins(const AppDirInfo &appDirInfo, const QString &pluginSourcePath
11431147
QString relativePath = dir.relativeFilePath(appDirInfo.path + "/" + libraries[0].libraryDestinationDirectory);
11441148
relativePath.remove(0, 3); // remove initial '../'
11451149
changeIdentification("$ORIGIN/" + relativePath, QFileInfo(destinationPath).canonicalFilePath());
1146-
1150+
11471151
}
11481152
}
11491153
}
@@ -1224,7 +1228,7 @@ bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo,
12241228
argumentList.append(qtToBeBundledInfo.value("QT_INSTALL_QML"));
12251229

12261230
LogDebug() << "qmlImportsPath (QT_INSTALL_QML):" << qtToBeBundledInfo.value("QT_INSTALL_QML");
1227-
1231+
12281232
// run qmlimportscanner
12291233
QProcess qmlImportScanner;
12301234
LogDebug() << qmlImportScannerPath << argumentList;

shared/shared.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ QString findAppBinary(const QString &appDirPath);
112112
QList<LibraryInfo> getQtLibraries(const QString &path, const QString &appDirPath, const QSet<QString> &rpaths);
113113
QList<LibraryInfo> getQtLibraries(const QStringList &lddLines, const QString &appDirPath, const QSet<QString> &rpaths);
114114
QString copyLibrary(const LibraryInfo &library, const QString path);
115-
DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &additionalExecutables);
115+
DeploymentInfo deployQtLibraries(const QString &appDirPath,
116+
const QStringList &additionalExecutables,
117+
const QString &qmake);
116118
DeploymentInfo deployQtLibraries(QList<LibraryInfo> libraries,const QString &bundlePath, const QStringList &binaryPaths, bool useLoaderPath);
117119
void deployPlugins(const QString &appDirPath, DeploymentInfo deploymentInfo);
118120
bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo, QStringList &qmlDirs);

0 commit comments

Comments
 (0)