diff options
Diffstat (limited to 'qmake/generators/metamakefile.cpp')
-rw-r--r-- | qmake/generators/metamakefile.cpp | 284 |
1 files changed, 279 insertions, 5 deletions
diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp index 34d3698..4a9fd8d 100644 --- a/qmake/generators/metamakefile.cpp +++ b/qmake/generators/metamakefile.cpp @@ -263,8 +263,9 @@ MakefileGenerator class SubdirsMetaMakefileGenerator : public MetaMakefileGenerator { +protected: + bool init_flag; -private: struct Subdir { Subdir() : makefile(0), indent(0) { } ~Subdir() { delete makefile; } @@ -375,6 +376,7 @@ SubdirsMetaMakefileGenerator::init() self->makefile = new BuildsMetaMakefileGenerator(project, name, false); self->makefile->init(); subs.append(self); + return true; } @@ -418,6 +420,269 @@ SubdirsMetaMakefileGenerator::~SubdirsMetaMakefileGenerator() subs.clear(); } +class SymbianSubdirsMetaMakefileGenerator : public SubdirsMetaMakefileGenerator +{ +public: + SymbianSubdirsMetaMakefileGenerator(QMakeProject *p, const QString &n, bool op) : SubdirsMetaMakefileGenerator(p, n, op) { } + virtual ~SymbianSubdirsMetaMakefileGenerator(); + + virtual bool init(); + virtual bool write(const QString &); + +protected: + + static QMap<QString, QString> mmpPaths; + + static QMultiMap<QString, QString> mmpDependency; + + static QStringList getDependencyList(QString mmpFilename, int recursionDepth); + + static QStringList calculateRelativePaths(QString mmpParent, QStringList mmpChildren); + +private: + QString cleanFromSpecialCharacters(QString& str); +}; + +QMap<QString, QString> SymbianSubdirsMetaMakefileGenerator::mmpPaths; + +QMultiMap<QString, QString> SymbianSubdirsMetaMakefileGenerator::mmpDependency; + +QStringList SymbianSubdirsMetaMakefileGenerator::getDependencyList(QString mmpFilename, int recursionDepth) +{ + QStringList list; + + QList<QString> values = mmpDependency.values(mmpFilename); + if (recursionDepth < 0) { + // special case; just first dependency level + list = values; + return list; + } + if (values.size() == 0) { + //reached recursion END condition + if (recursionDepth == 0) { + --recursionDepth; + return list; // empty list // no dependencies / return + } else { + list.append(mmpFilename); + recursionDepth--; + return list; // leaf // return + } + } else { + recursionDepth++; + for (int i = 0; i < values.size(); ++i) { + QString current = values.at(i); + QStringList tailList = getDependencyList(current, recursionDepth); + for (int j = 0; j < tailList.size(); ++j) { + QString path = tailList.at(j); + list.append(path); + } + } + + if (recursionDepth > 0) { + //for mmp somewhere in middle + list.append(mmpFilename); + } + recursionDepth--; + return list; + } +} + +SymbianSubdirsMetaMakefileGenerator::~SymbianSubdirsMetaMakefileGenerator() { } + +bool SymbianSubdirsMetaMakefileGenerator::write(const QString &oldpwd) +{ + return SubdirsMetaMakefileGenerator::write(oldpwd); +} + +QString SymbianSubdirsMetaMakefileGenerator::cleanFromSpecialCharacters(QString& str) +{ + QString tmp = str; + + tmp.replace(QString("/"), QString("_")); + tmp.replace(QString("\\"), QString("_")); + tmp.replace(QString("-"), QString("_")); + tmp.replace(QString(":"), QString("_")); + tmp.replace(QString("."), QString("_")); + + return tmp; +} + +bool SymbianSubdirsMetaMakefileGenerator::init() +{ + if (init_flag) + return false; + + init_flag = true; + + // If we are here then we have template == subdirs + + Option::recursive = true; + + if (Option::recursive) { + QString old_output_dir = QDir::cleanPath(Option::output_dir); + if (!old_output_dir.endsWith('/')) + old_output_dir += '/'; + QString old_output = Option::output.fileName(); + QString oldpwd = QDir::cleanPath(qmake_getpwd()); + + if (!oldpwd.endsWith('/')) + oldpwd += '/'; + + // find the parent mmp filename + int end = oldpwd.size() - 1; + int start = oldpwd.lastIndexOf("/", end - 2); + QString parentMmpFilename = oldpwd.mid(start + 1, end - start - 1); + parentMmpFilename.prepend(oldpwd); + parentMmpFilename = parentMmpFilename.append(Option::mmp_ext); + + + const QStringList &subdirs = project->values("SUBDIRS"); + static int recurseDepth = -1; + ++recurseDepth; + for (int i = 0; i < subdirs.size(); ++i) { + Subdir *sub = new Subdir; + sub->indent = recurseDepth; + + QFileInfo subdir(subdirs.at(i)); + // childMmpFielname should be derived from subdirName + QString subdirName = subdirs.at(i); + if (!project->isEmpty(subdirs.at(i) + ".file")) + subdir = project->first(subdirs.at(i) + ".file"); + else if (!project->isEmpty(subdirs.at(i) + ".subdir")) + subdir = project->first(subdirs.at(i) + ".subdir"); + QString sub_name; + + QString childMmpFilename; + + if (subdir.isDir()) { + subdir = QFileInfo(subdir.filePath() + "/" + subdir.fileName() + Option::pro_ext); + childMmpFilename = subdir.fileName(); + childMmpFilename = subdir.absoluteFilePath(); + childMmpFilename.replace(Option::pro_ext, QString("")); + childMmpFilename.append(Option::mmp_ext); + } else { + childMmpFilename = subdir.absoluteFilePath(); + childMmpFilename.replace(Option::pro_ext, Option::mmp_ext); + sub_name = childMmpFilename; + sub_name.replace(Option::mmp_ext, QString("")); + sub_name.replace(0, sub_name.lastIndexOf("/") + 1, QString("")); + project->values("SHADOW_BLD_INFS").append(QString("bld.inf.") + sub_name); + } + + //handle sub project + QMakeProject *sub_proj = new QMakeProject(project->properties()); + for (int ind = 0; ind < sub->indent; ++ind) + printf(" "); + sub->input_dir = subdir.absolutePath(); + if (subdir.isRelative() && old_output_dir != oldpwd) { + sub->output_dir = old_output_dir + "/" + subdir.path(); + printf("Reading %s [%s]\n", subdir.absoluteFilePath().toLatin1().constData(), sub->output_dir.toLatin1().constData()); + } else { + sub->output_dir = sub->input_dir; + printf("Reading %s\n", subdir.absoluteFilePath().toLatin1().constData()); + } + + // find the child mmp filename + qmake_setpwd(sub->input_dir); + + QString newpwd = qmake_getpwd(); + + Option::output_dir = sub->output_dir; + if (Option::output_dir.at(Option::output_dir.length() - 1) != QLatin1Char('/')) + Option::output_dir += QLatin1Char('/'); + sub_proj->read(subdir.fileName()); + if (!sub_proj->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { + fprintf(stderr, "Project file(%s) not recursed because all requirements not met:\n\t%s\n", + subdir.fileName().toLatin1().constData(), + sub_proj->values("QMAKE_FAILED_REQUIREMENTS").join(" ").toLatin1().constData()); + delete sub; + delete sub_proj; + //continue; + } else { + // map mmpfile to its absolut filepath + mmpPaths.insert(childMmpFilename, newpwd); + + // update mmp files dependency map + mmpDependency.insert(parentMmpFilename, childMmpFilename); + + sub->makefile = MetaMakefileGenerator::createMetaGenerator(sub_proj, sub_name); + if (0 && sub->makefile->type() == SUBDIRSMETATYPE) { + subs.append(sub); + } else { + const QString output_name = Option::output.fileName(); + Option::output.setFileName(sub->output_file); + sub->makefile->write(sub->output_dir); + delete sub; + qmakeClearCaches(); + sub = 0; + Option::output.setFileName(output_name); + } + } + + Option::output_dir = old_output_dir; + qmake_setpwd(oldpwd); + + } + --recurseDepth; + Option::output.setFileName(old_output); + Option::output_dir = old_output_dir; + qmake_setpwd(oldpwd); + } + + Subdir *self = new Subdir; + self->input_dir = qmake_getpwd(); + + // To fully expand find all dependencies: + // Do as recursion, then insert result as subdirs data in project + QString newpwd = qmake_getpwd(); + if (!newpwd.endsWith('/')) + newpwd += '/'; + int end = newpwd.size() - 1; + int start = newpwd.lastIndexOf("/", end - 2); + QString mmpFilename = newpwd.mid(start + 1, end - start - 1); + mmpFilename.prepend(newpwd); + mmpFilename = mmpFilename.append(Option::mmp_ext); + + // map mmpfile to its absolute filepath + mmpPaths.insert(mmpFilename, newpwd); + + QStringList directDependencyList = getDependencyList(mmpFilename, -1); + for (int i = 0; i < directDependencyList.size(); ++i) { + project->values("MMPFILES_DIRECT_DEPENDS").append(directDependencyList.at(i)); + } + + QStringList dependencyList = getDependencyList(mmpFilename, 0); + + self->output_dir = Option::output_dir; + if (!Option::recursive || (!Option::output.fileName().endsWith(Option::dir_sep) && !QFileInfo(Option::output).isDir())) + self->output_file = Option::output.fileName(); + self->makefile = new BuildsMetaMakefileGenerator(project, name, false); + self->makefile->init(); + subs.append(self); + + return true; +} + +QStringList SymbianSubdirsMetaMakefileGenerator::calculateRelativePaths(QString mmpParent, QStringList mmpChildren) +{ + QStringList mmpRelativePaths; + QString parentDir = mmpPaths.value(mmpParent); + QDir directory(parentDir); + for (int i = 0; i < mmpChildren.size(); ++i) { + QString childDir = mmpPaths.value(mmpChildren.at(i)); + if (mmpChildren.at(i) == mmpParent) + mmpRelativePaths.append(mmpChildren.at(i)); + else { + QString relativePath = directory.relativeFilePath(childDir); + if (relativePath.startsWith("..")) + mmpRelativePaths.append(childDir); + else + directory.relativeFilePath(relativePath); + } + } + return mmpRelativePaths; +} + //Factory things QT_BEGIN_INCLUDE_NAMESPACE #include "unixmake.h" @@ -428,6 +693,8 @@ QT_BEGIN_INCLUDE_NAMESPACE #include "borland_bmake.h" #include "msvc_dsp.h" #include "msvc_vcproj.h" +#include "symmake_abld.h" +#include "symmake_sbsv2.h" QT_END_INCLUDE_NAMESPACE MakefileGenerator * @@ -464,6 +731,10 @@ MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO) mkfile = new NmakeMakefileGenerator; } else if(gen == "BMAKE") { mkfile = new BorlandMakefileGenerator; + } else if(gen == "SYMBIAN_ABLD") { + mkfile = new SymbianAbldMakefileGenerator; + } else if(gen == "SYMBIAN_SBSV2") { + mkfile = new SymbianSbsv2MakefileGenerator; } else { fprintf(stderr, "Unknown generator specified: %s\n", gen.toLatin1().constData()); } @@ -478,12 +749,15 @@ MetaMakefileGenerator * MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &name, bool op) { MetaMakefileGenerator *ret = 0; - if((Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || - Option::qmake_mode == Option::QMAKE_GENERATE_PRL)) { - if(proj->first("TEMPLATE").endsWith("subdirs")) + if ((Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || + Option::qmake_mode == Option::QMAKE_GENERATE_PRL)) { + if (proj->first("MAKEFILE_GENERATOR").startsWith("SYMBIAN") && proj->values("TEMPLATE").contains("subdirs")) { + // new metamakefilegenerator type to support subdirs for symbian related projects + ret = new SymbianSubdirsMetaMakefileGenerator(proj, name, op); + } else if (proj->first("TEMPLATE").endsWith("subdirs")) ret = new SubdirsMetaMakefileGenerator(proj, name, op); } - if(!ret) + if (!ret) ret = new BuildsMetaMakefileGenerator(proj, name, op); ret->init(); return ret; |