diff options
Diffstat (limited to 'qmake/generators/metamakefile.cpp')
-rw-r--r-- | qmake/generators/metamakefile.cpp | 315 |
1 files changed, 313 insertions, 2 deletions
diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp index 1646b5b..5494b5d 100644 --- a/qmake/generators/metamakefile.cpp +++ b/qmake/generators/metamakefile.cpp @@ -258,8 +258,9 @@ MakefileGenerator class SubdirsMetaMakefileGenerator : public MetaMakefileGenerator { +protected: + bool init_flag; -private: struct Subdir { Subdir() : makefile(0), indent(0) { } ~Subdir() { delete makefile; } @@ -370,6 +371,7 @@ SubdirsMetaMakefileGenerator::init() self->makefile = new BuildsMetaMakefileGenerator(project, name, false); self->makefile->init(); subs.append(self); + return true; } @@ -413,6 +415,306 @@ 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; + + // printf("Entering recursion mmpFilename = %s and depth = %d \n", qPrintable(mmpFilename), recursionDepth); + + 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 = mmpFilename + tailList.at(j); + QString path = tailList.at(j); + list.append(path); + //printf("MMPDEPENDENCY: %s\n", path.toAscii().data()); + }// for(int j = 0; j < values.size(); ++j) + //list.append(current); + } // for (int i = 0; i < values.size(); ++i) + + 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; + + /* + Not neccessary as it was + causing second pass through + subdir elements + + SubdirsMetaMakefileGenerator::init(); + */ + + /* + if we are here then we have template = subdirs + + so... go for it ... + */ + + 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(".mmp"); + + + 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(); + // TODO: create Option::mmp_ext + childMmpFilename = subdir.absoluteFilePath(); + childMmpFilename.replace(Option::pro_ext, QString("")); + childMmpFilename.append(".mmp"); + } + else { + childMmpFilename = subdir.absoluteFilePath(); + childMmpFilename.replace(QString(".pro"), QString(".mmp")); + sub_name = childMmpFilename; + sub_name.replace(QString(".mmp"), 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 { //what about shadow builds? + 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(".mmp"); + + // map mmpfile to its absolut 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); +/* + printf("\n \n PRINTING DEPENDENCY FOR: %s \n", mmpFilename.toAscii().data()); + // print it for debug + for(int i = 0; i < dependencyList.size(); ++i) { + printf("FINAL MMP DEPENDENCIES: %s\n", dependencyList.at(i).toAscii().data()); + } + printf("\n \n"); + + printf("\n \n PRINTING DIRECT DEPENDENCY FOR: %s \n", mmpFilename.toAscii().data()); + // print it for debug + for(int i = 0; i < directDependencyList.size(); ++i) { + printf("DIRECT MMP DEPENDENCIES: %s\n", directDependencyList.at(i).toAscii().data()); + } + printf("\n \n"); +*/ + 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); + //mmpRelativePaths.append(directory.relativeFilePath(childDir) + "/" + mmpChildren.at(i)); + } + } + return mmpRelativePaths; +} + //Factory things QT_BEGIN_INCLUDE_NAMESPACE #include "unixmake.h" @@ -423,6 +725,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 * @@ -459,6 +763,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()); } @@ -475,7 +783,10 @@ MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &na 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(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) |