420 lines
10 KiB
C++
Raw Normal View History

2018-08-19 11:00:13 +03:00
/*
* Copyright (C) 2018 QuasarApp.
* Distributed under the lgplv3 software license, see the accompanying
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
2018-08-17 20:47:49 +03:00
#include "deploy.h"
#include <QFileInfo>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <quasarapp.h>
#include <QProcess>
bool Deploy::getDeployQml() const {
return deployQml;
}
void Deploy::setDeployQml(bool value) {
deployQml = value;
}
QString Deploy::getQmlScaner() const {
return qmlScaner;
}
void Deploy::setQmlScaner(const QString &value) {
qmlScaner = value;
deployQml = QFileInfo(qmlScaner).isFile();
}
QString Deploy::getQmake() const {
return qmake;
}
void Deploy::setQmake(const QString &value) {
qmake = value;
}
QString Deploy::getTarget() const {
return target;
}
bool Deploy::setTarget(const QString &value) {
target = value;
2018-08-17 23:54:29 +03:00
targetDir = QFileInfo(target).absolutePath();
2018-08-17 20:47:49 +03:00
2018-08-17 23:54:29 +03:00
if (!QFileInfo::exists(targetDir + QDir::separator() + "lib") &&
!QDir(targetDir).mkdir("lib")) {
2018-08-17 20:47:49 +03:00
return false;
}
if (QuasarAppUtils::isEndable("qmlDir") &&
2018-08-17 23:54:29 +03:00
!QFileInfo::exists(targetDir + QDir::separator() + "qml") &&
2018-08-17 20:47:49 +03:00
!QDir(targetDir).mkdir("qml")){
return false;
}
return true;
}
2018-08-19 11:00:13 +03:00
bool Deploy::createRunScript() {
QString content =
"#!/bin/sh\n"
"BASEDIR=$(dirname $0)\n"
"export LD_LIBRARY_PATH=\"$BASEDIR/lib:$BASEDIR\"\n"
"export QML_IMPORT_PATH=\"$BASEDIR/qml\"\n"
"export QML2_IMPORT_PATH=\"$BASEDIR/qml\"\n"
"export QT_PLUGIN_PATH=\"$BASEDIR/plugins\"\n"
"export QT_QPA_PLATFORM_PLUGIN_PATH=\"$BASEDIR/plugins/platforms\"\n"
"$BASEDIR//%1";
content = content.arg(QFileInfo(target).fileName());
2018-08-19 14:43:26 +03:00
QString fname = targetDir + QDir::separator() + QFileInfo(target).fileName() + ".sh";
2018-08-19 11:00:13 +03:00
QFile F(fname);
if (!F.open(QIODevice::WriteOnly)) {
return false;
}
F.write(content.toUtf8());
F.flush();
F.close();
return F.setPermissions(QFileDevice::ExeUser |
QFileDevice::WriteUser |
QFileDevice::ReadUser);
}
2018-08-17 20:47:49 +03:00
void Deploy::deploy() {
qInfo() << "target deploy started!!";
if (QuasarAppUtils::isEndable("ignoreCudaLib")) {
ignoreList << "libicudata" << "libicui" << "libicuuc";
}
if (QuasarAppUtils::isEndable("ignore")) {
auto list = QuasarAppUtils::getStrArg("ignore").split(',');
ignoreList.append(list);
}
2018-08-17 20:47:49 +03:00
extract(target);
copyFiles(QtLibs, targetDir + QDir::separator() + "lib");
if (QuasarAppUtils::isEndable("deploy-not-qt")) {
copyFiles(noQTLibs, targetDir + QDir::separator() + "lib");
}
2018-08-17 23:54:29 +03:00
if (!QuasarAppUtils::isEndable("noStrip")) {
strip(targetDir + QDir::separator() + "lib");
}
copyPlugins(neededPlugins);
if (!QuasarAppUtils::isEndable("noStrip")) {
strip(targetDir + QDir::separator() + "plugins");
}
2018-08-18 22:36:28 +03:00
if (deployQml && !extractQml()) {
qCritical() << "qml not extacted!";
}
2018-08-19 11:00:13 +03:00
if (!createRunScript()) {
qCritical() << "run script not created!";
}
2018-08-17 20:47:49 +03:00
}
QString Deploy::getQtDir() const {
return qtDir;
}
void Deploy::setQtDir(const QString &value) {
qtDir = value;
}
bool Deploy::isQtLib(const QString &lib) const {
QFileInfo info(lib);
2018-08-17 23:54:29 +03:00
return info.absolutePath().contains(qtDir);
2018-08-17 20:47:49 +03:00
}
void Deploy::copyFiles(const QStringList &files , const QString& target) {
for (auto file : files) {
2018-08-19 11:00:13 +03:00
if (QFileInfo(file).absolutePath() != targetDir && !copyFile(file, target)) {
2018-08-17 20:47:49 +03:00
qWarning() << file + " not copied";
}
}
}
bool Deploy::copyFile(const QString &file, const QString& target) {
auto info = QFileInfo(file);
auto name = info.fileName();
2018-08-17 23:54:29 +03:00
info.setFile(target + QDir::separator() + name);
2018-08-17 20:47:49 +03:00
if (QuasarAppUtils::isEndable("always-overwrite") &&
2018-08-17 23:54:29 +03:00
info.exists() && !QFile::remove(target + QDir::separator() + name)){
2018-08-17 20:47:49 +03:00
return false;
}
qInfo() << "copy :" << target + QDir::separator() + name;
return QFile::copy(file, target + QDir::separator() + name);
}
void Deploy::extract(const QString &file) {
qInfo() << "extract lib :" << file;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("LD_LIBRARY_PATH", qtDir + "/lib");
2018-08-17 23:54:29 +03:00
env.insert("LD_LIBRARY_PATH", targetDir);
2018-08-17 20:47:49 +03:00
env.insert("QML_IMPORT_PATH", qtDir + "/qml");
env.insert("QML2_IMPORT_PATH", qtDir + "/qml");
env.insert("QT_PLUGIN_PATH", qtDir + "/plugins");
env.insert("QT_QPA_PLATFORM_PLUGIN_PATH", qtDir + "/plugins/platforms");
QProcess P;
P.setProcessEnvironment(env);
P.start("ldd " + file, QProcess::ReadOnly);
if (!P.waitForStarted()) return;
if (!P.waitForFinished()) return;
auto data = QString(P.readAll());
QStringList libs;
for (QString &line : data.split("\n", QString::SkipEmptyParts)) {
line = line.simplified();
auto innerlist = line.split(" ");
if (innerlist.count() < 3) continue;
line = innerlist[2];
if (!line.startsWith("/")) {
continue;
}
bool isIgnore = false;
for (auto ignore: ignoreList) {
if (line.contains(ignore)) {
qInfo() << line << " ignored by filter" << ignore;
isIgnore = true;
}
}
if (isIgnore) {
continue;
}
2018-08-17 20:47:49 +03:00
if (isQtLib(line) && !QtLibs.contains(line)) {
QtLibs << line;
extract(line);
extractPlugins(line);
2018-08-17 23:54:29 +03:00
continue;
2018-08-17 20:47:49 +03:00
}
2018-08-17 23:54:29 +03:00
if (QuasarAppUtils::isEndable("deploy-not-qt") &&
!noQTLibs.contains(line)) {
2018-08-17 20:47:49 +03:00
noQTLibs << line;
extract(line);
}
}
}
void Deploy::extractPlugins(const QString &lib) {
qInfo() << "extrac plugin for " << lib;
if (lib.contains("libQt5Core") && !neededPlugins.contains("xcbglintegrations")) {
neededPlugins << "xcbglintegrations"
<< "platforms";
} else if (lib.contains("libQt5Gui") && !neededPlugins.contains("imageformats")) {
neededPlugins << "imageformats"
<< "iconengines";
} else if (lib.contains("libQt5Sql") && !neededPlugins.contains("sqldrivers")) {
neededPlugins << "sqldrivers";
} else if (lib.contains("libQt5Gamepad") && !neededPlugins.contains("gamepads")) {
neededPlugins << "gamepads";
} else if (lib.contains("libQt5PrintSupport") && !neededPlugins.contains("printsupport")) {
neededPlugins << "printsupport";
} else if (lib.contains("libQt5Sensors") && !neededPlugins.contains("sensors")) {
neededPlugins << "sensors"
<< "sensorgestures";
} else if (lib.contains("libQt5Positioning") && !neededPlugins.contains("geoservices")) {
neededPlugins << "geoservices"
<< "position"
<< "geometryloaders";
} else if (lib.contains("libQt5Multimedia") && !neededPlugins.contains("audio")) {
neededPlugins << "audio"
<< "mediaservice"
<< "playlistformats";
}
}
bool Deploy::copyPlugin(const QString &plugin) {
QDir dir(qtDir);
if (!dir.cd("plugins")) {
return false;
}
if (!dir.cd(plugin)) {
return false;
}
QDir dirTo(targetDir);
if (!dirTo.cd("plugins")) {
if (!dirTo.mkdir("plugins")) {
return false;
}
if (!dirTo.cd("plugins")) {
return false;
}
}
if (!dirTo.cd(plugin)) {
if (!dirTo.mkdir(plugin)) {
return false;
}
if (!dirTo.cd(plugin)) {
return false;
}
}
return copyFolder(dir, dirTo, ".so.debug");
}
void Deploy::copyPlugins(const QStringList &list) {
for (auto plugin : list) {
if ( !copyPlugin(plugin)) {
qWarning () << plugin << " not copied!";
}
}
}
bool Deploy::copyFolder( QDir &from, QDir &to, const QString& filter) {
if (!(from.isReadable() && to.isReadable())){
return false;
}
2018-08-18 22:36:28 +03:00
auto list = from.entryInfoList(QDir::NoDotAndDotDot|QDir::AllEntries);
for (auto item : list ) {
if (QFileInfo(item).isDir()) {
2018-08-18 22:36:28 +03:00
if (!from.cd(item.baseName())) {
qWarning() <<"not open " << from.absolutePath() + QDir::separator() + item.baseName();
continue;
}
2018-08-18 22:36:28 +03:00
if (!QFileInfo::exists(to.absolutePath() + QDir::separator() + item.baseName()) &&
!to.mkdir(item.baseName())) {
qWarning() <<"not create " << to.absolutePath() + QDir::separator() + item.baseName();
continue;
}
2018-08-18 22:36:28 +03:00
if (!to.cd(item.baseName())) {
qWarning() <<"not open " << to.absolutePath() + QDir::separator() + item.baseName();
continue;
}
copyFolder(from, to, filter);
from.cdUp();
to.cdUp();
} else {
2018-08-18 22:36:28 +03:00
if (!filter.isEmpty() && item.fileName().contains(filter)) {
qInfo() << item << " ignored by filter " << filter;
continue;
}
2018-08-18 22:36:28 +03:00
if (!copyFile(from.absolutePath() + QDir::separator() + item.fileName(), to.absolutePath())) {
qWarning() <<"not copied file " << to.absolutePath() + QDir::separator() + item.fileName();
}
}
}
return true;
}
2018-08-18 22:36:28 +03:00
bool Deploy::extractQml() {
auto qmlDir = QuasarAppUtils::getStrArg("qmlDir");
if (!QFileInfo::exists(qmlDir)){
qWarning() << "qml dir wrong!";
return false;
}
QDir dir(qmlDir);
QDir dirTo(targetDir);
if (!dirTo.cd("qml")) {
if (!dirTo.mkdir("qml")) {
return false;
}
if (!dirTo.cd("qml")) {
return false;
}
}
return copyFolder(dir, dirTo, ".so.debug");
}
2018-08-18 19:02:07 +03:00
void Deploy::clear() {
QDir dir(targetDir);
if (dir.cd("lib")) {
dir.removeRecursively();
dir.cdUp();
}
if (dir.cd("plugins")) {
dir.removeRecursively();
dir.cdUp();
}
2018-08-18 22:36:28 +03:00
if (dir.cd("qml")) {
dir.removeRecursively();
dir.cdUp();
}
2018-08-18 19:02:07 +03:00
}
2018-08-17 23:54:29 +03:00
void Deploy::strip(const QString& dir) {
QProcess P;
P.setWorkingDirectory(dir);
P.setArguments(QStringList() << "*");
P.start("strip", QProcess::ReadOnly);
if (!P.waitForStarted()) return;
if (!P.waitForFinished()) return;
}
2018-08-17 20:47:49 +03:00
Deploy::Deploy(){
}