summaryrefslogtreecommitdiffstats
path: root/src/libs/installer/qtpatchoperation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/installer/qtpatchoperation.cpp')
-rw-r--r--src/libs/installer/qtpatchoperation.cpp186
1 files changed, 149 insertions, 37 deletions
diff --git a/src/libs/installer/qtpatchoperation.cpp b/src/libs/installer/qtpatchoperation.cpp
index 9699219ec..e9fbb65c5 100644
--- a/src/libs/installer/qtpatchoperation.cpp
+++ b/src/libs/installer/qtpatchoperation.cpp
@@ -111,7 +111,10 @@ static QHash<QByteArray, QByteArray> generatePatchValueHash(const QByteArray &ne
replaceHash.insert( QByteArray("qt_trnspath=%1").replace("%1", oldValue),
QByteArray("qt_trnspath=%1/translations").replace("%1/", newQtPath + nativeSeperator));
- // This must not be patched. Commenting out to fix QTSDK-429
+ // This must not be patched!
+ // On desktop there should be a correct default path (for example "/etc/xdg"),
+ // but on some other targets you need to use "-sysconfdir </your/default/config/path"
+ // while building Qt to get a correct QT_INSTALL_CONFIGURATION value
// oldValue = qmakeValueHash.value(QLatin1String("QT_INSTALL_CONFIGURATION"));
// replaceMap.insert( QByteArray("qt_stngpath=%1").replace("%1", oldValue),
// QByteArray("qt_stngpath=%1").replace("%1", newQtPath));
@@ -142,6 +145,10 @@ static QHash<QByteArray, QByteArray> generatePatchValueHash(const QByteArray &ne
replaceHash.insert(QByteArray("qt_hdatpath=%1").replace("%1", oldValue),
QByteArray("qt_hdatpath=%1/").replace("%1/", newQtPath));
+ oldValue = qmakeValueHash.value(QLatin1String("QT_HOST_LIBS"));
+ replaceHash.insert(QByteArray("qt_hlibpath=%1").replace("%1", oldValue),
+ QByteArray("qt_hlibpath=%1/lib").replace("%1/", newQtPath + nativeSeperator));
+
return replaceHash;
}
@@ -160,16 +167,34 @@ bool QtPatchOperation::performOperation()
// 1. type
// 2. new/target qtpath
// 3. version if greather Qt4
+ // optional QmakeOutputInstallerKey=<used_installer_value>
// the possible 2 argument case is here to support old syntax
- if (arguments().count() < 2 || arguments().count() > 3) {
+ if (arguments().count() < 2 && arguments().count() > 4) {
setError(InvalidArguments);
setErrorString(tr("Invalid arguments in %0: %1 arguments given, %2 expected%3.")
- .arg(name()).arg(arguments().count()).arg(tr("exactly 3"), QLatin1String("")));
+ .arg(name()).arg(arguments().count()).arg(tr("3 or 4"), QLatin1String("")));
return false;
}
- QString type = arguments().at(0);
+ QStringList args = arguments();
+ QString qmakeOutputInstallerKey;
+ QStringList filteredQmakeOutputInstallerKey = args.filter(QLatin1String("QmakeOutputInstallerKey="),
+ Qt::CaseInsensitive);
+ PackageManagerCore *const core = value(QLatin1String("installer")).value<PackageManagerCore*>();
+ if (!filteredQmakeOutputInstallerKey.isEmpty()) {
+ if (!core) {
+ setError(UserDefinedError);
+ setErrorString(tr("Needed installer object in \"%1\" operation is empty.").arg(name()));
+ return false;
+ }
+ QString qmakeOutputInstallerKeyArgument = filteredQmakeOutputInstallerKey.at(0);
+ qmakeOutputInstallerKey = qmakeOutputInstallerKeyArgument;
+ qmakeOutputInstallerKey.replace(QLatin1String("QmakeOutputInstallerKey="), QString(), Qt::CaseInsensitive);
+ args.removeAll(qmakeOutputInstallerKeyArgument);
+ }
+
+ QString type = args.at(0);
bool isPlatformSupported = type.contains(QLatin1String("linux"), Qt::CaseInsensitive)
|| type.contains(QLatin1String("windows"), Qt::CaseInsensitive)
|| type.contains(QLatin1String("mac"), Qt::CaseInsensitive);
@@ -180,31 +205,42 @@ bool QtPatchOperation::performOperation()
return false;
}
- const QString newQtPathStr = QDir::toNativeSeparators(arguments().at(1));
- const QByteArray newQtPath = newQtPathStr.toUtf8();
+ if (core && !filteredQmakeOutputInstallerKey.isEmpty() && core->value(qmakeOutputInstallerKey).isEmpty()) {
+ setError(UserDefinedError);
+ setErrorString(tr("Could not find the needed QmakeOutputInstallerKey(%1) value on the installer "
+ "object. The ConsumeOutput operation on the valid qmake needs to be called first.").arg(
+ qmakeOutputInstallerKey));
+ return false;
+ }
+ const QString newQtPathStr = QDir::toNativeSeparators(args.at(1));
+ const QByteArray newQtPath = newQtPathStr.toUtf8();
QString qmakePath = QString::fromUtf8(newQtPath) + QLatin1String("/bin/qmake");
#ifdef Q_OS_WIN
qmakePath = qmakePath + QLatin1String(".exe");
#endif
- if (!QFile::exists(qmakePath)) {
- setError(UserDefinedError);
- setErrorString(tr("QMake from the current Qt version \n(%1)is not existing. Please file a bugreport "
- "with this dialog at https://bugreports.qt-project.org.").arg(QDir::toNativeSeparators(qmakePath)));
- return false;
+ QHash<QString, QByteArray> qmakeValueHash;
+ if (core && !core->value(qmakeOutputInstallerKey).isEmpty()) {
+ qmakeValueHash = QtPatch::readQmakeOutput(core->value(qmakeOutputInstallerKey).toLatin1());
+ } else {
+ if (!QFile::exists(qmakePath)) {
+ setError(UserDefinedError);
+ setErrorString(tr("QMake from the current Qt version \n(%1)is not existing. Please file a bugreport "
+ "with this dialog at https://bugreports.qt-project.org.").arg(QDir::toNativeSeparators(qmakePath)));
+ return false;
+ }
+ QByteArray qmakeOutput;
+ qmakeValueHash = QtPatch::qmakeValues(qmakePath, &qmakeOutput);
+ if (qmakeValueHash.isEmpty()) {
+ setError(UserDefinedError);
+ setErrorString(tr("The output of \n%1 -query\nis not parseable. Please file a bugreport with this "
+ "dialog https://bugreports.qt-project.org.\noutput: \"%2\"").arg(QDir::toNativeSeparators(qmakePath),
+ QString::fromUtf8(qmakeOutput)));
+ return false;
+ }
}
- QByteArray qmakeOutput;
- QHash<QString, QByteArray> qmakeValueHash = QtPatch::qmakeValues(qmakePath, &qmakeOutput);
-
- if (qmakeValueHash.isEmpty()) {
- setError(UserDefinedError);
- setErrorString(tr("The output of \n%1 -query\nis not parseable. Please file a bugreport with this "
- "dialog https://bugreports.qt-project.org.\noutput: \"%2\"").arg(QDir::toNativeSeparators(qmakePath),
- QString::fromUtf8(qmakeOutput)));
- return false;
- }
const QByteArray oldQtPath = qmakeValueHash.value(QLatin1String("QT_INSTALL_PREFIX"));
bool oldQtPathFromQMakeIsEmpty = oldQtPath.isEmpty();
@@ -218,19 +254,97 @@ bool QtPatchOperation::performOperation()
}
#ifdef Q_OS_MAC
- // just try to patch here at the beginning to keep the unpatched qmake if mac install_names_tool fails
- MacReplaceInstallNamesOperation operation;
- operation.setArguments(QStringList()
- //can not use the old path which is wrong in the webkit case
- //<< QString::fromUtf8(oldQtPath)
- << QLatin1String("/lib/Qt") // search string
- << newQtPathStr + QLatin1String("/lib/Qt") //replace string
- << newQtPathStr //where
- );
- if (!operation.performOperation()) {
- setError(operation.error());
- setErrorString(operation.errorString());
- return false;
+ // looking for /lib/Qt wasn't enough for all libs and frameworks,
+ // at the Qt4 case we had for example: /lib/libQtCLucene* and /lib/phonon*
+ // so now we find every possible replace string inside dynlib dependencies
+ // and we reduce it to few as possible search strings
+ QStringList possibleSearchStringList;
+ QDirIterator dirIterator(newQtPathStr + QLatin1String("/lib/"));
+ while (dirIterator.hasNext()) {
+ const QString possibleSearchString = QString(dirIterator.next()).remove(newQtPathStr);
+ const QFileInfo fileInfo = dirIterator.fileInfo();
+ if (fileInfo.isSymLink())
+ continue;
+ if (fileInfo.isDir()) {
+ if (possibleSearchString.endsWith(QLatin1String(".framework")))
+ possibleSearchStringList.append(possibleSearchString);
+ else
+ continue;
+ }
+ if (possibleSearchString.endsWith(QLatin1String(".dylib")))
+ possibleSearchStringList.append(possibleSearchString);
+ }
+
+ // now we have this in possibleSearchStringList at Qt 4.8.6
+// "/lib/libQtCLucene.4.8.6.dylib"
+// "/lib/libQtCLucene_debug.4.8.6.dylib"
+// "/lib/phonon.framework"
+// "/lib/QtCore.framework"
+// "/lib/QtDeclarative.framework"
+// "/lib/QtDesigner.framework"
+// "/lib/QtDesignerComponents.framework"
+// "/lib/QtGui.framework"
+// "/lib/QtHelp.framework"
+// "/lib/QtMultimedia.framework"
+// "/lib/QtNetwork.framework"
+// "/lib/QtOpenGL.framework"
+// "/lib/QtScript.framework"
+// "/lib/QtScriptTools.framework"
+// "/lib/QtSql.framework"
+// "/lib/QtSvg.framework"
+// "/lib/QtTest.framework"
+// "/lib/QtWebKit.framework"
+// "/lib/QtXml.framework"
+// "/lib/QtXmlPatterns.framework"
+
+ // so then we reduce the possible filter strings as much as possible
+ QStringList searchStringList;
+
+ // as the minimal search string use the subdirector lib + one letter from the name
+ int minFilterLength = QString(QLatin1String("/lib/")).length() + 1;
+
+ while (!possibleSearchStringList.isEmpty()) {
+ QString firstSearchString = possibleSearchStringList.first();
+ int filterLength = minFilterLength;
+ int lastFilterCount = 0;
+ QString lastFilterString;
+ // now filter as long as we find something more then 1
+ for (; filterLength < firstSearchString.length(); ++filterLength) {
+ QString filterString(firstSearchString.left(filterLength));
+ QStringList filteredStringList(possibleSearchStringList.filter(filterString));
+ // found a valid filter
+ if (lastFilterCount > filteredStringList.count()) {
+ possibleSearchStringList = QList<QString>::fromSet(possibleSearchStringList.toSet() -
+ possibleSearchStringList.filter(lastFilterString).toSet());
+ searchStringList.append(lastFilterString);
+ break;
+ } else if (lastFilterCount == 1){ //in case there is only one we can use the complete name
+ possibleSearchStringList = QList<QString>::fromSet(possibleSearchStringList.toSet() -
+ possibleSearchStringList.filter(firstSearchString).toSet());
+ searchStringList.append(firstSearchString);
+ break;
+ } else {
+ lastFilterCount = possibleSearchStringList.filter(filterString).count();
+ lastFilterString = filterString;
+ }
+ }
+ }
+
+ // in the tested Qt 4.8.6 case we have searchStringList ("/lib/libQtCLucene", "/lib/Qt", "/lib/phonon")
+ foreach (const QString &searchString, searchStringList) {
+ MacReplaceInstallNamesOperation operation;
+ operation.setArguments(QStringList()
+ //can not use the old path which is wrong in the webkit case
+ //<< QString::fromUtf8(oldQtPath)
+ << searchString
+ << newQtPathStr + searchString //replace string
+ << newQtPathStr //where
+ );
+ if (!operation.performOperation()) {
+ setError(operation.error());
+ setErrorString(operation.errorString());
+ return false;
+ }
}
#endif
@@ -239,13 +353,11 @@ bool QtPatchOperation::performOperation()
fileName = QString::fromLatin1(":/files-to-patch-windows");
else if (type == QLatin1String("linux"))
fileName = QString::fromLatin1(":/files-to-patch-linux");
- else if (type == QLatin1String("linux-emb-arm"))
- fileName = QString::fromLatin1(":/files-to-patch-linux-emb-arm");
else if (type == QLatin1String("mac"))
fileName = QString::fromLatin1(":/files-to-patch-macx");
QFile patchFileListFile(fileName);
- QString version = arguments().value(2).toLower();
+ QString version = args.value(2).toLower();
if (!version.isEmpty())
patchFileListFile.setFileName(fileName + QLatin1Char('-') + version);