qmake/generators/metamakefile.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
   427     for(int i = 0; i < subs.count(); i++)
   427     for(int i = 0; i < subs.count(); i++)
   428         delete subs[i];
   428         delete subs[i];
   429     subs.clear();
   429     subs.clear();
   430 }
   430 }
   431 
   431 
   432 class SymbianSubdirsMetaMakefileGenerator : public SubdirsMetaMakefileGenerator
       
   433 {
       
   434 public:
       
   435     SymbianSubdirsMetaMakefileGenerator(QMakeProject *p, const QString &n, bool op) : SubdirsMetaMakefileGenerator(p, n, op) { }
       
   436     virtual ~SymbianSubdirsMetaMakefileGenerator();
       
   437 
       
   438     virtual bool init();
       
   439     virtual bool write(const QString &);
       
   440 
       
   441 protected:
       
   442 
       
   443     static QMap<QString, QString> mmpPaths;
       
   444 
       
   445     static QMultiMap<QString, QString> mmpDependency;
       
   446 
       
   447     static QStringList getDependencyList(QString mmpFilename, int recursionDepth);
       
   448 
       
   449     static QStringList calculateRelativePaths(QString mmpParent, QStringList mmpChildren);
       
   450 
       
   451 private:
       
   452     QString cleanFromSpecialCharacters(QString& str);
       
   453 };
       
   454 
       
   455 QMap<QString, QString> SymbianSubdirsMetaMakefileGenerator::mmpPaths;
       
   456 
       
   457 QMultiMap<QString, QString> SymbianSubdirsMetaMakefileGenerator::mmpDependency;
       
   458 
       
   459 QStringList SymbianSubdirsMetaMakefileGenerator::getDependencyList(QString mmpFilename, int recursionDepth)
       
   460 {
       
   461     QStringList list;
       
   462 
       
   463     QList<QString> values = mmpDependency.values(mmpFilename);
       
   464     if (recursionDepth < 0) {
       
   465         // special case; just first dependency level
       
   466         list = values;
       
   467         return list;
       
   468     }
       
   469     if (values.size() == 0) {
       
   470         //reached recursion END condition
       
   471         if (recursionDepth == 0) {
       
   472             --recursionDepth;
       
   473             return list; // empty list // no dependencies / return
       
   474         } else {
       
   475             list.append(mmpFilename);
       
   476             recursionDepth--;
       
   477             return list; // leaf // return
       
   478         }
       
   479     } else {
       
   480         recursionDepth++;
       
   481         for (int i = 0; i < values.size(); ++i) {
       
   482             QString current = values.at(i);
       
   483             QStringList tailList = getDependencyList(current, recursionDepth);
       
   484             for (int j = 0; j < tailList.size(); ++j) {
       
   485                 QString path = tailList.at(j);
       
   486                 list.append(path);
       
   487             }
       
   488         }
       
   489 
       
   490         if (recursionDepth > 0) {
       
   491             //for mmp somewhere in middle
       
   492             list.append(mmpFilename);
       
   493         }
       
   494         recursionDepth--;
       
   495         return list;
       
   496     }
       
   497 }
       
   498 
       
   499 SymbianSubdirsMetaMakefileGenerator::~SymbianSubdirsMetaMakefileGenerator() { }
       
   500 
       
   501 bool SymbianSubdirsMetaMakefileGenerator::write(const QString &oldpwd)
       
   502 {
       
   503     return SubdirsMetaMakefileGenerator::write(oldpwd);
       
   504 }
       
   505 
       
   506 QString SymbianSubdirsMetaMakefileGenerator::cleanFromSpecialCharacters(QString& str)
       
   507 {
       
   508     QString tmp = str;
       
   509 
       
   510     tmp.replace(QString("/"), QString("_"));
       
   511     tmp.replace(QString("\\"), QString("_"));
       
   512     tmp.replace(QString("-"), QString("_"));
       
   513     tmp.replace(QString(":"), QString("_"));
       
   514     tmp.replace(QString("."), QString("_"));
       
   515 
       
   516     return tmp;
       
   517 }
       
   518 
       
   519 bool SymbianSubdirsMetaMakefileGenerator::init()
       
   520 {
       
   521     if (init_flag)
       
   522         return false;
       
   523 
       
   524     init_flag = true;
       
   525 
       
   526     // If we are here then we have template == subdirs
       
   527 
       
   528     Option::recursive = true;
       
   529 
       
   530     if (Option::recursive) {
       
   531         QString old_output_dir = QDir::cleanPath(Option::output_dir);
       
   532         if (!old_output_dir.endsWith('/'))
       
   533             old_output_dir += '/';
       
   534         QString old_output = Option::output.fileName();
       
   535         QString oldpwd = QDir::cleanPath(qmake_getpwd());
       
   536 
       
   537         if (!oldpwd.endsWith('/'))
       
   538             oldpwd += '/';
       
   539 
       
   540         // find the parent mmp filename
       
   541         int end = oldpwd.size() - 1;
       
   542         int start = oldpwd.lastIndexOf("/", end - 2);
       
   543         QString parentMmpFilename = oldpwd.mid(start + 1, end - start - 1);
       
   544         parentMmpFilename.prepend(oldpwd);
       
   545         parentMmpFilename = parentMmpFilename.append(Option::mmp_ext);
       
   546 
       
   547 
       
   548         const QStringList &subdirs = project->values("SUBDIRS");
       
   549         static int recurseDepth = -1;
       
   550         ++recurseDepth;
       
   551         for (int i = 0; i < subdirs.size(); ++i) {
       
   552             Subdir *sub = new Subdir;
       
   553             sub->indent = recurseDepth;
       
   554 
       
   555             QFileInfo subdir(subdirs.at(i));
       
   556             // childMmpFielname should be derived from subdirName
       
   557             QString subdirName = subdirs.at(i);
       
   558             if (!project->isEmpty(subdirs.at(i) + ".file"))
       
   559                 subdir = project->first(subdirs.at(i) + ".file");
       
   560             else if (!project->isEmpty(subdirs.at(i) + ".subdir"))
       
   561                 subdir = project->first(subdirs.at(i) + ".subdir");
       
   562             QString sub_name;
       
   563 
       
   564             QString childMmpFilename;
       
   565 
       
   566             if (subdir.isDir()) {
       
   567                 subdir = QFileInfo(subdir.filePath() + "/" + subdir.fileName() + Option::pro_ext);
       
   568                 childMmpFilename = subdir.fileName();
       
   569                 childMmpFilename = subdir.absoluteFilePath();
       
   570                 childMmpFilename.replace(Option::pro_ext, QString(""));
       
   571                 childMmpFilename.append(Option::mmp_ext);
       
   572             } else {
       
   573                 childMmpFilename = subdir.absoluteFilePath();
       
   574                 childMmpFilename.replace(Option::pro_ext, Option::mmp_ext);
       
   575                 sub_name = childMmpFilename;
       
   576                 sub_name.replace(Option::mmp_ext, QString(""));
       
   577                 sub_name.replace(0, sub_name.lastIndexOf("/") + 1, QString(""));
       
   578                 project->values("SHADOW_BLD_INFS").append(QString("bld.inf.") + sub_name);
       
   579             }
       
   580 
       
   581             //handle sub project
       
   582             QMakeProject *sub_proj = new QMakeProject(project->properties());
       
   583 
       
   584             if (!Option::mkfile::listgen) {
       
   585                 for (int ind = 0; ind < sub->indent; ++ind)
       
   586                     printf(" ");
       
   587             }
       
   588 
       
   589             sub->input_dir = subdir.absolutePath();
       
   590             if (subdir.isRelative() && old_output_dir != oldpwd) {
       
   591                 sub->output_dir = old_output_dir + "/" + subdir.path();
       
   592                 printf("Reading %s [%s]\n", subdir.absoluteFilePath().toLatin1().constData(), sub->output_dir.toLatin1().constData());
       
   593             } else {
       
   594                 sub->output_dir = sub->input_dir;
       
   595                 printf("Reading %s\n", subdir.absoluteFilePath().toLatin1().constData());
       
   596             }
       
   597 
       
   598             // find the child mmp filename
       
   599             qmake_setpwd(sub->input_dir);
       
   600 
       
   601             QString newpwd = qmake_getpwd();
       
   602 
       
   603             Option::output_dir = sub->output_dir;
       
   604             if (Option::output_dir.at(Option::output_dir.length() - 1) != QLatin1Char('/'))
       
   605                 Option::output_dir += QLatin1Char('/');
       
   606             sub_proj->read(subdir.fileName());
       
   607             if (!sub_proj->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
       
   608                 fprintf(stderr, "Project file(%s) not recursed because all requirements not met:\n\t%s\n",
       
   609                         subdir.fileName().toLatin1().constData(),
       
   610                         sub_proj->values("QMAKE_FAILED_REQUIREMENTS").join(" ").toLatin1().constData());
       
   611                 delete sub;
       
   612                 delete sub_proj;
       
   613                 //continue;
       
   614             } else {
       
   615                 // map mmpfile to its absolut filepath
       
   616                 mmpPaths.insert(childMmpFilename, newpwd);
       
   617 
       
   618                 // update mmp files dependency map
       
   619                 mmpDependency.insert(parentMmpFilename, childMmpFilename);
       
   620 
       
   621                 sub->makefile = MetaMakefileGenerator::createMetaGenerator(sub_proj, sub_name);
       
   622                 if (0 && sub->makefile->type() == SUBDIRSMETATYPE) {
       
   623                     subs.append(sub);
       
   624                 } else {
       
   625                     const QString output_name = Option::output.fileName();
       
   626                     Option::output.setFileName(sub->output_file);
       
   627                     sub->makefile->write(sub->output_dir);
       
   628                     delete sub;
       
   629                     qmakeClearCaches();
       
   630                     sub = 0;
       
   631                     Option::output.setFileName(output_name);
       
   632                 }
       
   633             }
       
   634 
       
   635             Option::output_dir = old_output_dir;
       
   636             qmake_setpwd(oldpwd);
       
   637 
       
   638         }
       
   639         --recurseDepth;
       
   640         Option::output.setFileName(old_output);
       
   641         Option::output_dir = old_output_dir;
       
   642         qmake_setpwd(oldpwd);
       
   643     }
       
   644 
       
   645     Subdir *self = new Subdir;
       
   646     self->input_dir = qmake_getpwd();
       
   647 
       
   648     // To fully expand find all dependencies:
       
   649     // Do as recursion, then insert result as subdirs data in project
       
   650     QString newpwd = qmake_getpwd();
       
   651     if (!newpwd.endsWith('/'))
       
   652         newpwd += '/';
       
   653     int end = newpwd.size() - 1;
       
   654     int start = newpwd.lastIndexOf("/", end - 2);
       
   655     QString mmpFilename = newpwd.mid(start + 1, end - start - 1);
       
   656     mmpFilename.prepend(newpwd);
       
   657     mmpFilename = mmpFilename.append(Option::mmp_ext);
       
   658 
       
   659     // map mmpfile to its absolute filepath
       
   660     mmpPaths.insert(mmpFilename, newpwd);
       
   661 
       
   662     QStringList directDependencyList = getDependencyList(mmpFilename, -1);
       
   663     for (int i = 0; i < directDependencyList.size(); ++i) {
       
   664         project->values("MMPFILES_DIRECT_DEPENDS").append(directDependencyList.at(i));
       
   665     }
       
   666 
       
   667     QStringList dependencyList = getDependencyList(mmpFilename, 0);
       
   668 
       
   669     self->output_dir = Option::output_dir;
       
   670     if (!Option::recursive || (!Option::output.fileName().endsWith(Option::dir_sep) && !QFileInfo(Option::output).isDir()))
       
   671         self->output_file = Option::output.fileName();
       
   672     self->makefile = new BuildsMetaMakefileGenerator(project, name, false);
       
   673     self->makefile->init();
       
   674     subs.append(self);
       
   675 
       
   676     return true;
       
   677 }
       
   678 
       
   679 QStringList SymbianSubdirsMetaMakefileGenerator::calculateRelativePaths(QString mmpParent, QStringList mmpChildren)
       
   680 {
       
   681     QStringList mmpRelativePaths;
       
   682     QString parentDir = mmpPaths.value(mmpParent);
       
   683     QDir directory(parentDir);
       
   684     for (int i = 0; i < mmpChildren.size(); ++i) {
       
   685         QString childDir = mmpPaths.value(mmpChildren.at(i));
       
   686         if (mmpChildren.at(i) == mmpParent)
       
   687             mmpRelativePaths.append(mmpChildren.at(i));
       
   688         else {
       
   689             QString relativePath = directory.relativeFilePath(childDir);
       
   690             if (relativePath.startsWith(".."))
       
   691                 mmpRelativePaths.append(childDir);
       
   692             else
       
   693                 directory.relativeFilePath(relativePath);
       
   694         }
       
   695     }
       
   696     return mmpRelativePaths;
       
   697 }
       
   698 
       
   699 //Factory things
   432 //Factory things
   700 QT_BEGIN_INCLUDE_NAMESPACE
   433 QT_BEGIN_INCLUDE_NAMESPACE
   701 #include "unixmake.h"
   434 #include "unixmake.h"
   702 #include "mingw_make.h"
   435 #include "mingw_make.h"
   703 #include "projectgenerator.h"
   436 #include "projectgenerator.h"