532 lines
14 KiB
C++
Raw Normal View History

2019-09-04 21:27:29 +03:00
#include "cqt.h"
2019-09-07 12:01:20 +03:00
#include <QDebug>
#include <QDir>
#include <QFileInfo>
2019-09-07 12:36:20 +03:00
#include <QProcess>
2019-09-07 12:01:20 +03:00
#include "deploycore.h"
2019-09-08 13:37:33 +03:00
#include "filemanager.h"
2019-09-07 12:01:20 +03:00
#include "quasarapp.h"
2019-09-04 21:27:29 +03:00
2019-09-07 12:01:20 +03:00
bool CQT::parseParams() {
2019-09-10 18:22:49 +03:00
auto path = QuasarAppUtils::Params::getStrArg("confFile");
bool createFile = !path.isEmpty();
if (path.isEmpty()) {
path = QFileInfo("./").absoluteFilePath();
}
loadFromFile(path);
2019-09-07 12:01:20 +03:00
switch (DeployCore::getMode()) {
case RunMode::Info: {
qInfo() << "selected info mode" ;
if (!parseQtInfoMode()) {
qCritical() << "info mode fail!";
return false;
}
2019-09-08 13:37:33 +03:00
DeployCore::_config = &_config;
2019-09-10 18:22:49 +03:00
break;
2019-09-07 12:01:20 +03:00
}
case RunMode::Clear: {
qInfo() << "selected clear mode" ;
if (!parseQtClearMode()) {
qCritical() << "clear mode fail!";
return false;
}
2019-09-08 13:37:33 +03:00
DeployCore::_config = &_config;
2019-09-10 18:22:49 +03:00
break;
2019-09-07 12:01:20 +03:00
}
case RunMode::Deploy: {
qInfo() << "selected deploy mode" ;
if (!parseQtDeployMode()) {
qCritical() << "deploy mode fail!";
return false;
}
2019-09-08 13:37:33 +03:00
DeployCore::_config = &_config;
2019-09-10 18:22:49 +03:00
break;
}
2019-09-07 12:01:20 +03:00
}
2019-09-10 18:22:49 +03:00
if (createFile) {
createFromDeploy(path);
2019-09-07 12:01:20 +03:00
}
2019-09-10 18:22:49 +03:00
return true;
2019-09-07 12:01:20 +03:00
}
2019-09-08 13:37:33 +03:00
const DeployConfig *CQT::config() const {
return &_config;
2019-09-07 12:01:20 +03:00
}
2019-09-10 15:40:12 +03:00
void CQT::writeKey(const QString& key, QJsonObject& obj) const {
if (QuasarAppUtils::Params::isEndable(key)) {
obj[key] = QuasarAppUtils::Params::getStrArg(key);
}
}
void CQT::readKey(const QString& key, const QJsonObject& obj) const {
if (!QuasarAppUtils::Params::isEndable(key)) {
QuasarAppUtils::Params::setArg(key, obj[key].toVariant());
}
}
bool CQT::createFromDeploy(const QString& confFile) const {
QJsonObject obj;
for (auto &key :DeployCore::helpKeys()) {
writeKey(key, obj);
}
QJsonDocument doc(obj);
QFile file(confFile);
if (file.open(QIODevice::WriteOnly| QIODevice::Truncate)) {
file.write(doc.toJson());
file.close();
return true;
}
return false;
2019-09-07 12:01:20 +03:00
}
2019-09-10 15:40:12 +03:00
bool CQT::loadFromFile(const QString& confFile) {
QFile file(confFile);
if (file.open(QIODevice::ReadOnly)) {
auto doc = QJsonDocument::fromJson(file.readAll());
if (!doc.isObject()) {
return false;
}
auto obj = doc.object();
2019-09-07 12:01:20 +03:00
2019-09-10 15:40:12 +03:00
for (auto &key: obj.keys()) {
readKey(key, obj);
}
file.close();
return true;
}
return false;
2019-09-07 12:01:20 +03:00
}
bool CQT::parseQtDeployMode() {
2019-09-08 13:37:33 +03:00
auto bin = QuasarAppUtils::Params::getStrArg("bin").split(',');
if (!setTargets(bin)) {
auto binDir = QuasarAppUtils::Params::getStrArg("binDir");
if (!(setTargetsRecursive(binDir) || setTargets({"./"}))) {
qCritical() << "setTargetDir fail!";
return false;
}
}
initIgnoreEnvList();
initEnvirement();
initIgnoreList();
_config.depchLimit = 0;
if (QuasarAppUtils::Params::isEndable("recursiveDepth")) {
bool ok;
_config.depchLimit = QuasarAppUtils::Params::getArg("recursiveDepth").toInt(&ok);
if (!ok) {
_config.depchLimit = 0;
qWarning() << "recursiveDepth is invalid! use default value 0";
}
}
auto listLibDir = QuasarAppUtils::Params::getStrArg("libDir").split(",");
auto listExtraPlugin =
QuasarAppUtils::Params::getStrArg("extraPlugin").split(",");
setExtraPath(listLibDir);
setExtraPlugins(listExtraPlugin);
auto qmake = QuasarAppUtils::Params::getStrArg("qmake");
QString basePath = "";
QFileInfo info(qmake);
if (!info.isFile() || (info.baseName() != "qmake")) {
qInfo() << "deploy only C libs because qmake is not found";
return true;
}
basePath = info.absolutePath();
setQmake(qmake);
auto qmlDir = QuasarAppUtils::Params::getStrArg("qmlDir");
QDir dir(basePath);
if (QFileInfo::exists(qmlDir) ||
QuasarAppUtils::Params::isEndable("allQmlDependes")) {
_config.deployQml = true;
} else {
QuasarAppUtils::Params::verboseLog("qml dir not exits!",
QuasarAppUtils::VerboseLvl::Warning);
}
if (!dir.cdUp()) {
return false;
}
setQtDir(dir.absolutePath());
return true;
2019-09-07 12:01:20 +03:00
}
bool CQT::parseQtInfoMode() {
2019-09-08 13:37:33 +03:00
if ((QuasarAppUtils::Params::isEndable("v") ||
QuasarAppUtils::Params::isEndable("version"))) {
DeployCore::printVersion();
return true;
}
DeployCore::help();
2019-09-07 12:01:20 +03:00
2019-09-08 13:37:33 +03:00
return true;
2019-09-07 12:01:20 +03:00
}
bool CQT::parseQtClearMode() {
2019-09-07 12:36:20 +03:00
setTargetDir("./");
2019-09-08 13:37:33 +03:00
return true;
2019-09-07 12:01:20 +03:00
}
void CQT::setTargetDir(const QString &target) {
if (QuasarAppUtils::Params::isEndable("targetDir")) {
2019-09-07 12:36:20 +03:00
_config.targetDir = QFileInfo(QuasarAppUtils::Params::getStrArg("targetDir")).absoluteFilePath();
2019-09-07 12:01:20 +03:00
} else if (target.size()) {
2019-09-07 12:36:20 +03:00
_config.targetDir = QFileInfo(target).absoluteFilePath();
2019-09-07 12:01:20 +03:00
} else {
2019-09-07 12:36:20 +03:00
if (_config.targets.size())
_config.targetDir = QFileInfo(
_config.targets.begin().key()).absolutePath() + "/Distro";
2019-09-07 12:01:20 +03:00
2019-09-07 12:36:20 +03:00
_config.targetDir = QFileInfo("./Distro").absoluteFilePath();
qInfo () << "flag targetDir not used." << "use default target dir :" << _config.targetDir;
2019-09-07 12:01:20 +03:00
}
}
bool CQT::setTargets(const QStringList &value) {
bool isfillList = false;
for (auto &i : value) {
QFileInfo targetInfo(i);
if (i.isEmpty())
continue;
if (targetInfo.isFile()) {
auto sufix = targetInfo.completeSuffix();
2019-09-07 12:36:20 +03:00
_config.targets.insert(QDir::fromNativeSeparators(i), sufix.isEmpty());
2019-09-07 12:01:20 +03:00
isfillList = true;
}
else if (targetInfo.isDir()) {
if (!setBinDir(i)) {
DeployCore::verboseLog(i + " du not contains executable binaries!");
continue;
}
isfillList = true;
} else {
DeployCore::verboseLog(targetInfo.absoluteFilePath() + " not exits!");
}
}
if (!isfillList)
return false;
setTargetDir();
return true;
}
bool CQT::setTargetsRecursive(const QString &dir) {
if (!setBinDir(dir, true)) {
qWarning() << "setBinDir failed!";
return false;
}
setTargetDir();
return true;
}
bool CQT::setBinDir(const QString &dir, bool recursive) {
QDir d(dir);
if (dir.isEmpty() || !d.exists()) {
DeployCore::verboseLog(dir + " dir not exits!");
return false;
}
DeployCore::verboseLog("setBinDir check path: " + dir);
QFileInfoList list;
if (recursive) {
list = d.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
} else {
list = d.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
}
bool result = false;
for (auto &file : list) {
if (file.isDir()) {
result |= setBinDir(file.absoluteFilePath(), recursive);
continue;
}
auto sufix = file.completeSuffix();
2019-09-12 10:23:49 +03:00
if (!((!recursive) || sufix.isEmpty() || sufix.contains("dll", Qt::CaseInsensitive) ||
2019-09-07 12:01:20 +03:00
sufix.contains("so", Qt::CaseInsensitive) || sufix.contains("exe", Qt::CaseInsensitive))) {
continue;
}
result = true;
2019-09-07 12:36:20 +03:00
_config.targets.insert(QDir::fromNativeSeparators(file.absoluteFilePath()), sufix.isEmpty());
2019-09-07 12:01:20 +03:00
}
return result;
}
void CQT::initIgnoreList()
2019-09-04 21:27:29 +03:00
{
2019-09-07 12:01:20 +03:00
if (QuasarAppUtils::Params::isEndable("ignore")) {
auto list = QuasarAppUtils::Params::getStrArg("ignore").split(',');
2019-09-07 12:36:20 +03:00
_config.ignoreList.append(list);
2019-09-07 12:01:20 +03:00
}
if (QuasarAppUtils::Params::isEndable("noLibc")) {
2019-09-07 12:36:20 +03:00
_config.ignoreList.append("libc.so");
2019-09-07 12:01:20 +03:00
}
}
void CQT::initIgnoreEnvList() {
if (QuasarAppUtils::Params::isEndable("ignoreEnv")) {
auto ignoreList = QuasarAppUtils::Params::getStrArg("ignoreEnv").split(',');
2019-09-07 12:36:20 +03:00
QStringList ignoreEnvList;
2019-09-07 12:01:20 +03:00
for (auto &i : ignoreList) {
auto path = QFileInfo(i).absoluteFilePath();
if (path.right(1) == "/" || path.right(1) == "\\") {
path.remove(path.size() - 1, 1);
}
ignoreEnvList.append(path);
}
2019-09-07 12:36:20 +03:00
_config.envirement.setIgnoreEnvList(ignoreEnvList);
2019-09-07 12:01:20 +03:00
}
}
void CQT::setQmlScaner(const QString &value) {
2019-09-07 12:36:20 +03:00
_config.externQmlScaner = QDir::fromNativeSeparators(value);
QuasarAppUtils::Params::verboseLog("qmlScaner = " + _config.externQmlScaner,
2019-09-07 12:01:20 +03:00
QuasarAppUtils::VerboseLvl::Info);
2019-09-07 12:36:20 +03:00
_config.deployQml = QFileInfo(_config.externQmlScaner).isFile();
2019-09-07 12:01:20 +03:00
}
void CQT::setQmake(const QString &value) {
2019-09-07 12:36:20 +03:00
_config.qmake = QDir::fromNativeSeparators(value);
2019-09-07 12:01:20 +03:00
2019-09-07 12:36:20 +03:00
QFileInfo info(_config.qmake);
2019-09-07 12:01:20 +03:00
QDir dir = info.absoluteDir();
if (!dir.cdUp() || !dir.cd("qml")) {
QuasarAppUtils::Params::verboseLog("get qml fail!");
return;
}
2019-09-07 12:36:20 +03:00
_config.qmlDir = dir.absolutePath();
QuasarAppUtils::Params::verboseLog("qmlDir = " + _config.qmlDir);
2019-09-07 12:01:20 +03:00
dir = (info.absoluteDir());
if (!dir.cdUp() || !dir.cd("translations")) {
QuasarAppUtils::Params::verboseLog("get translations fail!");
return;
}
2019-09-07 12:36:20 +03:00
_config.translationDir = dir.absolutePath();
QuasarAppUtils::Params::verboseLog("translations = " + _config.translationDir);
2019-09-07 12:01:20 +03:00
}
void CQT::setQtDir(const QString &value) {
2019-09-07 12:36:20 +03:00
_config.qtDir = QDir::fromNativeSeparators(value);
_config.envirement.addEnv(_config.qtDir, _config.appDir, _config.targetDir);
_config.envirement.addEnv(_config.qtDir + "/lib", _config.appDir, _config.targetDir);
_config.envirement.addEnv(_config.qtDir + "/bin", _config.appDir, _config.targetDir);
2019-09-07 12:01:20 +03:00
}
void CQT::setExtraPath(const QStringList &value) {
QDir dir;
for (auto i : value) {
QFileInfo info(i);
if (info.isDir()) {
2019-09-07 12:36:20 +03:00
if (_config.targets.contains(info.absoluteFilePath())) {
2019-09-07 12:01:20 +03:00
QuasarAppUtils::Params::verboseLog("skip the extra lib path becouse it is target!");
continue;
}
dir.setPath(info.absoluteFilePath());
2019-09-07 12:36:20 +03:00
_config.extraPaths.push_back(
2019-09-07 12:01:20 +03:00
QDir::fromNativeSeparators(info.absoluteFilePath()));
2019-09-07 12:36:20 +03:00
_config.envirement.addEnv(recursiveInvairement(0, dir), _config.appDir, _config.targetDir);
2019-09-07 12:01:20 +03:00
} else {
QuasarAppUtils::Params::verboseLog(i + " does not exist! and skiped");
}
}
}
void CQT::setExtraPlugins(const QStringList &value) {
for (auto i : value) {
QFileInfo info(i);
if (info.exists()) {
2019-09-07 12:36:20 +03:00
_config.extraPlugins.append(info.absoluteFilePath());
2019-09-07 12:01:20 +03:00
} else {
QuasarAppUtils::Params::verboseLog(i + " does not exist! and skiped");
}
}
}
QString CQT::recursiveInvairement(int depch, QDir &dir) {
char separator = ':';
#ifdef Q_OS_WIN
separator = ';';
#endif
2019-09-07 12:36:20 +03:00
if (!dir.exists() || depch >= _config.depchLimit) {
2019-09-07 12:01:20 +03:00
return dir.absolutePath();
}
QFileInfoList list = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
QString res = "";
for (QFileInfo &i : list) {
dir.cd(i.fileName());
QString temp = recursiveInvairement(depch + 1, dir);
res += (res.size())? separator + temp: temp;
dir.cdUp();
}
res += (res.size())? separator + dir.absolutePath(): dir.absolutePath();
return res;
}
void CQT::initEnvirement() {
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
2019-09-07 12:36:20 +03:00
_config.envirement.addEnv(env.value("LD_LIBRARY_PATH"), _config.appDir, _config.targetDir);
_config.envirement.addEnv(env.value("PATH"), _config.appDir, _config.targetDir);
2019-09-07 12:01:20 +03:00
if (QuasarAppUtils::Params::isEndable("deploySystem")) {
QStringList dirs;
if (!QuasarAppUtils::Params::isEndable("noLibc"))
dirs.append(getDirsRecursive("/lib"));
dirs.append(getDirsRecursive("/usr/lib"));
for (auto &&i : dirs) {
2019-09-07 12:36:20 +03:00
_config.envirement.addEnv(i, _config.appDir, _config.targetDir);
2019-09-07 12:01:20 +03:00
}
}
2019-09-07 12:36:20 +03:00
if (_config.envirement.size() < 2) {
2019-09-07 12:01:20 +03:00
qWarning() << "system environment is empty";
}
}
QStringList CQT::getDirsRecursive(const QString &path) {
QDir dir(path);
QStringList res;
auto list = dir.entryInfoList(QDir::Dirs| QDir::NoDotAndDotDot);
for (auto &&subDir: list) {
res.push_back(subDir.absoluteFilePath());
res.append(getDirsRecursive(subDir.absoluteFilePath()));
}
return res;
}
2019-09-08 13:37:33 +03:00
bool CQT::smartMoveTargets() {
QMap<QString, bool> temp;
bool result = true;
for (auto i = _config.targets.cbegin(); i != _config.targets.cend(); ++i) {
QFileInfo target(i.key());
auto targetPath = _config.targetDir + (DeployCore::isLib(target) ? "/lib" : "/bin");
if (target.completeSuffix().contains("dll", Qt::CaseInsensitive) ||
target.completeSuffix().contains("exe", Qt::CaseInsensitive)) {
targetPath = _config.targetDir;
}
if (!_fileManager->smartCopyFile(target.absoluteFilePath(), targetPath, _config.targetDir)) {
result = false;
}
temp.insert(targetPath + "/" + target.fileName(), i.value());
}
_config.targets = temp;
return result;
}
CQT::CQT(FileManager *filemanager):
_fileManager(filemanager) {
assert(_fileManager);
2019-09-07 12:01:20 +03:00
2019-09-08 13:37:33 +03:00
#ifdef Q_OS_LINUX
_config.appDir = QuasarAppUtils::Params::getStrArg("appPath");
if (_config.appDir.right(4) == "/bin") {
_config.appDir = _config.appDir.left(_config.appDir.size() - 4);
}
#else
_config.appDir = QuasarAppUtils::Params::getStrArg("appPath");
#endif
2019-09-04 21:27:29 +03:00
2019-09-08 13:37:33 +03:00
QuasarAppUtils::Params::verboseLog("appDir = " + _config.appDir);
2019-09-04 21:27:29 +03:00
}