From bf9aa944008a1527c71e166188b2dc4144c1b4e6 Mon Sep 17 00:00:00 2001
From: EndrII <endriimail@gmail.com>
Date: Sun, 15 Sep 2019 17:38:47 +0300
Subject: [PATCH] fix out features

---
 Deploy/Deploy.pro          |   2 +
 Deploy/configparser.cpp    |  19 ++---
 Deploy/configparser.h      |   6 +-
 Deploy/distrostruct.cpp    |  40 +++++----
 Deploy/distrostruct.h      |  16 ++--
 Deploy/extracter.cpp       | 131 ++++-------------------------
 Deploy/extracter.h         |  12 +--
 Deploy/metafilemanager.cpp | 163 +++++++++++++++++++++++++++++++++++++
 Deploy/metafilemanager.h   |  27 ++++++
 9 files changed, 255 insertions(+), 161 deletions(-)
 create mode 100644 Deploy/metafilemanager.cpp
 create mode 100644 Deploy/metafilemanager.h

diff --git a/Deploy/Deploy.pro b/Deploy/Deploy.pro
index 12a828a..c031044 100644
--- a/Deploy/Deploy.pro
+++ b/Deploy/Deploy.pro
@@ -52,6 +52,7 @@ SOURCES += \
     envirement.cpp \
     extracter.cpp \
     filemanager.cpp \
+    metafilemanager.cpp \
     pe.cpp \
     igetlibinfo.cpp \
     dependenciesscanner.cpp \
@@ -70,6 +71,7 @@ HEADERS += \
     envirement.h \
     extracter.h \
     filemanager.h \
+    metafilemanager.h \
     pe.h \
     igetlibinfo.h \
     dependenciesscanner.h \
