From bca5a5d6f6e317151f3dab56f1d804af8d1aa62a Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 24 Nov 2010 11:51:57 -0600 Subject: [PATCH] Add resolve_depends(var, prefix) function to qmake This function calculates the topological order of variables. We will use it to determine which and in what order to link module libraries. The function is not tied to libraries/modules only, but requires the variables to be ordered to have their dependencies in the [prefix].depends subvariable. Due to the recursive nature of the algorithm it was just much easier to implement it directly in C++ rather than in a qmake-language function. --- qmake/project.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++- qmake/project.h | 1 + 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/qmake/project.cpp b/qmake/project.cpp index d4fa786..993c161 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -81,7 +81,7 @@ enum ExpandFunc { E_MEMBER=1, E_FIRST, E_LAST, E_CAT, E_FROMFILE, E_EVAL, E_LIST E_SPRINTF, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION, E_FIND, E_SYSTEM, E_UNIQUE, E_QUOTE, E_ESCAPE_EXPAND, E_UPPER, E_LOWER, E_FILES, E_PROMPT, E_RE_ESCAPE, E_REPLACE, - E_SIZE, E_GENERATE_UID }; + E_SIZE, E_GENERATE_UID, E_RESOLVE_DEPENDS }; QMap qmake_expandFunctions() { static QMap *qmake_expand_functions = 0; @@ -114,6 +114,7 @@ QMap qmake_expandFunctions() qmake_expand_functions->insert("replace", E_REPLACE); qmake_expand_functions->insert("size", E_SIZE); qmake_expand_functions->insert("generate_uid", E_GENERATE_UID); + qmake_expand_functions->insert("resolve_depends", E_RESOLVE_DEPENDS); } return *qmake_expand_functions; } @@ -1800,6 +1801,39 @@ QMakeProject::doProjectExpand(QString func, QStringList args, // defined in symbian generator extern QString generate_test_uid(const QString& target); + +void calculateDeps(QStringList &sortedList, const QString &item, const QString &prefix, + QStringList &org, QMap &place) +{ + if (sortedList.contains(item)) + return; + + foreach(QString dep, place.value(prefix + item + ".depends")) { + calculateDeps(sortedList, dep, prefix, org, place); + if (org.isEmpty()) + break; + } + + if (org.contains(item)) { + sortedList += item; + org.removeAll(item); + } +} + +QStringList +QMakeProject::resolveDepends(const QStringList &deps, const QString &prefix, + QMap &place) +{ + QStringList sortedList; + QStringList org = deps; + foreach(QString item, deps) { + calculateDeps(sortedList, item, prefix, org, place); + if (org.isEmpty()) + break; + } + return sortedList; +} + QStringList QMakeProject::doProjectExpand(QString func, QList args_list, QMap &place) @@ -2246,6 +2280,16 @@ QMakeProject::doProjectExpand(QString func, QList args_list, ret += generate_test_uid(args.first()); } break; + case E_RESOLVE_DEPENDS: { + if(args.count() < 1 || args.count() > 2) { + fprintf(stderr, "%s:%d: resolve_depends(var, prefix) requires one or two arguments.\n", + parser.file.toLatin1().constData(), parser.line_no); + } else { + ret += resolveDepends(args[0].split(QString(Option::field_sep)), + (args.count() != 2 ? QString() : args[1]), + place); + } + break; } default: { fprintf(stderr, "%s:%d: Unknown replace function: %s\n", parser.file.toLatin1().constData(), parser.line_no, diff --git a/qmake/project.h b/qmake/project.h index 0e6131d..aea18af 100644 --- a/qmake/project.h +++ b/qmake/project.h @@ -107,6 +107,7 @@ class QMakeProject QStringList doVariableReplaceExpand(const QString &str, QMap &place, bool *ok=0); void init(QMakeProperty *, const QMap *); QStringList &values(const QString &v, QMap &place); + QStringList resolveDepends(const QStringList &deps, const QString &prefix, QMap &place); void validateModes(); public: -- 2.7.4