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