+6
-4
@@ -23,14 +23,16 @@ install:
|
|||||||
script:
|
script:
|
||||||
- source /opt/qt*/bin/qt*-env.sh
|
- source /opt/qt*/bin/qt*-env.sh
|
||||||
- /opt/qt*/bin/qmake linuxdeployqt.pro
|
- /opt/qt*/bin/qmake linuxdeployqt.pro
|
||||||
- make -j7
|
|
||||||
|
- make -j2
|
||||||
|
|
||||||
- mkdir -p linuxdeployqt.AppDir/usr/bin/
|
- mkdir -p linuxdeployqt.AppDir/usr/bin/
|
||||||
- cp /usr/local/bin/patchelf linuxdeployqt.AppDir/usr/bin/
|
- cp /usr/local/bin/patchelf linuxdeployqt.AppDir/usr/bin/
|
||||||
- cp /usr/local/bin/appimagetool linuxdeployqt.AppDir/usr/bin/
|
- cp /usr/local/bin/appimagetool linuxdeployqt.AppDir/usr/bin/
|
||||||
- find linuxdeployqt.AppDir/
|
- find linuxdeployqt.AppDir/
|
||||||
- export VERSION=continuous
|
- export VERSION=continuousfhs
|
||||||
- cp ./linuxdeployqt/linuxdeployqt linuxdeployqt.AppDir/linuxdeployqt
|
- cp ./linuxdeployqt/linuxdeployqt linuxdeployqt.AppDir/usr/bin/
|
||||||
- ./linuxdeployqt/linuxdeployqt linuxdeployqt.AppDir/linuxdeployqt -verbose=3 -appimage
|
- ./linuxdeployqt/linuxdeployqt linuxdeployqt.AppDir/usr/bin/linuxdeployqt -verbose=3 -appimage
|
||||||
- ls -lh
|
- ls -lh
|
||||||
- find *.AppDir
|
- find *.AppDir
|
||||||
- wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh
|
- wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh
|
||||||
|
|||||||
@@ -39,9 +39,8 @@ tar xf patchelf-0.9.tar.bz2
|
|||||||
* Optional if you want to generate AppImages: Download [appimagetool](https://github.com/probonopd/AppImageKit/releases) and put it into your $PATH, e.g., into `/usr/local/bin`. Make sure it is renamed to `appimagetool` and is `chmod a+x`
|
* Optional if you want to generate AppImages: Download [appimagetool](https://github.com/probonopd/AppImageKit/releases) and put it into your $PATH, e.g., into `/usr/local/bin`. Make sure it is renamed to `appimagetool` and is `chmod a+x`
|
||||||
|
|
||||||
```
|
```
|
||||||
wget https://github.com/probonopd/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O appimagetool
|
sudo wget -c "https://github.com/probonopd/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" -O /usr/local/bin/appimagetool
|
||||||
chmod a+x appimagetool
|
sudo chmod a+x /usr/local/bin/appimagetool
|
||||||
sudo mv appimagetool /usr/local/bin/
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
+36
-14
@@ -36,7 +36,7 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
QString appBinaryPath;
|
extern QString appBinaryPath;
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
appBinaryPath = QString::fromLocal8Bit(argv[1]);
|
appBinaryPath = QString::fromLocal8Bit(argv[1]);
|
||||||
@@ -91,34 +91,54 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDir dir;
|
|
||||||
// QString appDir = QDir::cleanPath(appFile + "/../" + appName + ".AppDir");
|
|
||||||
QString appDir = QDir::cleanPath(appBinaryPath + "/../");
|
QString appDir = QDir::cleanPath(appBinaryPath + "/../");
|
||||||
|
|
||||||
if (QDir().exists(appDir) == false) {
|
if (QDir().exists(appDir) == false) {
|
||||||
qDebug() << "Error: Could not find AppDir" << appDir;
|
qDebug() << "Error: Could not find AppDir" << appDir;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString appDirPath = appDir;
|
|
||||||
|
|
||||||
QFile appRun(appDir + "/AppRun");
|
|
||||||
|
|
||||||
if(appRun.exists()){
|
|
||||||
appRun.remove();
|
|
||||||
}
|
|
||||||
QFile::link(appName, appDir + "/AppRun");
|
|
||||||
|
|
||||||
bool plugins = true;
|
bool plugins = true;
|
||||||
bool appimage = false;
|
bool appimage = false;
|
||||||
extern bool runStripEnabled;
|
extern bool runStripEnabled;
|
||||||
extern bool bundleAllButCoreLibs;
|
extern bool bundleAllButCoreLibs;
|
||||||
|
extern bool fhsLikeMode;
|
||||||
|
extern QString fhsPrefix;
|
||||||
extern bool alwaysOwerwriteEnabled;
|
extern bool alwaysOwerwriteEnabled;
|
||||||
extern QStringList librarySearchPath;
|
extern QStringList librarySearchPath;
|
||||||
QStringList additionalExecutables;
|
QStringList additionalExecutables;
|
||||||
bool qmldirArgumentUsed = false;
|
bool qmldirArgumentUsed = false;
|
||||||
QStringList qmlDirs;
|
QStringList qmlDirs;
|
||||||
|
|
||||||
|
/* FHS-like mode is for an application that has been installed to a $PREFIX which is otherwise empty, e.g., /path/to/usr.
|
||||||
|
* In this case, we want to construct an AppDir in /path/to. */
|
||||||
|
if (QDir().exists((QDir::cleanPath(appBinaryPath + "/../../bin"))) == true) {
|
||||||
|
fhsPrefix = QDir::cleanPath(appBinaryPath + "/../../");
|
||||||
|
qDebug() << "FHS-like mode with PREFIX, fhsPrefix:" << fhsPrefix;
|
||||||
|
fhsLikeMode = true;
|
||||||
|
} else {
|
||||||
|
qDebug() << "Not using FHS-like mode, appBinaryPath:" << appBinaryPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString appDirPath;
|
||||||
|
QString relativeBinPath;
|
||||||
|
if(fhsLikeMode == false){
|
||||||
|
appDirPath = appDir;
|
||||||
|
relativeBinPath = appName;
|
||||||
|
} else {
|
||||||
|
appDirPath = QDir::cleanPath(fhsPrefix + "/../");
|
||||||
|
QString relativePrefix = fhsPrefix.replace(appDirPath+"/", "");
|
||||||
|
relativeBinPath = relativePrefix + "/bin/" + appName;
|
||||||
|
}
|
||||||
|
qDebug() << "appDirPath:" << appDirPath;
|
||||||
|
qDebug() << "relativeBinPath:" << relativeBinPath;
|
||||||
|
|
||||||
|
QFile appRun(appDirPath + "/AppRun");
|
||||||
|
if(appRun.exists()){
|
||||||
|
appRun.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile::link(relativeBinPath, appDirPath + "/AppRun");
|
||||||
|
|
||||||
for (int i = 2; i < argc; ++i) {
|
for (int i = 2; i < argc; ++i) {
|
||||||
QByteArray argument = QByteArray(argv[i]);
|
QByteArray argument = QByteArray(argv[i]);
|
||||||
if (argument == QByteArray("-no-plugins")) {
|
if (argument == QByteArray("-no-plugins")) {
|
||||||
@@ -175,8 +195,10 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (appimage) {
|
if (appimage) {
|
||||||
if(checkAppImagePrerequisites(appDirPath) == false)
|
if(checkAppImagePrerequisites(appDirPath) == false){
|
||||||
|
LogError() << "checkAppImagePrerequisites failed\n";
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeploymentInfo deploymentInfo = deployQtLibraries(appDirPath, additionalExecutables);
|
DeploymentInfo deploymentInfo = deployQtLibraries(appDirPath, additionalExecutables);
|
||||||
|
|||||||
+28
-24
@@ -44,9 +44,11 @@
|
|||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
|
|
||||||
|
QString appBinaryPath;
|
||||||
bool runStripEnabled = true;
|
bool runStripEnabled = true;
|
||||||
bool bundleAllButCoreLibs = false;
|
bool bundleAllButCoreLibs = false;
|
||||||
|
bool fhsLikeMode = false;
|
||||||
|
QString fhsPrefix;
|
||||||
bool alwaysOwerwriteEnabled = false;
|
bool alwaysOwerwriteEnabled = false;
|
||||||
QStringList librarySearchPath;
|
QStringList librarySearchPath;
|
||||||
bool appstoreCompliant = false;
|
bool appstoreCompliant = false;
|
||||||
@@ -81,7 +83,7 @@ QDebug operator<<(QDebug debug, const LibraryInfo &info)
|
|||||||
return debug;
|
return debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString bundleLibraryDirectory = "lib"; // the same directory as the main executable; could define a relative subdirectory here
|
QString bundleLibraryDirectory;
|
||||||
|
|
||||||
inline QDebug operator<<(QDebug debug, const AppDirInfo &info)
|
inline QDebug operator<<(QDebug debug, const AppDirInfo &info)
|
||||||
{
|
{
|
||||||
@@ -217,6 +219,14 @@ int containsHowOften(QStringList haystack, QString needle) {
|
|||||||
|
|
||||||
LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath, const QSet<QString> &rpaths)
|
LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath, const QSet<QString> &rpaths)
|
||||||
{
|
{
|
||||||
|
if(fhsLikeMode == false){
|
||||||
|
bundleLibraryDirectory= "lib"; // relative to bundle
|
||||||
|
} else {
|
||||||
|
QString relativePrefix = fhsPrefix.replace(appDirPath+"/", "");
|
||||||
|
bundleLibraryDirectory = relativePrefix + "/lib/";
|
||||||
|
}
|
||||||
|
LogDebug() << "bundleLibraryDirectory:" << bundleLibraryDirectory;
|
||||||
|
|
||||||
LibraryInfo info;
|
LibraryInfo info;
|
||||||
QString trimmed = line.trimmed();
|
QString trimmed = line.trimmed();
|
||||||
|
|
||||||
@@ -338,21 +348,6 @@ LibraryInfo parseLddLibraryLine(const QString &line, const QString &appDirPath,
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString findAppBinary(const QString &appDirPath)
|
|
||||||
{
|
|
||||||
QString binaryPath;
|
|
||||||
|
|
||||||
// FIXME: Do without the need for an AppRun symlink
|
|
||||||
// by passing appBinaryPath from main.cpp here
|
|
||||||
binaryPath = appDirPath + "/" + "AppRun";
|
|
||||||
|
|
||||||
if (QFile::exists(binaryPath))
|
|
||||||
return binaryPath;
|
|
||||||
|
|
||||||
LogError() << "Could not find bundle binary for" << appDirPath << "at" << binaryPath;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList findAppLibraries(const QString &appDirPath)
|
QStringList findAppLibraries(const QString &appDirPath)
|
||||||
{
|
{
|
||||||
QStringList result;
|
QStringList result;
|
||||||
@@ -678,7 +673,7 @@ void runStrip(const QString &binaryPath)
|
|||||||
|
|
||||||
void stripAppBinary(const QString &bundlePath)
|
void stripAppBinary(const QString &bundlePath)
|
||||||
{
|
{
|
||||||
runStrip(findAppBinary(bundlePath));
|
runStrip(appBinaryPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -772,7 +767,7 @@ DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &a
|
|||||||
|
|
||||||
applicationBundle.path = appDirPath;
|
applicationBundle.path = appDirPath;
|
||||||
LogDebug() << "applicationBundle.path:" << applicationBundle.path;
|
LogDebug() << "applicationBundle.path:" << applicationBundle.path;
|
||||||
applicationBundle.binaryPath = findAppBinary(appDirPath);
|
applicationBundle.binaryPath = appBinaryPath;
|
||||||
LogDebug() << "applicationBundle.binaryPath:" << applicationBundle.binaryPath;
|
LogDebug() << "applicationBundle.binaryPath:" << applicationBundle.binaryPath;
|
||||||
|
|
||||||
// Determine the location of the Qt to be bundled
|
// Determine the location of the Qt to be bundled
|
||||||
@@ -804,7 +799,11 @@ DeploymentInfo deployQtLibraries(const QString &appDirPath, const QStringList &a
|
|||||||
setenv("LD_LIBRARY_PATH",newPath.toUtf8().constData(),1);
|
setenv("LD_LIBRARY_PATH",newPath.toUtf8().constData(),1);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeIdentification("$ORIGIN/" + bundleLibraryDirectory, applicationBundle.binaryPath);
|
if(fhsLikeMode == false){
|
||||||
|
changeIdentification("$ORIGIN/" + bundleLibraryDirectory, applicationBundle.binaryPath);
|
||||||
|
} else {
|
||||||
|
changeIdentification("$ORIGIN/../lib/" + bundleLibraryDirectory, applicationBundle.binaryPath);
|
||||||
|
}
|
||||||
applicationBundle.libraryPaths = findAppLibraries(appDirPath);
|
applicationBundle.libraryPaths = findAppLibraries(appDirPath);
|
||||||
LogDebug() << "applicationBundle.libraryPaths:" << applicationBundle.libraryPaths;
|
LogDebug() << "applicationBundle.libraryPaths:" << applicationBundle.libraryPaths;
|
||||||
|
|
||||||
@@ -986,7 +985,7 @@ void createQtConf(const QString &appDirPath)
|
|||||||
"Qml2Imports = qml\n";
|
"Qml2Imports = qml\n";
|
||||||
|
|
||||||
QString filePath = appDirPath + "/"; // Is picked up when placed next to the main executable
|
QString filePath = appDirPath + "/"; // Is picked up when placed next to the main executable
|
||||||
QString fileName = filePath + "qt.conf";
|
QString fileName = appBinaryPath + "/../qt.conf";
|
||||||
|
|
||||||
QDir().mkpath(filePath);
|
QDir().mkpath(filePath);
|
||||||
|
|
||||||
@@ -1036,7 +1035,7 @@ void deployPlugins(const QString &appDirPath, DeploymentInfo deploymentInfo)
|
|||||||
{
|
{
|
||||||
AppDirInfo applicationBundle;
|
AppDirInfo applicationBundle;
|
||||||
applicationBundle.path = appDirPath;
|
applicationBundle.path = appDirPath;
|
||||||
applicationBundle.binaryPath = findAppBinary(appDirPath);
|
applicationBundle.binaryPath = appBinaryPath;
|
||||||
|
|
||||||
const QString pluginDestinationPath = appDirPath + "/" + "plugins";
|
const QString pluginDestinationPath = appDirPath + "/" + "plugins";
|
||||||
deployPlugins(applicationBundle, deploymentInfo.pluginPath, pluginDestinationPath, deploymentInfo);
|
deployPlugins(applicationBundle, deploymentInfo.pluginPath, pluginDestinationPath, deploymentInfo);
|
||||||
@@ -1104,7 +1103,7 @@ bool deployQmlImports(const QString &appDirPath, DeploymentInfo deploymentInfo,
|
|||||||
LogDebug() << qmlImportScannerPath << argumentList;
|
LogDebug() << qmlImportScannerPath << argumentList;
|
||||||
qmlImportScanner.start(qmlImportScannerPath, argumentList);
|
qmlImportScanner.start(qmlImportScannerPath, argumentList);
|
||||||
if (!qmlImportScanner.waitForStarted()) {
|
if (!qmlImportScanner.waitForStarted()) {
|
||||||
LogError() << "Could not start qmlimpoortscanner. Process error is" << qmlImportScanner.errorString();
|
LogError() << "Could not start qmlimportscanner. Process error is" << qmlImportScanner.errorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
qmlImportScanner.waitForFinished();
|
qmlImportScanner.waitForFinished();
|
||||||
@@ -1208,7 +1207,6 @@ void changeQtLibraries(const QList<LibraryInfo> libraries, const QStringList &bi
|
|||||||
|
|
||||||
void changeQtLibraries(const QString appPath, const QString &qtPath)
|
void changeQtLibraries(const QString appPath, const QString &qtPath)
|
||||||
{
|
{
|
||||||
const QString appBinaryPath = findAppBinary(appPath);
|
|
||||||
const QStringList libraryPaths = findAppLibraries(appPath);
|
const QStringList libraryPaths = findAppLibraries(appPath);
|
||||||
const QList<LibraryInfo> libraries = getQtLibrariesForPaths(QStringList() << appBinaryPath << libraryPaths, appPath, getBinaryRPaths(appBinaryPath, true));
|
const QList<LibraryInfo> libraries = getQtLibrariesForPaths(QStringList() << appBinaryPath << libraryPaths, appPath, getBinaryRPaths(appBinaryPath, true));
|
||||||
if (libraries.isEmpty()) {
|
if (libraries.isEmpty()) {
|
||||||
@@ -1223,6 +1221,12 @@ void changeQtLibraries(const QString appPath, const QString &qtPath)
|
|||||||
|
|
||||||
bool checkAppImagePrerequisites(const QString &appDirPath)
|
bool checkAppImagePrerequisites(const QString &appDirPath)
|
||||||
{
|
{
|
||||||
|
if(fhsLikeMode == true){
|
||||||
|
/* In FHS-like mode, we assume that there will be a desktop file
|
||||||
|
* and icon file that appimagetool will be able to pick up */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QDirIterator iter(appDirPath, QStringList() << QString::fromLatin1("*.desktop"),
|
QDirIterator iter(appDirPath, QStringList() << QString::fromLatin1("*.desktop"),
|
||||||
QDir::Files, QDirIterator::Subdirectories);
|
QDir::Files, QDirIterator::Subdirectories);
|
||||||
if (!iter.hasNext()) {
|
if (!iter.hasNext()) {
|
||||||
|
|||||||
@@ -40,8 +40,11 @@ extern int logLevel;
|
|||||||
#define LogNormal() if (logLevel < 2) {} else qDebug() << "Log:"
|
#define LogNormal() if (logLevel < 2) {} else qDebug() << "Log:"
|
||||||
#define LogDebug() if (logLevel < 3) {} else qDebug() << "Log:"
|
#define LogDebug() if (logLevel < 3) {} else qDebug() << "Log:"
|
||||||
|
|
||||||
|
extern QString appBinaryPath;
|
||||||
extern bool runStripEnabled;
|
extern bool runStripEnabled;
|
||||||
extern bool bundleAllButCoreLibs;
|
extern bool bundleAllButCoreLibs;
|
||||||
|
extern bool fhsLikeMode;
|
||||||
|
extern QString fhsPrefix;
|
||||||
|
|
||||||
class LibraryInfo
|
class LibraryInfo
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user