Commit 792bdecebdd426672bc2d687a55ef1a732322ac9

Refactored SymbianSubdirsMetaMakefileGenerator out of qmake.

There was no need to have SymbianSubdirsMetaMakefileGenerator in
cross-platform metamakefile.cpp, so moved the Symbian specific
functionality to symmake.cpp as suggested by qmake reviewers.

Task-number: QT-822
Reviewed-by: Janne Anttila
qmake/generators/metamakefile.cpp
(1 / 267)
  
419419 subs.clear();
420420}
421421
422class SymbianSubdirsMetaMakefileGenerator : public SubdirsMetaMakefileGenerator
423{
424public:
425 SymbianSubdirsMetaMakefileGenerator(QMakeProject *p, const QString &n, bool op) : SubdirsMetaMakefileGenerator(p, n, op) { }
426 virtual ~SymbianSubdirsMetaMakefileGenerator();
427
428 virtual bool init();
429 virtual bool write(const QString &);
430
431protected:
432
433 static QMap<QString, QString> mmpPaths;
434
435 static QMultiMap<QString, QString> mmpDependency;
436
437 static QStringList getDependencyList(QString mmpFilename, int recursionDepth);
438
439 static QStringList calculateRelativePaths(QString mmpParent, QStringList mmpChildren);
440
441private:
442 QString cleanFromSpecialCharacters(QString& str);
443};
444
445QMap<QString, QString> SymbianSubdirsMetaMakefileGenerator::mmpPaths;
446
447QMultiMap<QString, QString> SymbianSubdirsMetaMakefileGenerator::mmpDependency;
448
449QStringList SymbianSubdirsMetaMakefileGenerator::getDependencyList(QString mmpFilename, int recursionDepth)
450{
451 QStringList list;
452
453 QList<QString> values = mmpDependency.values(mmpFilename);
454 if (recursionDepth < 0) {
455 // special case; just first dependency level
456 list = values;
457 return list;
458 }
459 if (values.size() == 0) {
460 //reached recursion END condition
461 if (recursionDepth == 0) {
462 --recursionDepth;
463 return list; // empty list // no dependencies / return
464 } else {
465 list.append(mmpFilename);
466 recursionDepth--;
467 return list; // leaf // return
468 }
469 } else {
470 recursionDepth++;
471 for (int i = 0; i < values.size(); ++i) {
472 QString current = values.at(i);
473 QStringList tailList = getDependencyList(current, recursionDepth);
474 for (int j = 0; j < tailList.size(); ++j) {
475 QString path = tailList.at(j);
476 list.append(path);
477 }
478 }
479
480 if (recursionDepth > 0) {
481 //for mmp somewhere in middle
482 list.append(mmpFilename);
483 }
484 recursionDepth--;
485 return list;
486 }
487}
488
489SymbianSubdirsMetaMakefileGenerator::~SymbianSubdirsMetaMakefileGenerator() { }
490
491bool SymbianSubdirsMetaMakefileGenerator::write(const QString &oldpwd)
492{
493 return SubdirsMetaMakefileGenerator::write(oldpwd);
494}
495
496QString SymbianSubdirsMetaMakefileGenerator::cleanFromSpecialCharacters(QString& str)
497{
498 QString tmp = str;
499
500 tmp.replace(QString("/"), QString("_"));
501 tmp.replace(QString("\\"), QString("_"));
502 tmp.replace(QString("-"), QString("_"));
503 tmp.replace(QString(":"), QString("_"));
504 tmp.replace(QString("."), QString("_"));
505
506 return tmp;
507}
508
509bool SymbianSubdirsMetaMakefileGenerator::init()
510{
511 if (init_flag)
512 return false;
513
514 init_flag = true;
515
516 // If we are here then we have template == subdirs
517
518 Option::recursive = true;
519
520 if (Option::recursive) {
521 QString old_output_dir = QDir::cleanPath(Option::output_dir);
522 if (!old_output_dir.endsWith('/'))
523 old_output_dir += '/';
524 QString old_output = Option::output.fileName();
525 QString oldpwd = QDir::cleanPath(qmake_getpwd());
526
527 if (!oldpwd.endsWith('/'))
528 oldpwd += '/';
529
530 // find the parent mmp filename
531 int end = oldpwd.size() - 1;
532 int start = oldpwd.lastIndexOf("/", end - 2);
533 QString parentMmpFilename = oldpwd.mid(start + 1, end - start - 1);
534 parentMmpFilename.prepend(oldpwd);
535 parentMmpFilename = parentMmpFilename.append(Option::mmp_ext);
536
537
538 const QStringList &subdirs = project->values("SUBDIRS");
539 static int recurseDepth = -1;
540 ++recurseDepth;
541 for (int i = 0; i < subdirs.size(); ++i) {
542 Subdir *sub = new Subdir;
543 sub->indent = recurseDepth;
544
545 QFileInfo subdir(subdirs.at(i));
546 // childMmpFielname should be derived from subdirName
547 QString subdirName = subdirs.at(i);
548 if (!project->isEmpty(subdirs.at(i) + ".file"))
549 subdir = project->first(subdirs.at(i) + ".file");
550 else if (!project->isEmpty(subdirs.at(i) + ".subdir"))
551 subdir = project->first(subdirs.at(i) + ".subdir");
552 QString sub_name;
553
554 QString childMmpFilename;
555
556 if (subdir.isDir()) {
557 subdir = QFileInfo(subdir.filePath() + "/" + subdir.fileName() + Option::pro_ext);
558 childMmpFilename = subdir.fileName();
559 childMmpFilename = subdir.absoluteFilePath();
560 childMmpFilename.replace(Option::pro_ext, QString(""));
561 childMmpFilename.append(Option::mmp_ext);
562 } else {
563 childMmpFilename = subdir.absoluteFilePath();
564 childMmpFilename.replace(Option::pro_ext, Option::mmp_ext);
565 sub_name = childMmpFilename;
566 sub_name.replace(Option::mmp_ext, QString(""));
567 sub_name.replace(0, sub_name.lastIndexOf("/") + 1, QString(""));
568 project->values("SHADOW_BLD_INFS").append(QString("bld.inf.") + sub_name);
569 }
570
571 //handle sub project
572 QMakeProject *sub_proj = new QMakeProject(project->properties());
573 for (int ind = 0; ind < sub->indent; ++ind)
574 printf(" ");
575 sub->input_dir = subdir.absolutePath();
576 if (subdir.isRelative() && old_output_dir != oldpwd) {
577 sub->output_dir = old_output_dir + "/" + subdir.path();
578 printf("Reading %s [%s]\n", subdir.absoluteFilePath().toLatin1().constData(), sub->output_dir.toLatin1().constData());
579 } else {
580 sub->output_dir = sub->input_dir;
581 printf("Reading %s\n", subdir.absoluteFilePath().toLatin1().constData());
582 }
583
584 // find the child mmp filename
585 qmake_setpwd(sub->input_dir);
586
587 QString newpwd = qmake_getpwd();
588
589 Option::output_dir = sub->output_dir;
590 if (Option::output_dir.at(Option::output_dir.length() - 1) != QLatin1Char('/'))
591 Option::output_dir += QLatin1Char('/');
592 sub_proj->read(subdir.fileName());
593 if (!sub_proj->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
594 fprintf(stderr, "Project file(%s) not recursed because all requirements not met:\n\t%s\n",
595 subdir.fileName().toLatin1().constData(),
596 sub_proj->values("QMAKE_FAILED_REQUIREMENTS").join(" ").toLatin1().constData());
597 delete sub;
598 delete sub_proj;
599 //continue;
600 } else {
601 // map mmpfile to its absolut filepath
602 mmpPaths.insert(childMmpFilename, newpwd);
603
604 // update mmp files dependency map
605 mmpDependency.insert(parentMmpFilename, childMmpFilename);
606
607 sub->makefile = MetaMakefileGenerator::createMetaGenerator(sub_proj, sub_name);
608 if (0 && sub->makefile->type() == SUBDIRSMETATYPE) {
609 subs.append(sub);
610 } else {
611 const QString output_name = Option::output.fileName();
612 Option::output.setFileName(sub->output_file);
613 sub->makefile->write(sub->output_dir);
614 delete sub;
615 qmakeClearCaches();
616 sub = 0;
617 Option::output.setFileName(output_name);
618 }
619 }
620
621 Option::output_dir = old_output_dir;
622 qmake_setpwd(oldpwd);
623
624 }
625 --recurseDepth;
626 Option::output.setFileName(old_output);
627 Option::output_dir = old_output_dir;
628 qmake_setpwd(oldpwd);
629 }
630
631 Subdir *self = new Subdir;
632 self->input_dir = qmake_getpwd();
633
634 // To fully expand find all dependencies:
635 // Do as recursion, then insert result as subdirs data in project
636 QString newpwd = qmake_getpwd();
637 if (!newpwd.endsWith('/'))
638 newpwd += '/';
639 int end = newpwd.size() - 1;
640 int start = newpwd.lastIndexOf("/", end - 2);
641 QString mmpFilename = newpwd.mid(start + 1, end - start - 1);
642 mmpFilename.prepend(newpwd);
643 mmpFilename = mmpFilename.append(Option::mmp_ext);
644
645 // map mmpfile to its absolute filepath
646 mmpPaths.insert(mmpFilename, newpwd);
647
648 QStringList directDependencyList = getDependencyList(mmpFilename, -1);
649 for (int i = 0; i < directDependencyList.size(); ++i) {
650 project->values("MMPFILES_DIRECT_DEPENDS").append(directDependencyList.at(i));
651 }
652
653 QStringList dependencyList = getDependencyList(mmpFilename, 0);
654
655 self->output_dir = Option::output_dir;
656 if (!Option::recursive || (!Option::output.fileName().endsWith(Option::dir_sep) && !QFileInfo(Option::output).isDir()))
657 self->output_file = Option::output.fileName();
658 self->makefile = new BuildsMetaMakefileGenerator(project, name, false);
659 self->makefile->init();
660 subs.append(self);
661
662 return true;
663}
664
665QStringList SymbianSubdirsMetaMakefileGenerator::calculateRelativePaths(QString mmpParent, QStringList mmpChildren)
666{
667 QStringList mmpRelativePaths;
668 QString parentDir = mmpPaths.value(mmpParent);
669 QDir directory(parentDir);
670 for (int i = 0; i < mmpChildren.size(); ++i) {
671 QString childDir = mmpPaths.value(mmpChildren.at(i));
672 if (mmpChildren.at(i) == mmpParent)
673 mmpRelativePaths.append(mmpChildren.at(i));
674 else {
675 QString relativePath = directory.relativeFilePath(childDir);
676 if (relativePath.startsWith(".."))
677 mmpRelativePaths.append(childDir);
678 else
679 directory.relativeFilePath(relativePath);
680 }
681 }
682 return mmpRelativePaths;
683}
684
685422//Factory things
686423QT_BEGIN_INCLUDE_NAMESPACE
687424#include "unixmake.h"
487487 MetaMakefileGenerator *ret = 0;
488488 if ((Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
489489 Option::qmake_mode == Option::QMAKE_GENERATE_PRL)) {
490 if (proj->first("MAKEFILE_GENERATOR").startsWith("SYMBIAN") && proj->values("TEMPLATE").contains("subdirs")) {
491 // new metamakefilegenerator type to support subdirs for symbian related projects
492 ret = new SymbianSubdirsMetaMakefileGenerator(proj, name, op);
493 } else if (proj->first("TEMPLATE").endsWith("subdirs"))
490 if (proj->first("TEMPLATE").endsWith("subdirs"))
494491 ret = new SubdirsMetaMakefileGenerator(proj, name, op);
495492 }
496493 if (!ret)
qmake/generators/symbian/symmake.cpp
(44 / 56)
  