diff --git a/Deploy/configparser.cpp b/Deploy/configparser.cpp
index 1630188..48e55bc 100644
--- a/Deploy/configparser.cpp
+++ b/Deploy/configparser.cpp
@@ -183,6 +183,8 @@ bool ConfigParser::parseQtDeployMode() {
     initEnvirement();
     initIgnoreList();
 
+    _config.distroStruct.init();
+
     _config.depchLimit = 0;
 
     if (QuasarAppUtils::Params::isEndable("recursiveDepth")) {
@@ -388,13 +390,6 @@ void ConfigParser::initIgnoreEnvList() {
     }
 }
 
-void ConfigParser::setQmlScaner(const QString &value) {
-    _config.externQmlScaner = QDir::fromNativeSeparators(value);
-    QuasarAppUtils::Params::verboseLog("qmlScaner = " + _config.externQmlScaner,
-                                       QuasarAppUtils::VerboseLvl::Info);
-    _config.deployQml = QFileInfo(_config.externQmlScaner).isFile();
-}
-
 void ConfigParser::setQmake(const QString &value) {
     _config.qmake = QDir::fromNativeSeparators(value);
 
@@ -533,13 +528,13 @@ bool ConfigParser::smartMoveTargets() {
     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().compare("dll", Qt::CaseInsensitive) == 0 ||
-                target.completeSuffix().compare("exe", Qt::CaseInsensitive) == 0) {
-
-            targetPath = _config.targetDir;
+        QString targetPath = _config.targetDir;
 
+        if (DeployCore::isLib(target)) {
+            targetPath += _config.distroStruct.getLibOutDir();
+        } else {
+            targetPath += _config.distroStruct.getBinOutDir();
         }
 
         if (!_fileManager->smartCopyFile(target.absoluteFilePath(), targetPath, _config.targetDir)) {
diff --git a/Deploy/configparser.h b/Deploy/configparser.h
index ef65ddc..1238069 100644
--- a/Deploy/configparser.h
+++ b/Deploy/configparser.h
@@ -1,5 +1,6 @@
 #ifndef CQT_H
 #define CQT_H
+#include "distrostruct.h"
 #include "envirement.h"
 
 #include <QJsonObject>
@@ -16,8 +17,6 @@ struct DEPLOYSHARED_EXPORT DeployConfig {
     QString qmake = "";
     QString targetDir = "";
     QString qmlDir = "";
-    QString translationDir = "";
-    QString externQmlScaner = "";
     int depchLimit = 0;
     bool deployQml = false;
     QStringList ignoreList;
@@ -32,6 +31,8 @@ struct DEPLOYSHARED_EXPORT DeployConfig {
      */
     QMap<QString, bool> targets;
     Envirement envirement;
+    DistroStruct distroStruct;
+    QString translationDir;
 
 };
 
@@ -56,7 +57,6 @@ private:
     void initIgnoreList();
     void initIgnoreEnvList();
 
-    void setQmlScaner(const QString &value);
     void setQmake(const QString &value);
     void setQtDir(const QString &value);
 
diff --git a/Deploy/distrostruct.cpp b/Deploy/distrostruct.cpp
index 166dfd2..4ff6652 100644
--- a/Deploy/distrostruct.cpp
+++ b/Deploy/distrostruct.cpp
@@ -1,5 +1,3 @@
-#include "distrostruct.h"
-#include <quasarapp.h>
 
 //#
 //# Copyright (C) 2018-2019 QuasarApp.
@@ -8,6 +6,9 @@
 //# of this license document, but changing it is not allowed.
 //#
 
+#include "distrostruct.h"
+#include <quasarapp.h>
+
 QString DistroStruct::getLibOutDir(const QString &basePath) const {
     return getRelativePath(basePath) + libOutDir;
 }
@@ -60,6 +61,26 @@ QString DistroStruct::getRootDir(const QString &basePath) const {
     return getRelativePath(basePath);
 }
 
+void DistroStruct::init() {
+
+#ifdef Q_OS_LINUX
+
+    setBinOutDir(QuasarAppUtils::Params::getStrArg("binOut", "/bin"));
+    setLibOutDir(QuasarAppUtils::Params::getStrArg("libOut", "/lib"));
+
+#else
+    setBinOutDir(QuasarAppUtils::Params::getStrArg("binOut", "/"));
+    setLibOutDir(QuasarAppUtils::Params::getStrArg("libOut", "/"));
+#endif
+
+
+    setQmlOutDir(QuasarAppUtils::Params::getStrArg("qmlOut", "/qml"));
+    setTrOutDir(QuasarAppUtils::Params::getStrArg("trOut", "/translations"));
+    setPluginsOutDir(QuasarAppUtils::Params::getStrArg("pluginOut", "/plugins"));
+    setResOutDir("/resources");
+
+}
+
 QString DistroStruct::toFullPath(QString path) const {
     path.replace('\\', '/');
 
@@ -118,20 +139,5 @@ QString DistroStruct::getRelativePath(QString path) const {
 
 DistroStruct::DistroStruct() {
 
-#ifdef Q_OS_LINUX
-
-    setBinOutDir(QuasarAppUtils::Params::getStrArg("binOut", "/bin"));
-    setLibOutDir(QuasarAppUtils::Params::getStrArg("libOut", "/lib"));
-
-#else
-    setBinOutDir(QuasarAppUtils::Params::getStrArg("binOut", "/"));
-    setLibOutDir(QuasarAppUtils::Params::getStrArg("libOut", "/"));
-#endif
-
-
-    setQmlOutDir(QuasarAppUtils::Params::getStrArg("qmlOut", "/qml"));
-    setTrOutDir(QuasarAppUtils::Params::getStrArg("trOut", "/translations"));
-    setPluginsOutDir(QuasarAppUtils::Params::getStrArg("pluginOut", "/plugins"));
-    setResOutDir("/resources");
 
 }
diff --git a/Deploy/distrostruct.h b/Deploy/distrostruct.h
index 40ecfdf..484d3fc 100644
--- a/Deploy/distrostruct.h
+++ b/Deploy/distrostruct.h
@@ -29,22 +29,26 @@ private:
     QString stripPath(QString path) const;
     QString getRelativePath(QString path) const;
 
+    void setBinOutDir(const QString &value);
+    void setLibOutDir(const QString &value);
+    void setQmlOutDir(const QString &value);
+    void setTrOutDir(const QString &value);
+    void setResOutDir(const QString &value);
+    void setPluginsOutDir(const QString &value);
+
+
 public:
     DistroStruct();
     QString getLibOutDir(const QString& basePath = "/") const;
-    void setLibOutDir(const QString &value);
     QString getBinOutDir(const QString& basePath = "/") const;
-    void setBinOutDir(const QString &value);
     QString getQmlOutDir(const QString& basePath = "/") const;
-    void setQmlOutDir(const QString &value);
     QString getTrOutDir(const QString& basePath = "/") const;
-    void setTrOutDir(const QString &value);
     QString getResOutDir(const QString& basePath = "/") const;
-    void setResOutDir(const QString &value);
     QString getPluginsOutDir(const QString& basePath = "/") const;
-    void setPluginsOutDir(const QString &value);
     QString getRootDir(const QString& basePath = "/") const;
 
+    void init();
+
     friend class deploytest;
 };
 
diff --git a/Deploy/extracter.cpp b/Deploy/extracter.cpp
index b744aaa..33ee761 100644
--- a/Deploy/extracter.cpp
+++ b/Deploy/extracter.cpp
@@ -9,6 +9,7 @@
 #include "deploycore.h"
 #include "pluginsparser.h"
 #include "configparser.h"
+#include "metafilemanager.h"
 #include <QCoreApplication>
 #include <QDebug>
 #include <QDir>
@@ -38,8 +39,12 @@ bool Extracter::copyPlugin(const QString &plugin) {
 
     QStringList listItems;
 
-    if (!_fileManager->copyFolder(plugin, DeployCore::_config->targetDir + "/plugins/" + QFileInfo(plugin).fileName(),
-                                 QStringList() << ".so.debug" << "d.dll", &listItems)) {
+    auto pluginPath = DeployCore::_config->targetDir +
+            DeployCore::_config->distroStruct.getPluginsOutDir() +
+            QFileInfo(plugin).fileName();
+
+    if (!_fileManager->copyFolder(plugin, pluginPath,
+                    QStringList() << ".so.debug" << "d.dll", &listItems)) {
         return false;
     }
 
@@ -62,12 +67,11 @@ void Extracter::copyExtraPlugins() {
         info.setFile(extraPlugin);
         if (info.isDir() && info.absoluteFilePath().contains(DeployCore::_config->qtDir)) {
 
-            _fileManager->copyFolder(info.absoluteFilePath(),
-                                    DeployCore::_config->targetDir + "/plugins/" + info.baseName(),
-                                    QStringList() << ".so.debug" << "d.dll");
+            copyPlugin(info.baseName());
+
         } else if (info.exists()) {
             _fileManager->copyFile(info.absoluteFilePath(),
-                                  DeployCore::_config->targetDir + QDir::separator() + "plugins");
+                                  DeployCore::_config->targetDir + DeployCore::_config->distroStruct.getPluginsOutDir());
             extract(info.absoluteFilePath());
         }
     }
@@ -82,89 +86,6 @@ void Extracter::copyPlugins(const QStringList &list) {
     copyExtraPlugins();
 }
 
-bool Extracter::createRunScript(const QString &target) {
-
-    QString content =
-            "#!/bin/sh\n"
-            "BASE_DIR=$(dirname \"$(readlink -f \"$0\")\")\n"
-            "export "
-            "LD_LIBRARY_PATH=\"$BASE_DIR\"/lib:\"$BASE_DIR\":$LD_LIBRARY_PATH\n"
-            "export QML_IMPORT_PATH=\"$BASE_DIR\"/qml:QML_IMPORT_PATH\n"
-            "export QML2_IMPORT_PATH=\"$BASE_DIR\"/qml:QML2_IMPORT_PATH\n"
-            "export QT_PLUGIN_PATH=\"$BASE_DIR\"/plugins:QT_PLUGIN_PATH\n"
-            "export QTDIR=\"$BASE_DIR\"\n"
-            "export "
-            "QT_QPA_PLATFORM_PLUGIN_PATH=\"$BASE_DIR\"/plugins/"
-            "platforms:QT_QPA_PLATFORM_PLUGIN_PATH\n"
-            "%2"
-            "\"$BASE_DIR\"/bin/%1 \"$@\"";
-
-    content = content.arg(QFileInfo(target).fileName());
-    int ld_index = DeployCore::find("ld-linux", _fileManager->getDeployedFilesStringList());
-
-    if (ld_index >= 0 && QuasarAppUtils::Params::isEndable("deploySystem") &&
-            !QuasarAppUtils::Params::isEndable("noLibc")) {
-
-        content = content.arg(QString("\nexport LD_PRELOAD=\"$BASE_DIR\"/lib/%0\n").
-            arg(QFileInfo(_fileManager->getDeployedFilesStringList()[ld_index]).fileName()));
-    } else {
-        content = content.arg("");
-    }
-
-
-    QString fname = DeployCore::_config->targetDir + QDir::separator() + QFileInfo(target).baseName()+ ".sh";
-
-    QFile F(fname);
-    if (!F.open(QIODevice::WriteOnly)) {
-        return false;
-    }
-
-    F.write(content.toUtf8());
-    F.flush();
-    F.close();
-
-    _fileManager->addToDeployed(fname);
-
-    return F.setPermissions(QFileDevice::ExeOther | QFileDevice::WriteOther |
-                            QFileDevice::ReadOther | QFileDevice::ExeUser |
-                            QFileDevice::WriteUser | QFileDevice::ReadUser |
-                            QFileDevice::ExeOwner | QFileDevice::WriteOwner |
-                            QFileDevice::ReadOwner);
-}
-
-bool Extracter::createQConf() {
-
-    QString content =
-            "[Paths]\n"
-            "Prefix= ./\n"
-            "Libraries= ./\n"
-            "Plugins= ./plugins\n"
-            "Imports= ./qml\n"
-            "Qml2Imports= ./qml\n";
-
-
-    QString fname = DeployCore::_config->targetDir + QDir::separator() + "qt.conf";
-
-    QFile F(fname);
-    if (!F.open(QIODevice::WriteOnly)) {
-        return false;
-    }
-
-    F.write(content.toUtf8());
-    F.flush();
-    F.close();
-
-    _fileManager->addToDeployed(fname);
-
-    return F.setPermissions(QFileDevice::ExeOther | QFileDevice::WriteOther |
-                            QFileDevice::ReadOther | QFileDevice::ExeUser |
-                            QFileDevice::WriteUser | QFileDevice::ReadUser |
-                            QFileDevice::ExeOwner | QFileDevice::WriteOwner |
-                            QFileDevice::ReadOwner);
-}
-
-
-
 void Extracter::extractAllTargets() {
     for (auto i = DeployCore::_config->targets.cbegin(); i != DeployCore::_config->targets.cend(); ++i) {
         extract(i.key());
@@ -218,26 +139,6 @@ void Extracter::copyTr()
     }
 }
 
-void Extracter::createRunMetaFiles()
-{
-    bool targetWindows = false;
-
-    for (auto i = DeployCore::_config->targets.cbegin(); i != DeployCore::_config->targets.cend(); ++i) {
-
-        if (QFileInfo(i.key()).completeSuffix().compare("exe", Qt::CaseInsensitive) == 0) {
-            targetWindows = true;
-        }
-
-        if (i.value() && !createRunScript(i.key())) {
-            qCritical() << "run script not created!";
-        }
-    }
-
-    if (targetWindows && !createQConf()) {
-        QuasarAppUtils::Params::verboseLog("create qt.conf failr", QuasarAppUtils::Warning);
-    }
-}
-
 void Extracter::deploy() {
     qInfo() << "target deploy started!!";
 
@@ -262,7 +163,7 @@ void Extracter::deploy() {
         QuasarAppUtils::Params::verboseLog("deploy msvc failed");
     }
 
-    createRunMetaFiles();
+    _metaFileManager->createRunMetaFiles();
 
     _fileManager->saveDeploymendFiles(DeployCore::_config->targetDir);
 
@@ -285,7 +186,7 @@ bool Extracter::copyTranslations(QStringList list) {
     auto listItems = dir.entryInfoList(filters, QDir::Files | QDir::NoDotAndDotDot);
 
     for (auto &&i: listItems) {
-        _fileManager->copyFile(i.absoluteFilePath(), DeployCore::_config->targetDir + "/translations");
+        _fileManager->copyFile(i.absoluteFilePath(), DeployCore::_config->targetDir + DeployCore::_config->distroStruct.getTrOutDir());
     }
 
     return true;
@@ -363,7 +264,8 @@ bool Extracter::extractQmlAll() {
 
     QStringList listItems;
 
-    if (!_fileManager->copyFolder(DeployCore::_config->qmlDir, DeployCore::_config->targetDir + "/qml",
+    if (!_fileManager->copyFolder(DeployCore::_config->qmlDir,
+                                 DeployCore::_config->targetDir + DeployCore::_config->distroStruct.getQmlOutDir(),
                     QStringList() << ".so.debug" << "d.dll",
                     &listItems)) {
         return false;
@@ -404,7 +306,8 @@ bool Extracter::extractQmlFromSource(const QString& sourceDir) {
         return false;
     }
 
-    if (!_fileManager->copyFolder(DeployCore::_config->qmlDir, DeployCore::_config->targetDir + "/qml",
+    if (!_fileManager->copyFolder(DeployCore::_config->qmlDir,
+                                 DeployCore::_config->targetDir + DeployCore::_config->distroStruct.getQmlOutDir(),
                     filter , &listItems, &plugins)) {
         return false;
     }
@@ -455,5 +358,7 @@ Extracter::Extracter(FileManager *fileManager, ConfigParser *cqt):
     assert(_cqt);
     assert(_fileManager);
     assert(DeployCore::_config);
+
+    _metaFileManager = new MetaFileManager(_fileManager);
 }
 
diff --git a/Deploy/extracter.h b/Deploy/extracter.h
index 18ea740..1f833ef 100644
--- a/Deploy/extracter.h
+++ b/Deploy/extracter.h
@@ -16,6 +16,7 @@
 #include "qml.h"
 
 class ConfigParser;
+class MetaFileManager;
 
 class DEPLOYSHARED_EXPORT Extracter {
   private:
@@ -27,11 +28,11 @@ class DEPLOYSHARED_EXPORT Extracter {
     DependenciesScanner scaner;
     FileManager *_fileManager;
     ConfigParser *_cqt;
+    MetaFileManager *_metaFileManager;
 
     void extract(const QString &file);
     bool copyTranslations(QStringList list);
 
-    bool createQConf();
     bool extractQml();
 
     QFileInfoList findFilesInsideDir(const QString &name, const QString &dirpath);
@@ -48,23 +49,14 @@ class DEPLOYSHARED_EXPORT Extracter {
 
 
     void extractAllTargets();
-
     void initQtModules();
     void clear();
-
     void extractPlugins();
-
     void copyFiles();
-
     void copyTr();
-
-    void createRunMetaFiles();
-
     void copyExtraPlugins();
-
 public:
     explicit Extracter(FileManager *fileManager, ConfigParser * cqt);
-    bool createRunScript(const QString &target);
     void deploy();
 
     friend class deploytest;
diff --git a/Deploy/metafilemanager.cpp b/Deploy/metafilemanager.cpp
new file mode 100644
index 0000000..0a5917a
--- /dev/null
+++ b/Deploy/metafilemanager.cpp
@@ -0,0 +1,163 @@
+#include "deploycore.h"
+#include "metafilemanager.h"
+
+#include <quasarapp.h>
+#include <QDir>
+#include <configparser.h>
+#include "filemanager.h"
+
+
+bool MetaFileManager::createRunScriptWindows(const QString &target) {
+
+    if (DeployCore::_config->distroStruct.getBinOutDir() ==
+            DeployCore::_config->distroStruct.getLibOutDir() ) {
+        return true;
+    }
+
+    QString content =
+            "@echo off \n"
+            "SET BASE_DIR=%~dp0\n"
+            "SET PATH=%BASE_DIR%" + DeployCore::_config->distroStruct.getLibOutDir() + ";%PATH%\n"
+            "start \"\" \"%BASE_DIR%" + DeployCore::_config->distroStruct.getBinOutDir() + "%0\" %1 \n";
+
+    content = content.arg(QFileInfo(target).fileName()).arg("%*");
+    content = QDir::toNativeSeparators(content);
+
+    QString fname = DeployCore::_config->targetDir + QDir::separator() + QFileInfo(target).baseName()+ ".bat";
+
+    QFile F(fname);
+    if (!F.open(QIODevice::WriteOnly)) {
+        return false;
+    }
+
+    F.write(content.toUtf8());
+    F.flush();
+    F.close();
+
+    _fileManager->addToDeployed(fname);
+
+    return F.setPermissions(QFileDevice::ExeOther | QFileDevice::WriteOther |
+                            QFileDevice::ReadOther | QFileDevice::ExeUser |
+                            QFileDevice::WriteUser | QFileDevice::ReadUser |
+                            QFileDevice::ExeOwner | QFileDevice::WriteOwner |
+                            QFileDevice::ReadOwner);
+}
+
+bool MetaFileManager::createRunScriptLinux(const QString &target) {
+    QString content =
+            "#!/bin/sh\n"
+            "BASE_DIR=$(dirname \"$(readlink -f \"$0\")\")\n"
+            "export "
+            "LD_LIBRARY_PATH=\"$BASE_DIR\"" + DeployCore::_config->distroStruct.getLibOutDir() + ":\"$BASE_DIR\":$LD_LIBRARY_PATH\n"
+            "export QML_IMPORT_PATH=\"$BASE_DIR\"" + DeployCore::_config->distroStruct.getQmlOutDir() + ":QML_IMPORT_PATH\n"
+            "export QML2_IMPORT_PATH=\"$BASE_DIR\"" + DeployCore::_config->distroStruct.getQmlOutDir() + ":QML2_IMPORT_PATH\n"
+            "export QT_PLUGIN_PATH=\"$BASE_DIR\"" + DeployCore::_config->distroStruct.getPluginsOutDir() + ":QT_PLUGIN_PATH\n"
+            "export QTDIR=\"$BASE_DIR\"\n"
+            "export "
+            "QT_QPA_PLATFORM_PLUGIN_PATH=\"$BASE_DIR\"" + DeployCore::_config->distroStruct.getPluginsOutDir() +
+            "/platforms:QT_QPA_PLATFORM_PLUGIN_PATH\n"
+            "%2"
+            "\"$BASE_DIR\"" + DeployCore::_config->distroStruct.getBinOutDir() + "%1 \"$@\"";
+
+    content = content.arg(QFileInfo(target).fileName());
+    int ld_index = DeployCore::find("ld-linux", _fileManager->getDeployedFilesStringList());
+
+    if (ld_index >= 0 && QuasarAppUtils::Params::isEndable("deploySystem") &&
+            !QuasarAppUtils::Params::isEndable("noLibc")) {
+
+        content = content.arg(QString("\nexport LD_PRELOAD=\"$BASE_DIR\"" + DeployCore::_config->distroStruct.getLibOutDir() + "%0\n").
+            arg(QFileInfo(_fileManager->getDeployedFilesStringList()[ld_index]).fileName()));
+    } else {
+        content = content.arg("");
+    }
+
+    QString fname = DeployCore::_config->targetDir + QDir::separator() + QFileInfo(target).baseName()+ ".sh";
+
+    QFile F(fname);
+    if (!F.open(QIODevice::WriteOnly)) {
+        return false;
+    }
+
+    F.write(content.toUtf8());
+    F.flush();
+    F.close();
+
+    _fileManager->addToDeployed(fname);
+
+    return F.setPermissions(QFileDevice::ExeOther | QFileDevice::WriteOther |
+                            QFileDevice::ReadOther | QFileDevice::ExeUser |
+                            QFileDevice::WriteUser | QFileDevice::ReadUser |
+                            QFileDevice::ExeOwner | QFileDevice::WriteOwner |
+                            QFileDevice::ReadOwner);
+}
+
+MetaFileManager::MetaFileManager(FileManager *manager):
+    _fileManager(manager)
+{
+    assert(_fileManager);
+}
+
+bool MetaFileManager::createRunScript(const QString &target) {
+
+    QFileInfo info(target);
+    auto sufix = info.completeSuffix();
+
+    if (sufix.contains("exe", Qt::CaseSensitive)) {
+        return createRunScriptWindows(target);
+    }
+
+    return createRunScriptLinux(target);
+}
+
+bool MetaFileManager::createQConf() {
+
+    QString content =
+            "[Paths]\n"
+            "Prefix= ./\n"
+            "Libraries= ." + DeployCore::_config->distroStruct.getLibOutDir(DeployCore::_config->distroStruct.getBinOutDir()) + "\n"
+            "Plugins= ." + DeployCore::_config->distroStruct.getPluginsOutDir(DeployCore::_config->distroStruct.getBinOutDir()) + "\n"
+            "Imports= ." + DeployCore::_config->distroStruct.getQmlOutDir(DeployCore::_config->distroStruct.getBinOutDir()) + "\n"
+            "Qml2Imports= ." + DeployCore::_config->distroStruct.getQmlOutDir(DeployCore::_config->distroStruct.getBinOutDir()) + "\n";
+
+
+    content.replace("//", "/");
+    content = QDir::fromNativeSeparators(content);
+
+    QString fname = DeployCore::_config->targetDir + DeployCore::_config->distroStruct.getBinOutDir() + "qt.conf";
+
+    QFile F(fname);
+    if (!F.open(QIODevice::WriteOnly)) {
+        return false;
+    }
+
+    F.write(content.toUtf8());
+    F.flush();
+    F.close();
+
+    _fileManager->addToDeployed(fname);
+
+    return F.setPermissions(QFileDevice::ExeOther | QFileDevice::WriteOther |
+                            QFileDevice::ReadOther | QFileDevice::ExeUser |
+                            QFileDevice::WriteUser | QFileDevice::ReadUser |
+                            QFileDevice::ExeOwner | QFileDevice::WriteOwner |
+                            QFileDevice::ReadOwner);
+}
+
+void MetaFileManager::createRunMetaFiles() {
+    bool targetWindows = false;
+
+    for (auto i = DeployCore::_config->targets.cbegin(); i != DeployCore::_config->targets.cend(); ++i) {
+
+        if (QFileInfo(i.key()).completeSuffix().compare("exe", Qt::CaseInsensitive) == 0) {
+            targetWindows = true;
+        }
+
+        if (i.value() && !createRunScript(i.key())) {
+            qCritical() << "run script not created!";
+        }
+    }
+
+    if (targetWindows && !createQConf()) {
+        QuasarAppUtils::Params::verboseLog("create qt.conf failr", QuasarAppUtils::Warning);
+    }
+}
diff --git a/Deploy/metafilemanager.h b/Deploy/metafilemanager.h
new file mode 100644
index 0000000..ce345f4
--- /dev/null
+++ b/Deploy/metafilemanager.h
@@ -0,0 +1,27 @@
+#ifndef METAFILEMANAGER_H
+#define METAFILEMANAGER_H
+
+#include <QString>
+
+class FileManager;
+
+class MetaFileManager
+{
+
+private:
+    bool createRunScriptWindows(const QString &target);
+    bool createRunScriptLinux(const QString &target);
+
+
+    bool createRunScript(const QString &target);
+    bool createQConf();
+
+    FileManager* _fileManager = nullptr;
+
+public:
+    MetaFileManager(FileManager* manager);
+
+    void createRunMetaFiles();
+};
+
+#endif // METAFILEMANAGER_H