diff options
author | Bradley T. Hughes <bradley.hughes@nokia.com> | 2012-02-14 10:01:17 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-03-13 12:27:44 +0100 |
commit | ba6952b28d17b6b34f65510be645e414fa1ef6a2 (patch) | |
tree | 29dbe86906cb375fa58d7cc18a11b25a6a48dae2 /tools | |
parent | 6d85d77a5def22ef8a50505f3c7634146db73421 (diff) | |
download | qtbase-ba6952b28d17b6b34f65510be645e414fa1ef6a2.tar.gz |
Remove -arch argument and #define QT_ARCH from configures
Do not try to detect the host or target architectures using uname or
similar, and do not override with the -arch or -host-arch configure
arguments. The configures will still accept the -arch and -host-arch
arguments, but it ignores them and instead outputs a warning stating
that these arguments are obsolete and should not be used.
Set QT_ARCH and QT_HOST_ARCH qconfig.pri variables based on the compiler
target. This is done by running qmake (twice when cross-compiling) on
config.tests/arch/arch.pro, which preprocesses a file that contains all
knowns processors.
On Windows, configure.exe has never run any config.tests before, and
does not currently have a function to run a program and capture its
output. Use _popen() to accomplish this (as qmake does for its system()
function). This needs to be done after qmake is built, as does the
mkspecs/qconfig.pri generation. As a side effect, the configure steps
have been slightly re-ordered, but the overall result is the same. The
displayConfig() call is moved to just before generating Makefiles, so
that it can show the detected architecture(s).
Change-Id: I77666c77a93b48848f87648d08e79a42f721683f
Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/configure/configureapp.cpp | 121 | ||||
-rw-r--r-- | tools/configure/configureapp.h | 2 | ||||
-rw-r--r-- | tools/configure/environment.cpp | 22 | ||||
-rw-r--r-- | tools/configure/environment.h | 1 | ||||
-rw-r--r-- | tools/configure/main.cpp | 10 |
5 files changed, 130 insertions, 26 deletions
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 8423953d7d..165dc0a043 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -188,7 +188,6 @@ Configure::Configure(int& argc, char** argv) dictionary[ "QMAKESPEC_FROM" ] = "env"; } - dictionary[ "ARCHITECTURE" ] = "windows"; dictionary[ "QCONFIG" ] = "full"; dictionary[ "EMBEDDED" ] = "no"; dictionary[ "BUILD_QMAKE" ] = "yes"; @@ -470,11 +469,7 @@ void Configure::parseCmdLine() ++i; if (i == argCount) break; - dictionary[ "ARCHITECTURE" ] = configCmdLine.at(i); - if (configCmdLine.at(i) == "boundschecker") { - dictionary[ "ARCHITECTURE" ] = "generic"; // Boundschecker uses the generic arch, - qtConfig += "boundschecker"; // but also needs this CONFIG option - } + dictionary["OBSOLETE_ARCH_ARG"] = "yes"; } else if (configCmdLine.at(i) == "-embedded") { dictionary[ "EMBEDDED" ] = "yes"; } else if (configCmdLine.at(i) == "-xplatform") { @@ -1365,7 +1360,6 @@ void Configure::applySpecSpecifics() dictionary[ "STL" ] = "no"; dictionary[ "EXCEPTIONS" ] = "no"; dictionary[ "RTTI" ] = "no"; - dictionary[ "ARCHITECTURE" ] = "windowsce"; dictionary[ "3DNOW" ] = "no"; dictionary[ "SSE" ] = "no"; dictionary[ "SSE2" ] = "no"; @@ -1451,7 +1445,7 @@ bool Configure::displayHelp() "[-no-fast] [-fast] [-no-exceptions] [-exceptions]\n" "[-no-accessibility] [-accessibility] [-no-rtti] [-rtti]\n" "[-no-stl] [-stl] [-no-sql-<driver>] [-qt-sql-<driver>]\n" - "[-plugin-sql-<driver>] [-system-sqlite] [-arch <arch>]\n" + "[-plugin-sql-<driver>] [-system-sqlite]\n" "[-D <define>] [-I <includepath>] [-L <librarypath>]\n" "[-help] [-no-dsp] [-dsp] [-no-vcproj] [-vcproj]\n" "[-no-qmake] [-qmake] [-dont-process] [-process]\n" @@ -1623,13 +1617,6 @@ bool Configure::displayHelp() desc("DIRECTWRITE", "no", "-no-directwrite", "Do not build support for DirectWrite font rendering"); desc("DIRECTWRITE", "yes", "-directwrite", "Build support for DirectWrite font rendering (experimental, requires DirectWrite availability on target systems, e.g. Windows Vista with Platform Update, Windows 7, etc.)"); - desc( "-arch <arch>", "Specify an architecture.\n" - "Available values for <arch>:"); - desc("ARCHITECTURE","windows", "", " windows", ' '); - desc("ARCHITECTURE","windowsce", "", " windowsce", ' '); - desc("ARCHITECTURE","boundschecker", "", " boundschecker", ' '); - desc("ARCHITECTURE","generic", "", " generic\n", ' '); - desc( "-no-style-<style>", "Disable <style> entirely."); desc( "-qt-style-<style>", "Enable <style> in the Qt Library.\nAvailable styles: "); @@ -1846,13 +1833,13 @@ bool Configure::checkAvailability(const QString &part) else if (part == "SQL_IBASE") available = findFile("ibase.h") && (findFile("gds32_ms.lib") || findFile("gds32.lib")); else if (part == "IWMMXT") - available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); + available = (dictionary.value("XQMAKESPEC").startsWith("wince")); else if (part == "OPENGL_ES_CM") - available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); + available = (dictionary.value("XQMAKESPEC").startsWith("wince")); else if (part == "OPENGL_ES_2") - available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); + available = (dictionary.value("XQMAKESPEC").startsWith("wince")); else if (part == "DIRECTSHOW") - available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); + available = (dictionary.value("XQMAKESPEC").startsWith("wince")); else if (part == "SSE2") available = (dictionary.value("QMAKESPEC") != "win32-msvc"); else if (part == "3DNOW") @@ -1866,7 +1853,7 @@ bool Configure::checkAvailability(const QString &part) else if (part == "CETEST") { QString rapiHeader = locateFile("rapi.h"); QString rapiLib = locateFile("rapi.lib"); - available = (dictionary[ "ARCHITECTURE" ] == "windowsce") && !rapiHeader.isEmpty() && !rapiLib.isEmpty(); + available = (dictionary.value("XQMAKESPEC").startsWith("wince")) && !rapiHeader.isEmpty() && !rapiLib.isEmpty(); if (available) { dictionary[ "QT_CE_RAPI_INC" ] += QLatin1String("\"") + rapiHeader + QLatin1String("\""); dictionary[ "QT_CE_RAPI_LIB" ] += QLatin1String("\"") + rapiLib + QLatin1String("\""); @@ -2484,7 +2471,6 @@ void Configure::generateCachefile() moduleStream << "QMAKESPEC = " << escapeSeparators(mkspec_path) << endl; else moduleStream << "QMAKESPEC = " << fixSeparators(targetSpec, true) << endl; - moduleStream << "ARCH = " << dictionary[ "ARCHITECTURE" ] << endl; if (dictionary["QT_EDITION"] != "QT_EDITION_OPENSOURCE") moduleStream << "DEFINES *= QT_EDITION=QT_EDITION_DESKTOP" << endl; @@ -2528,7 +2514,83 @@ void Configure::generateCachefile() moduleStream.flush(); moduleFile.close(); } +} + +/* + Runs qmake on config.tests/arch/arch.pro, which will detect the target arch + for the compiler we are using +*/ +void Configure::detectArch() +{ + QString oldpwd = QDir::currentPath(); + + QString newpwd = fixSeparators(QString("%1/config.tests/arch").arg(buildPath)); + if (!QDir().exists(newpwd) && !QDir().mkpath(newpwd)) { + cout << "Failed to create directory " << qPrintable(newpwd) << endl; + dictionary["DONE"] = "error"; + return; + } + if (!QDir::setCurrent(newpwd)) { + cout << "Failed to change working directory to " << qPrintable(newpwd) << endl; + dictionary["DONE"] = "error"; + return; + } + + QList<QPair<QString, QString> > qmakespecs; + if (dictionary.contains("XQMAKESPEC")) + qmakespecs << qMakePair(QString("XQMAKESPEC"), QString("QT_ARCH")); + qmakespecs << qMakePair(QString("QMAKESPEC"), QString("QT_HOST_ARCH")); + + for (int i = 0; i < qmakespecs.count(); ++i) { + const QPair<QString, QString> &pair = qmakespecs.at(i); + QString qmakespec = dictionary.value(pair.first); + QString key = pair.second; + + QString command = + fixSeparators(QString("%1/bin/qmake.exe -spec %2 %3/config.tests/arch/arch.pro -o %4/Makefile.unused 2>&1") + .arg(buildPath, qmakespec, sourcePath, newpwd)); + QString output = Environment::execute(command); + if (output.isEmpty()) + continue; + + // strip everything up to and including 'Project MESSAGE: ' + QString ProjectMESSAGE = QStringLiteral("Project MESSAGE: "); + int at = output.indexOf(ProjectMESSAGE); + if (at != -1) + output = output.mid(at + ProjectMESSAGE.length()); + + // strip lines beginning with a # + at = 0; + while ((at = output.indexOf('#', at)) != -1) { + if (at > 0 && output.at(at - 1) != '\n') { + // # isnt' at the beginning of a line, skip it + ++at; + continue; + } + + int eol = output.indexOf('\n', at); + if (eol == -1) { + // end of string + output.remove(at, output.length() - at); + break; + } + + output.remove(at, eol - at + 1); + } + + dictionary[key] = output.simplified(); + } + + if (!dictionary.contains("QT_HOST_ARCH")) + dictionary["QT_HOST_ARCH"] = "unknown"; + if (!dictionary.contains("QT_ARCH")) + dictionary["QT_ARCH"] = dictionary["QT_HOST_ARCH"]; + + QDir::setCurrent(oldpwd); +} +void Configure::generateQConfigPri() +{ // Generate qconfig.pri QFile configFile(dictionary[ "QT_BUILD_TREE" ] + "/mkspecs/qconfig.pri"); if (configFile.open(QFile::WriteOnly | QFile::Text)) { // Truncates any existing file. @@ -2574,7 +2636,8 @@ void Configure::generateCachefile() configStream << "directwrite"; configStream << endl; - configStream << "QT_ARCH = " << dictionary[ "ARCHITECTURE" ] << endl; + configStream << "QT_ARCH = " << dictionary["QT_ARCH"] << endl; + configStream << "QT_HOST_ARCH = " << dictionary["QT_HOST_ARCH"] << endl; if (dictionary["QT_EDITION"].contains("OPENSOURCE")) configStream << "QT_EDITION = " << QLatin1String("OpenSource") << endl; else @@ -2712,7 +2775,6 @@ void Configure::generateConfigfiles() tmpStream << endl << "#define Q_WS_QPA" << endl; tmpStream << endl << "// Compile time features" << endl; - tmpStream << "#define QT_ARCH_" << dictionary["ARCHITECTURE"].toUpper() << endl; QStringList qconfigList; if (dictionary["STL"] == "no") qconfigList += "QT_NO_STL"; @@ -2958,7 +3020,8 @@ void Configure::displayConfig() cout << "QMAKESPEC..................." << dictionary[ "XQMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl; else cout << "QMAKESPEC..................." << dictionary[ "QMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl; - cout << "Architecture................" << dictionary[ "ARCHITECTURE" ] << endl; + cout << "Architecture................" << dictionary["QT_ARCH"] << endl; + cout << "Host Architecture..........." << dictionary["QT_HOST_ARCH"] << endl; cout << "Maketool...................." << dictionary[ "MAKE" ] << endl; cout << "Debug symbols..............." << (dictionary[ "BUILD" ] == "debug" ? "yes" : "no") << endl; cout << "Link Time Code Generation..." << dictionary[ "LTCG" ] << endl; @@ -3071,6 +3134,16 @@ void Configure::displayConfig() << "option was ignored. Qt will be built using the " << which_zlib << "zlib" << endl; } + if (dictionary["OBSOLETE_ARCH_ARG"] == "yes") { + cout << endl + << "NOTE: The -arch option is obsolete." << endl + << endl + << "Qt now detects the target and host architectures based on compiler" << endl + << "output. Qt will be built using " << dictionary["QT_ARCH"] << " for the target architecture" << endl + << "and " << dictionary["QT_HOST_ARCH"] << " for the host architecture (note that these two" << endl + << "will be the same unless you are cross-compiling)." << endl + << endl; + } } #endif diff --git a/tools/configure/configureapp.h b/tools/configure/configureapp.h index 58544b5041..65aa0cbed9 100644 --- a/tools/configure/configureapp.h +++ b/tools/configure/configureapp.h @@ -81,6 +81,8 @@ public: #if !defined(EVAL) bool copySpec(const char *name, const char *pfx, const QString &spec); void generateConfigfiles(); + void detectArch(); + void generateQConfigPri(); #endif void showSummary(); void findProjects( const QString& dirName ); diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp index b9af9eca8f..ab622b576a 100644 --- a/tools/configure/environment.cpp +++ b/tools/configure/environment.cpp @@ -422,6 +422,28 @@ int Environment::execute(QStringList arguments, const QStringList &additionalEnv } /*! + Executes \a command with _popen() and returns the stdout of the command. + + Taken from qmake's system() command. +*/ +QString Environment::execute(const QString &command) +{ + QString output; + FILE *proc = _popen(command.toLatin1().constData(), "r"); + char buff[256]; + while (proc && !feof(proc)) { + int read_in = int(fread(buff, 1, 255, proc)); + if (!read_in) + break; + buff[read_in] = '\0'; + output += buff; + } + if (proc) + _pclose(proc); + return output; +} + +/*! Copies the \a srcDir contents into \a destDir. If \a includeSrcDir is not empty, any files with 'h', 'prf', or 'conf' suffixes diff --git a/tools/configure/environment.h b/tools/configure/environment.h index e5f52b47b6..ec7cb635e1 100644 --- a/tools/configure/environment.h +++ b/tools/configure/environment.h @@ -65,6 +65,7 @@ public: static bool detectExecutable(const QString &executable); static int execute(QStringList arguments, const QStringList &additionalEnv, const QStringList &removeEnv); + static QString execute(const QString &command); static bool cpdir(const QString &srcDir, const QString &destDir, const QString &includeSrcDir = QString()); diff --git a/tools/configure/main.cpp b/tools/configure/main.cpp index 51abd7aa82..08cd691875 100644 --- a/tools/configure/main.cpp +++ b/tools/configure/main.cpp @@ -87,11 +87,17 @@ int runConfigure( int argc, char** argv ) if( !app.isDone() ) app.generateConfigfiles(); if( !app.isDone() ) - app.displayConfig(); - if( !app.isDone() ) app.generateHeaders(); if( !app.isDone() ) app.buildQmake(); + // must be done after buildQmake() + if (!app.isDone()) + app.detectArch(); + // must be done after detectArch() + if (!app.isDone()) + app.generateQConfigPri(); + if (!app.isDone()) + app.displayConfig(); #endif if( !app.isDone() ) app.generateMakefiles(); |