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" |