Index: trunk/qmake/generators/os2/gnumake.cpp
===================================================================
--- trunk/qmake/generators/os2/gnumake.cpp	(revision 369)
+++ trunk/qmake/generators/os2/gnumake.cpp	(revision 370)
@@ -100,10 +100,27 @@
 }
 
-QString
-GNUMakefileGenerator::findBestVersion(const QString &d, const QString &stem, const QString &ext)
-{
-    QString bd = Option::fixPathToLocalOS(d, true);
-    if(!exists(bd))
-        return QString();
+// Searches for the best version of the requested library named \a stem in
+// \a dir and append the result to the \a found list. If the best version is
+// found, it is appended first in the list, otherwise \a stem is appended as
+// is. If a .prl file corresponding to \a stem is found, the library name is
+// taken from there. If the .prl refers to other libraries the found one
+// depends on, they are also appended to the returned list (as is).
+//
+// The function returns \c true if the best version for the given \a stem was
+// actually found and \c false otherwise (\a found will remain untouched in this
+// case).
+//
+// Note that if a circular reference to the project's target library or to a
+// library we already processed is detected, the function returns \c true but
+// \a found remains untouched; this indicates that the given \a stem should be
+// dropped from the resulting library list at all.
+bool
+GNUMakefileGenerator::findBestVersion(const QString &dir, const QString &stem,
+                                      const QString &ext, QStringList &found)
+{
+    QString localDir = Option::fixPathToLocalOS(dir, true);
+    if(!exists(localDir)) {
+        return false;
+    }
 
     QString dllStem = stem + QTDLL_POSTFIX;
@@ -115,15 +132,16 @@
     if (project->isActiveConfig("link_prl")) {
         QMakeMetaInfo libinfo;
-        QString libfile = QMakeMetaInfo::findLib(bd + Option::dir_sep + dllStem);
-        if (project->values("QMAKE_PRL_INTERNAL_FILES").contains(libfile)) {
-            // already processed, return emtpy string to discard this lib
-            return QString("");
-        }
-        if (libinfo.readLib(libfile)) {
-            project->values("QMAKE_PRL_INTERNAL_FILES") += libfile;
+        QString prl = QMakeMetaInfo::findLib(localDir + Option::dir_sep + dllStem);
+        if (project->values("QMAKE_PRL_INTERNAL_FILES").contains(prl)) {
+            // already processed, drop this stem
+            return true;
+        }
+        if (libinfo.readLib(prl)) {
+            // take the data from .prl
+            project->values("QMAKE_PRL_INTERNAL_FILES") += prl;
             QString target = libinfo.first("QMAKE_PRL_TARGET");
             if (target == project->first("TARGET")) {
-                // circular reference to ourselves, return emtpy string to discard this lib
-                return QString("");
+                // circular reference to ourselves, drop this stem
+                return true;
             }
             if (target.isEmpty())
@@ -135,96 +153,121 @@
                 target += libinfo.first("QMAKE_PRL_VERSION").replace(".", "");
 
-            const QStringList &in = libinfo.values("QMAKE_PRL_LIBS");
-            QStringList &out = project->values("QMAKE_PRL_LIBS");
-            for (QStringList::ConstIterator it = in.begin(); it != in.end(); ++it) {
-                if (!out.contains(*it))
-                    out.append((*it));
-            }
-            return target;
-        }
-    }
-
-    if (!versionOverride.isEmpty())
-        return stem + versionOverride;
+            // put the stem replacement as found in .prl
+            found << target;
+            // put all dependencies as is
+            foreach (const QString &lib, libinfo.values("QMAKE_PRL_LIBS"))
+                found << lib;
+
+            return true;
+        }
+    }
+
+    if (!versionOverride.isEmpty()) {
+        // unconditionally use verrsion overrride
+        found << stem + versionOverride;
+        return true;
+    }
 
     int biggest = -1;
     if(!project->isActiveConfig("no_versionlink")) {
-        QDir dir(bd);
+        // search for a library with the highest version number
+        QDir dir(localDir);
         QStringList entries = dir.entryList();
-        QRegExp regx(QString("((lib)?%1([0-9]*))(%2)$").arg(dllStem).arg(ext), Qt::CaseInsensitive);
-        for(QStringList::Iterator it = entries.begin(); it != entries.end(); ++it) {
-            if(regx.exactMatch((*it))) {
-				if (!regx.cap(3).isEmpty()) {
-					bool ok = true;
-					int num = regx.cap(3).toInt(&ok);
-					biggest = qMax(biggest, (!ok ? -1 : num));
-				}
-			}
-        }
-    }
-    if (biggest != -1)
-        return stem + QString::number(biggest);
-
-    return QString();
+        QRegExp regx(QString("((lib)?%1([0-9]*))(%2)$").arg(dllStem).arg(ext),
+                     Qt::CaseInsensitive);
+        foreach (const QString &ent, entries) {
+            if(regx.exactMatch(ent)) {
+                if (!regx.cap(3).isEmpty()) {
+                    bool ok = true;
+                    int num = regx.cap(3).toInt(&ok);
+                    biggest = qMax(biggest, (!ok ? -1 : num));
+                }
+            }
+        }
+    }
+    if (biggest != -1) {
+        found << stem + QString::number(biggest);
+        return true;
+    }
+
+    return false;
 }
 
 bool GNUMakefileGenerator::findLibraries()
 {
-    QStringList &l = project->values("QMAKE_LIBS");
+    QStringList &libs = project->values("QMAKE_LIBS");
 
     QList<QMakeLocalFileName> dirs;
-    {
-        QStringList &libpaths = project->values("QMAKE_LIBDIR");
-        for(QStringList::Iterator libpathit = libpaths.begin();
-            libpathit != libpaths.end(); ++libpathit)
-            dirs.append(QMakeLocalFileName((*libpathit)));
-    }
-
-    QStringList::Iterator it = l.begin();
-
-    do {
-        project->values("QMAKE_PRL_LIBS").clear();
-        bool erase = false;
-        for (; it != l.end(); erase ? (erase = false, it = l.erase(it)) : ++it) {
-            if((*it).startsWith("-L")) {
-                dirs.append(QMakeLocalFileName((*it).mid(2)));
-            } else {
-                QString stem = *it, out;
-
-                if (stem.startsWith("-l"))
-                    stem = stem.mid(2);
-
-                QString suffix;
-                if (!project->isEmpty("QMAKE_" + stem.toUpper() + "_SUFFIX"))
-                    suffix = project->first("QMAKE_" + stem.toUpper() + "_SUFFIX");
-                for (QList<QMakeLocalFileName>::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) {
-                    QString best = findBestVersion((*dir_it).local(), stem,
-                                                   QString("%1.lib").arg(suffix));
-                    if (!best.isNull()) {
-                        if (best.isEmpty()) {
-                            // we are asked to discard this lib, do it
-                            erase = true;
-                            break;
-                        }
-                        out = best.prepend("-l");
-                        break;
-                    }
+    foreach (const QString &path, project->values("QMAKE_LIBDIR"))
+        dirs.append(QMakeLocalFileName(path));
+
+    QStringList seen;
+
+    for (QStringList::Iterator it = libs.begin(); it != libs.end(); /*below*/) {
+        QString &lib = *it;
+
+        if (lib.startsWith("-L")) {
+            // this is a library path
+            dirs.append(QMakeLocalFileName((*it).mid(2)));
+            ++it;
+            continue;
+        }
+
+        // this must be a library file
+        if (lib.startsWith("-l"))
+            lib = lib.mid(2);
+
+        if (seen.contains(lib, Qt::CaseInsensitive)) {
+            // already processed, remove
+            it = libs.erase(it);
+            continue;
+        }
+
+        seen << lib;
+
+        QString suffix;
+        if (!project->isEmpty("QMAKE_" + lib.toUpper() + "_SUFFIX"))
+            suffix = project->first("QMAKE_" + lib.toUpper() + "_SUFFIX");
+
+        // try every libpath we have by now
+        bool found = false;
+        QStringList foundLibs;
+        foreach (const QMakeLocalFileName &dir, dirs) {
+            if ((found = findBestVersion(dir.local(), lib,
+                                         QString("%1.lib").arg(suffix), foundLibs)))
+                break;
+        }
+        if (!found) {
+            // assume the stem is the exact specification and use as is
+            foundLibs << lib;
+        }
+
+        if (foundLibs.isEmpty()) {
+            // circular reference detected, remove this library from the list
+            it = libs.erase(it);
+        } else {
+            // replace the library with the best found one
+            lib = foundLibs.takeFirst();
+            // this may introduce a duplicate, check that
+            bool remove = false;
+            for (QStringList::ConstIterator it2 = libs.begin(); it2 != it; ++it2)
+                if ((remove = it2->compare(lib, Qt::CaseInsensitive) == 0))
+                    break;
+            // append the dependencies
+            if (!foundLibs.empty()) {
+                int itDiff = it - libs.begin();
+                foreach (const QString &foundLib, foundLibs) {
+                    if (!libs.contains(foundLib, Qt::CaseInsensitive))
+                        libs << foundLib;
                 }
-                if (!out.isEmpty()) // We assume if it never finds it then its correct
-                    if (!project->values("QMAKE_LIBS").contains(out))
-                        (*it) = out;
+                // restore the iterator as appending invalidated it
+                it = libs.begin() + itDiff;
             }
-        }
-
-        // add the libraries from PRL and process them normally
-        QStringList l2 = project->values("QMAKE_PRL_LIBS");
-        int oldSize = l.size();
-        for (QStringList::ConstIterator it2 = l2.begin(); it2 != l2.end(); ++it2) {
-            if (!l.contains(*it2))
-                l.append(*it2);
-        }
-        it = l.begin() + oldSize;
-
-    } while(it != l.end());
+            if (remove)
+                it = libs.erase(it);
+            else
+                ++it;
+        }
+    }
 
     return true;
Index: trunk/qmake/generators/os2/gnumake.h
===================================================================
--- trunk/qmake/generators/os2/gnumake.h	(revision 369)
+++ trunk/qmake/generators/os2/gnumake.h	(revision 370)
@@ -77,5 +77,7 @@
     QString preCompHeaderOut;
 
-    QString findBestVersion(const QString &d, const QString &stem, const QString &ext);
+    bool findBestVersion(const QString &dir, const QString &stem,
+                         const QString &ext, QStringList &found);
+
     virtual bool findLibraries();
     void fixTargetExt();
