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]<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.
This commit is contained in:
Marius Storm-Olsen 2010-11-24 11:51:57 -06:00 committed by axis
parent 00c5f39081
commit bca5a5d6f6
2 changed files with 46 additions and 1 deletions

View 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,

View 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: