summaryrefslogtreecommitdiffstats
path: root/tools/configure
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2012-02-14 10:01:17 +0100
committerQt by Nokia <qt-info@nokia.com>2012-03-13 12:27:44 +0100
commitba6952b28d17b6b34f65510be645e414fa1ef6a2 (patch)
tree29dbe86906cb375fa58d7cc18a11b25a6a48dae2 /tools/configure
parent6d85d77a5def22ef8a50505f3c7634146db73421 (diff)
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/configure')
-rw-r--r--tools/configure/configureapp.cpp121
-rw-r--r--tools/configure/configureapp.h2
-rw-r--r--tools/configure/environment.cpp22
-rw-r--r--tools/configure/environment.h1
-rw-r--r--tools/configure/main.cpp10
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();