10921092void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension)
10931093{
10941094 // Read user defined bld inf rules
1095
10951096 QMap<QString, QStringList> userBldInfRules;
10961097 for (QMap<QString, QStringList>::iterator it = project->variables().begin(); it != project->variables().end(); ++it) {
10971098 if (it.key().startsWith(BLD_INF_RULES_BASE)) {
11231123 QString mmpfilename = escapeFilePath(fileFixify(project->projectFile()));
11241124 mmpfilename = mmpfilename.replace(mmpfilename.lastIndexOf("."), 4, Option::mmp_ext);
11251125 QString currentPath = qmake_getpwd();
1126 QDir directory(currentPath);
11261127
1127 if (!currentPath.endsWith(QString("/")))
1128 currentPath.append("/");
1128 const QStringList &subdirs = project->values("SUBDIRS");
1129 foreach(QString item, subdirs) {
1130 QString fixedItem;
1131 if (!project->isEmpty(item + ".file")) {
1132 fixedItem = project->first(item + ".file");
1133 } else if (!project->isEmpty(item + ".subdir")) {
1134 fixedItem = project->first(item + ".subdir");
1135 } else {
1136 fixedItem = item;
1137 }
11291138
1130 QStringList mmpProjects = project->values("MMPFILES_DIRECT_DEPENDS");
1131 QStringList shadowProjects = project->values("SHADOW_BLD_INFS");
1132
1133 removeDuplicatedStrings(mmpProjects);
1134 removeDuplicatedStrings(shadowProjects);
1135
1136 // Go in reverse order as that is the way how we build the list
1137 QListIterator<QString> iT(mmpProjects);
1138 iT.toBack();
1139 while (iT.hasPrevious()) {
1140 QString fullMmpName = iT.previous();
1141 QString relativePath;
1139 QFileInfo subdir(fileInfo(fixedItem));
1140 QString relativePath = directory.relativeFilePath(fixedItem);
1141 QString subdirFileName = subdir.completeBaseName();
1142 QString fullProName = subdir.absoluteFilePath();;
11421143 QString bldinfFilename;
11431144
1144 QString fullProFilename = fullMmpName;
1145 fullProFilename.replace(Option::mmp_ext, Option::pro_ext);
1146 QString uid = generate_uid(fullProFilename);
1147
1148 QString cleanMmpName = fullProFilename;
1149 cleanMmpName.replace(Option::pro_ext, QString(""));
1150 cleanMmpName.replace(0, cleanMmpName.lastIndexOf("/") + 1, QString(""));
1151
1152 if (shadowProjects.contains(BLD_INF_FILENAME "." + cleanMmpName)) { // shadow project
1153 QDir directory(currentPath);
1154 relativePath = directory.relativeFilePath(fullProFilename);
1155 bldinfFilename = BLD_INF_FILENAME "." + cleanMmpName;
1145 if (subdir.isDir()) {
1146 // Subdir is a regular project
1147 bldinfFilename = relativePath + QString("/") + QString(BLD_INF_FILENAME);
1148 fullProName += QString("/") + subdirFileName + Option::pro_ext;
1149 } else {
1150 // Subdir is actually a .pro file
11561151 if (relativePath.contains("/")) {
1157 // Shadow .pro not in same directory as parent .pro
1158 if (relativePath.startsWith("..")) {
1159 // Shadow .pro out of parent .pro
1160 relativePath.replace(relativePath.lastIndexOf("/"), relativePath.length(), QString(""));
1161 bldinfFilename.prepend("/").prepend(relativePath);
1162 } else {
1163 relativePath.replace(relativePath.lastIndexOf("/"), relativePath.length(), QString(""));
1164 bldinfFilename.prepend("/").prepend(relativePath);
1165 }
1152 // .pro not in same directory as parent .pro
1153 relativePath.remove(relativePath.lastIndexOf("/") + 1, relativePath.length());
1154 bldinfFilename = relativePath;
11661155 } else {
1167 // Shadow .pro and parent .pro in same directory
1168 bldinfFilename.prepend("./");
1156 // .pro and parent .pro in same directory
1157 bldinfFilename = QString("./");
11691158 }
1170 } else { // regular project
1171 QDir directory(currentPath);
1172 relativePath = directory.relativeFilePath(fullProFilename);
1173 relativePath.replace(relativePath.lastIndexOf("/"), relativePath.length(), QString(""));
1174 bldinfFilename = relativePath.append("/").append(BLD_INF_FILENAME);
1159 bldinfFilename += QString(BLD_INF_FILENAME ".") + subdirFileName;
11751160 }
11761161
1177 QString bldinfDefine = QString("BLD_INF_") + cleanMmpName + QString("_") + uid;
1162 QString uid = generate_uid(fullProName);
1163 QString bldinfDefine = QString("BLD_INF_") + subdirFileName + QString("_") + uid;
11781164 bldinfDefine = bldinfDefine.toUpper();
11791165 removeSpecialCharacters(bldinfDefine);
11801166
11821182 t << endl;
11831183
11841184 // Add project mmps and old style extension makefiles
1185
11851186 QString mmpTag;
11861187 if (project->values("CONFIG").contains("symbian_test", Qt::CaseInsensitive))
11871188 mmpTag = QLatin1String(BLD_INF_TAG_TESTMMPFILES);
11921192 t << endl << mmpTag << endl << endl;
11931193
11941194 writeBldInfMkFilePart(t, addDeploymentExtension);
1195 if (targetType == TypeSubdirs) {
1196 mmpProjects.removeOne(mmpfilename);
1197 } else {
1195 if (targetType != TypeSubdirs) {
11981196 QString shortProFilename = project->projectFile();
11991197 shortProFilename.replace(0, shortProFilename.lastIndexOf("/") + 1, QString(""));
12001198 shortProFilename.replace(Option::pro_ext, QString(""));
12101210 t << endl << BLD_INF_TAG_EXTENSIONS << endl << endl;
12111211
12121212 // Generate extension rules
1213
12131214 writeBldInfExtensionRulesPart(t);
12141215
12151216 userItems = userBldInfRules.value(BLD_INF_TAG_EXTENSIONS);
16851685 .arg(MAKE_CACHE_NAME)
16861686 .arg(OK_SIS_TARGET)
16871687 .arg(FAIL_SIS_NOCACHE_TARGET)
1688 .arg(FAIL_SIS_NOPKG_TARGET);
1689 t << siscommand << endl;
1688 .arg(FAIL_SIS_NOPKG_TARGET);
1689 t << siscommand << endl;
16901690 t << endl;
16911691
16921692 t << OK_SIS_TARGET ":" << endl;
16971697 .arg("pkg");
16981698 t << pkgcommand << endl;
16991699 t << endl;
1700
1701 t << FAIL_SIS_NOPKG_TARGET ":" << endl;
1702 t << "\t$(error PKG file does not exist, 'SIS' target is only supported for executables or projects with DEPLOYMENT statement)" << endl;
1700
1701 t << FAIL_SIS_NOPKG_TARGET ":" << endl;
1702 t << "\t$(error PKG file does not exist, 'SIS' target is only supported for executables or projects with DEPLOYMENT statement)" << endl;
17031703 t << endl;
1704
1705 t << FAIL_SIS_NOCACHE_TARGET ":" << endl;
1706 t << "\t$(error Project has to be build before calling 'SIS' target)" << endl;
1704
1705 t << FAIL_SIS_NOCACHE_TARGET ":" << endl;
1706 t << "\t$(error Project has to be build before calling 'SIS' target)" << endl;
17071707 t << endl;
1708
17091708
1709
17101710 t << RESTORE_BUILD_TARGET ":" << endl;
17111711 t << "-include " MAKE_CACHE_NAME << endl;
17121712 t << endl;
17151715void SymbianMakefileGenerator::generateDistcleanTargets(QTextStream& t)
17161716{
17171717 t << "dodistclean:" << endl;
1718 foreach(QString item, project->values("SUBDIRS")) {
1718 const QStringList &subdirs = project->values("SUBDIRS");
1719 foreach(QString item, subdirs) {
17191720 bool fromFile = false;
17201721 QString fixedItem;
17211722 if (!project->isEmpty(item + ".file")) {
qmake/project.cpp
(23 / 22)
  
519519// Checking for symbian build is primarily determined from the qmake spec,
520520// but if that is not specified, detect if symbian is the default spec
521521// by checking the MAKEFILE_GENERATOR variable value.
522static void init_isForSymbian(const QMap<QString, QStringList>& vars)
522static void init_symbian(const QMap<QString, QStringList>& vars)
523523{
524524 if (isForSymbian_value != isForSymbian_NOT_SET)
525525 return;
527527 QString spec = QFileInfo(Option::mkfile::qmakespec).fileName();
528528 if (spec.startsWith("symbian-abld", Qt::CaseInsensitive)) {
529529 isForSymbian_value = isForSymbian_ABLD;
530 return;
531 }
532 if (spec.startsWith("symbian-sbsv2", Qt::CaseInsensitive)) {
530 } else if (spec.startsWith("symbian-sbsv2", Qt::CaseInsensitive)) {
533531 isForSymbian_value = isForSymbian_SBSV2;
534 return;
535 }
532 } else {
533 QStringList generatorList = vars["MAKEFILE_GENERATOR"];
536534
537 QStringList generatorList = vars["MAKEFILE_GENERATOR"];
538
539 if (!generatorList.isEmpty()) {
540 QString generator = generatorList.first();
541 if (generator.startsWith("SYMBIAN_ABLD"))
542 isForSymbian_value = isForSymbian_ABLD;
543 else if (generator.startsWith("SYMBIAN_SBSV2"))
544 isForSymbian_value = isForSymbian_SBSV2;
545 else
535 if (!generatorList.isEmpty()) {
536 QString generator = generatorList.first();
537 if (generator.startsWith("SYMBIAN_ABLD"))
538 isForSymbian_value = isForSymbian_ABLD;
539 else if (generator.startsWith("SYMBIAN_SBSV2"))
540 isForSymbian_value = isForSymbian_SBSV2;
541 else
542 isForSymbian_value = isForSymbian_FALSE;
543 } else {
546544 isForSymbian_value = isForSymbian_FALSE;
547 } else {
548 isForSymbian_value = isForSymbian_FALSE;
545 }
549546 }
547
548 // Force recursive on Symbian, as non-recursive is not really a viable option there
549 if (isForSymbian_value != isForSymbian_FALSE)
550 Option::recursive = true;
550551}
551552
552553bool isForSymbian()
555555 // If isForSymbian_value has not been initialized explicitly yet,
556556 // call initializer with dummy map to check qmake spec.
557557 if (isForSymbian_value == isForSymbian_NOT_SET)
558 init_isForSymbian(QMap<QString, QStringList>());
558 init_symbian(QMap<QString, QStringList>());
559559
560 return (isForSymbian_value == isForSymbian_ABLD || isForSymbian_value == isForSymbian_SBSV2);
560 return (isForSymbian_value != isForSymbian_FALSE);
561561}
562562
563563bool isForSymbianSbsv2()
565565 // If isForSymbian_value has not been initialized explicitly yet,
566566 // call initializer with dummy map to check qmake spec.
567567 if (isForSymbian_value == isForSymbian_NOT_SET)
568 init_isForSymbian(QMap<QString, QStringList>());
568 init_symbian(QMap<QString, QStringList>());
569569
570570 return (isForSymbian_value == isForSymbian_SBSV2);
571571}
14641464 return false;
14651465 }
14661466
1467 init_isForSymbian(base_vars);
1467 init_symbian(base_vars);
14681468
14691469 if(Option::mkfile::do_cache && !Option::mkfile::cachefile.isEmpty()) {
14701470 debug_msg(1, "QMAKECACHE file: reading %s", Option::mkfile::cachefile.toLatin1().constData());
17161716 if(file.indexOf(Option::dir_sep) == -1 || !QFile::exists(file)) {
17171717 static QStringList *feature_roots = 0;
17181718 if(!feature_roots) {
1719 init_isForSymbian(base_vars);
1719 init_symbian(base_vars);
17201720 feature_roots = new QStringList(qmake_feature_paths(prop));
17211721 qmakeAddCacheClear(qmakeDeleteCacheClear_QStringList, (void**)&feature_roots);
17221722 }

Comments

Add a new comment:

Login or create an account to post a comment

Add your comment