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:
parent
00c5f39081
commit
bca5a5d6f6
@ -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,
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user