Add resolve_depends(var, prefix) function to qmake
authorMarius Storm-Olsen <marius.storm-olsen@nokia.com>
Wed, 24 Nov 2010 17:51:57 +0000 (11:51 -0600)
committeraxis <qt-info@nokia.com>
Wed, 27 Apr 2011 10:05:46 +0000 (12:05 +0200)
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]<var>.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
qmake/project.h

index d4fa786..993c161 100644 (file)
@@ -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<QString, ExpandFunc> qmake_expandFunctions()
 {
     static QMap<QString, ExpandFunc> *qmake_expand_functions = 0;
@@ -114,6 +114,7 @@ QMap<QString, ExpandFunc> 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<QString, QStringList> &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<QString, QStringList> &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<QStringList> args_list,
                               QMap<QString, QStringList> &place)
@@ -2246,6 +2280,16 @@ QMakeProject::doProjectExpand(QString func, QList<QStringList> 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,
index 0e6131d..aea18af 100644 (file)
@@ -107,6 +107,7 @@ class QMakeProject
     QStringList doVariableReplaceExpand(const QString &str, QMap<QString, QStringList> &place, bool *ok=0);
     void init(QMakeProperty *, const QMap<QString, QStringList> *);
     QStringList &values(const QString &v, QMap<QString, QStringList> &place);
+    QStringList resolveDepends(const QStringList &deps, const QString &prefix, QMap<QString, QStringList> &place);
     void validateModes();
 
 public: