summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@digia.com>2013-12-03 16:23:31 (GMT)
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-05 20:31:27 (GMT)
commit636210a4ff3f3589fa062ea75869cfad9652cb7c (patch)
tree61bdb0fafda64bcd0eabafed60861998942290a4
parent894983bea2314c2251a10b0924259a6a58c996ef (diff)
downloadQt-636210a4ff3f3589fa062ea75869cfad9652cb7c.zip
Qt-636210a4ff3f3589fa062ea75869cfad9652cb7c.tar.gz
Qt-636210a4ff3f3589fa062ea75869cfad9652cb7c.tar.bz2
Completely bootstrap idc.
idc dynamically loads libraries depending on QtCore.dll whose static instances can then cause clashes. Task-number: QTBUG-35275 Change-Id: I48bb9c4b4ab33b1909d650458c0351c008b46ac0 Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com> (cherry picked from qtactiveqt/ab3e8e80fbd81a38039c713189b0422972e0963e)
-rw-r--r--src/tools/idc/idc.pro2
-rw-r--r--src/tools/idc/main.cpp100
2 files changed, 76 insertions, 26 deletions
diff --git a/src/tools/idc/idc.pro b/src/tools/idc/idc.pro
index f2b74e7..5907e68 100644
--- a/src/tools/idc/idc.pro
+++ b/src/tools/idc/idc.pro
@@ -6,7 +6,7 @@ build_all:!build_pass {
CONFIG += release
}
-QT = core
+include(../bootstrap/bootstrap.pri)
DESTDIR = ../../../bin
diff --git a/src/tools/idc/main.cpp b/src/tools/idc/main.cpp
index 1f76b84..4c00437 100644
--- a/src/tools/idc/main.cpp
+++ b/src/tools/idc/main.cpp
@@ -40,8 +40,8 @@
****************************************************************************/
#include <QFile>
-#include <QProcess>
-#include <QLibraryInfo>
+#include <QDir>
+#include <QScopedArrayPointer>
#include <qt_windows.h>
#include <io.h>
@@ -54,34 +54,84 @@ static QString quotePath(const QString &s)
return s;
}
+// Prepend the Qt binary directory to PATH.
+static bool prependPath()
+{
+ enum { maxEnvironmentSize = 32767 };
+ wchar_t buffer[maxEnvironmentSize];
+ if (!GetModuleFileName(NULL, buffer, maxEnvironmentSize))
+ return false;
+ wchar_t *ptr = wcsrchr(buffer, L'\\');
+ if (!ptr)
+ return false;
+ *ptr++ = L';';
+ const wchar_t pathVariable[] = L"PATH";
+ if (!GetEnvironmentVariable(pathVariable, ptr, maxEnvironmentSize - (ptr - buffer))
+ || !SetEnvironmentVariable(pathVariable, buffer)) {
+ return false;
+ }
+ return true;
+}
+
+static QString errorString(DWORD errorCode)
+{
+ wchar_t *resultW = 0;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPWSTR)&resultW, 0, NULL);
+ const QString result = QString::fromWCharArray(resultW);
+ LocalFree((HLOCAL)resultW);
+ return result;
+}
static bool runWithQtInEnvironment(const QString &cmd)
{
- QProcess proc;
-
- // prepend the qt binary directory to the path
- QStringList env = QProcess::systemEnvironment();
- for (int i=0; i<env.count(); ++i) {
- QString var = env.at(i);
- int setidx = var.indexOf(QLatin1Char('='));
- if (setidx != -1) {
- QString varname = var.left(setidx).trimmed().toUpper();
- if (varname == QLatin1String("PATH")) {
- var = var.mid(setidx + 1);
- var = QLatin1String("PATH=") +
- QLibraryInfo::location(QLibraryInfo::BinariesPath) +
- QLatin1Char(';') + var;
- env[i] = var;
- break;
- }
- }
+ enum { timeOutMs = 30000 };
+ static const bool pathSet = prependPath();
+ if (!pathSet)
+ return false;
+
+ STARTUPINFO si;
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+
+ STARTUPINFO myInfo;
+ GetStartupInfo(&myInfo);
+ si.hStdInput = myInfo.hStdInput;
+ si.hStdOutput = myInfo.hStdOutput;
+ si.hStdError = myInfo.hStdError;
+
+ PROCESS_INFORMATION pi;
+ ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+
+ QScopedArrayPointer<wchar_t> commandLineW(new wchar_t[cmd.size() + 1]);
+ cmd.toWCharArray(commandLineW.data());
+ commandLineW[cmd.size()] = 0;
+ if (!CreateProcessW(0, commandLineW.data(), 0, 0, /* InheritHandles */ TRUE, 0, 0, 0, &si, &pi)) {
+ fprintf(stderr, "Unable to execute \"%s\": %s\n", qPrintable(cmd),
+ qPrintable(errorString(GetLastError())));
+ return false;
}
- proc.setEnvironment(env);
- proc.start(cmd);
- proc.waitForFinished(-1);
-
- return (proc.exitCode() == 0);
+ DWORD exitCode = 1;
+ switch (WaitForSingleObject(pi.hProcess, timeOutMs)) {
+ case WAIT_OBJECT_0:
+ GetExitCodeProcess(pi.hProcess, &exitCode);
+ break;
+ case WAIT_TIMEOUT:
+ fprintf(stderr, "Timed out after %d ms out waiting for \"%s\".\n",
+ int(timeOutMs), qPrintable(cmd));
+ TerminateProcess(pi.hProcess, 1);
+ break;
+ default:
+ fprintf(stderr, "Error waiting for \"%s\": %s\n",
+ qPrintable(cmd), qPrintable(errorString(GetLastError())));
+ TerminateProcess(pi.hProcess, 1);
+ break;
+ }
+ CloseHandle(pi.hThread);
+ CloseHandle(pi.hProcess);
+ return exitCode == 0;
}
static bool attachTypeLibrary(const QString &applicationName, int resource, const QByteArray &data, QString *errorMessage)