Browse Source

Basic AppImage generation if AppImageAssistant is on the $PATH

master
probonopd 8 years ago
parent
commit
bfcd7681da
  1. 14
      linuxdeployqt/main.cpp
  2. 76
      shared/shared.cpp
  3. 2
      shared/shared.h

14
linuxdeployqt/main.cpp

@ -95,7 +95,7 @@ int main(int argc, char **argv)
QFile::link(appBinaryPath, appDir + "/AppRun"); QFile::link(appBinaryPath, appDir + "/AppRun");
bool plugins = true; bool plugins = true;
bool dmg = false; bool appimage = false;
extern bool runStripEnabled; extern bool runStripEnabled;
extern bool alwaysOwerwriteEnabled; extern bool alwaysOwerwriteEnabled;
extern QStringList librarySearchPath; extern QStringList librarySearchPath;
@ -108,9 +108,9 @@ int main(int argc, char **argv)
if (argument == QByteArray("-no-pluginss")) { if (argument == QByteArray("-no-pluginss")) {
LogDebug() << "Argument found:" << argument; LogDebug() << "Argument found:" << argument;
plugins = false; plugins = false;
} else if (argument == QByteArray("-dmg")) { } else if (argument == QByteArray("-appimage")) {
LogDebug() << "Argument found:" << argument; LogDebug() << "Argument found:" << argument;
dmg = true; appimage = true;
} else if (argument == QByteArray("-no-strip")) { } else if (argument == QByteArray("-no-strip")) {
LogDebug() << "Argument found:" << argument; LogDebug() << "Argument found:" << argument;
runStripEnabled = false; runStripEnabled = false;
@ -154,6 +154,11 @@ int main(int argc, char **argv)
} }
} }
if (appimage) {
if(checkAppImagePrerequisites(appDirPath) == false)
return 1;
}
DeploymentInfo deploymentInfo = deployQtLibraries(appDirPath, additionalExecutables); DeploymentInfo deploymentInfo = deployQtLibraries(appDirPath, additionalExecutables);
// Convenience: Look for .qml files in the current directoty if no -qmldir specified. // Convenience: Look for .qml files in the current directoty if no -qmldir specified.
@ -185,8 +190,7 @@ int main(int argc, char **argv)
if (runStripEnabled) if (runStripEnabled)
stripAppBinary(appDirPath); stripAppBinary(appDirPath);
if (dmg) { if (appimage) {
LogNormal();
createAppImage(appDirPath); createAppImage(appDirPath);
} }

76
shared/shared.cpp

@ -980,32 +980,70 @@ void changeQtLibraries(const QString appPath, const QString &qtPath)
} }
} }
void createAppImage(const QString &appDirPath) bool checkAppImagePrerequisites(const QString &appDirPath)
{ {
QString appBaseName = appDirPath; QDirIterator iter(appDirPath, QStringList() << QString::fromLatin1("*.desktop"),
appBaseName.chop(4); // remove ".app" from end QDir::Files, QDirIterator::Subdirectories);
if (!iter.hasNext()) {
LogError() << "Desktop file missing, cannot create AppImage";
// TODO: Create a generic desktop file (never overwrite an existing one though!)
return false;
}
QString dmgName = appBaseName + ".dmg"; // TODO: Compare whether the icon filename matches the Icon= entry without ending in the *.desktop file above
QDirIterator iter2(appDirPath, QStringList() << QString::fromLatin1("*.png"),
QDir::Files, QDirIterator::Subdirectories);
if (!iter2.hasNext()) {
LogError() << "Icon file missing, cannot create AppImage";
// TODO: Create a generic icon (never overwrite an existing one though!)
return false;
}
return true;
}
QFile dmg(dmgName); void createAppImage(const QString &appDirPath)
{
QString appImagePath = appDirPath + ".AppImage";
if (dmg.exists() && alwaysOwerwriteEnabled) QFile appImage(appImagePath);
dmg.remove(); LogDebug() << "appImageName:" << appImagePath;
if (dmg.exists()) { if (appImage.exists() && alwaysOwerwriteEnabled)
LogNormal() << "Disk image already exists, skipping .dmg creation for" << dmg.fileName(); appImage.remove();
if (appImage.exists()) {
LogNormal() << "AppImage already exists, skipping .AppImage creation for" << appImage.fileName();
LogNormal() << "use -always-overwrite to overwrite";
} else { } else {
LogNormal() << "Creating disk image (.dmg) for" << appDirPath; LogNormal() << "Creating AppImage for" << appDirPath;
} }
// More dmg options can be found in the hdiutil man page. QStringList options = QStringList() << appDirPath << appImagePath;
QStringList options = QStringList()
<< "create" << dmgName QProcess appImageAssistant;
<< "-srcfolder" << appDirPath appImageAssistant.start("AppImageAssistant", options);
<< "-format" << "UDZO" appImageAssistant.waitForFinished(-1);
<< "-volname" << appBaseName;
// FIXME: How to get the output to appear on the console as it happens rather than after the fact?
QString output = appImageAssistant.readAllStandardError();
QStringList outputLines = output.split("\n", QString::SkipEmptyParts);
for (const QString &outputLine : outputLines) {
// xorriso spits out a lot of WARNINGs which in the context of AppImage can be safely ignored
if(!outputLine.contains("WARNING")) {
LogNormal() << outputLine;
}
}
QProcess hdutil; // AppImageAssistant doesn't always give nonzero error codes, so we check for the presence of the AppImage file
hdutil.start("hdiutil", options); // This should eventually be fixed in AppImageAssistant
hdutil.waitForFinished(-1); if (!QFile(appDirPath).exists()) {
LogError() << "FIXME: TODO: Check for the presence of AppImageAssistant on the $PATH";
if(appImageAssistant.readAllStandardOutput().isEmpty() == false)
LogError() << "AppImageAssistant:" << appImageAssistant.readAllStandardOutput();
if(appImageAssistant.readAllStandardError().isEmpty() == false)
LogError() << "AppImageAssistant:" << appImageAssistant.readAllStandardError();
} else {
LogNormal() << "Created AppImage at" << appImagePath;
}
} }

2
shared/shared.h

@ -125,6 +125,6 @@ void stripAppBinary(const QString &bundlePath);
QString findAppBinary(const QString &appDirPath); QString findAppBinary(const QString &appDirPath);
QStringList findAppLibraries(const QString &appDirPath); QStringList findAppLibraries(const QString &appDirPath);
void createAppImage(const QString &appBundlePath); void createAppImage(const QString &appBundlePath);
bool checkAppImagePrerequisites(const QString &appBundlePath);
#endif #endif

Loading…
Cancel
Save