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 | |
parent | 6d85d77a5def22ef8a50505f3c7634146db73421 (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>
-rw-r--r-- | config.tests/arch/arch.cpp | 70 | ||||
-rw-r--r-- | config.tests/arch/arch.pro | 7 | ||||
-rwxr-xr-x | configure | 299 | ||||
-rw-r--r-- | src/corelib/global/qprocessordetection.h | 4 | ||||
-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 |
9 files changed, 297 insertions, 239 deletions
diff --git a/config.tests/arch/arch.cpp b/config.tests/arch/arch.cpp new file mode 100644 index 0000000000..0c12565f7c --- /dev/null +++ b/config.tests/arch/arch.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the FOO module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// NOTE: This file is not meant to be compiled, only preprocessed. +#include "../../src/corelib/global/qprocessordetection.h" +#if defined(Q_PROCESSOR_ALPHA) +alpha +#elif defined(Q_PROCESSOR_ARM) +arm +#elif defined(Q_PROCESSOR_AVR32) +avr32 +#elif defined(Q_PROCESSOR_BLACKFIN) +bfin +#elif defined(Q_PROCESSOR_X86_32) +i386 +#elif defined(Q_PROCESSOR_X86_64) +x86_64 +#elif defined(Q_PROCESSOR_IA64) +ia64 +#elif defined(Q_PROCESSOR_MIPS) +mips +#elif defined(Q_PROCESSOR_POWER) +power +#elif defined(Q_PROCESSOR_S390) +s390 +#elif defined(Q_PROCESSOR_SH) +sh +#elif defined(Q_PROCESSOR_SPARC) +sparc +#else +unknown +#endif diff --git a/config.tests/arch/arch.pro b/config.tests/arch/arch.pro new file mode 100644 index 0000000000..108f262a55 --- /dev/null +++ b/config.tests/arch/arch.pro @@ -0,0 +1,7 @@ +CONFIG -= qt debug_and_release +# Detect target by preprocessing a file that uses Q_PROCESSOR_* macros from qprocessordetection.h +COMMAND = $$QMAKE_CXX $$QMAKE_CXXFLAGS -E $$PWD/arch.cpp +# 'false' as second argument to system() prevents qmake from stripping newlines +COMPILER_ARCH = $$system($$COMMAND, false) +# Message back to configure so that it can set QT_ARCH and QT_HOST_ARCH +message($$COMPILER_ARCH) @@ -693,8 +693,13 @@ CFG_V8SNAPSHOT=auto CFG_DECLARATIVE_DEBUG=yes CFG_JAVASCRIPTCORE_JIT=auto +# Target architecture CFG_ARCH= +# Host architecture, same as CFG_ARCH when not cross-compiling CFG_HOST_ARCH= +# Set when the -arch or -host-arch arguments are used +OPT_OBSOLETE_HOST_ARG=no + CFG_USE_GNUMAKE=no CFG_IM=yes CFG_XINPUT2=auto @@ -742,7 +747,6 @@ CFG_GETIFADDRS=auto CFG_INOTIFY=auto CFG_RPATH=yes CFG_FRAMEWORK=auto -CFG_MAC_ARCHS= MAC_CONFIG_TEST_COMMANDLINE= # used to make the configure tests run with the correct arch's and SDK settings CFG_MAC_DWARF2=auto CFG_MAC_HARFBUZZ=no @@ -1201,17 +1205,8 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; - arch) - # if this is a Mac then "windows" probably means - # we are cross-compiling for MinGW - if [ "$BUILD_ON_MAC" = "yes" ] && [ "$VAL" != "windows" ]; then - CFG_MAC_ARCHS="$CFG_MAC_ARCHS $VAL" - else - CFG_ARCH=$VAL - fi - ;; - host-arch) - CFG_HOST_ARCH=$VAL + arch|host-arch) + OPT_OBSOLETE_HOST_ARG=yes ;; harfbuzz) if [ "$BUILD_ON_MAC" = "yes" ] && [ "$VAL" = "yes" ]; then @@ -2420,13 +2415,6 @@ if [ "$UNAME_SYSTEM" = "SunOS" ]; then fi fi -#------------------------------------------------------------------------------- -# determine the system architecture -#------------------------------------------------------------------------------- -if [ "$OPT_VERBOSE" = "yes" ]; then - echo "Determining system architecture... ($UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_MACHINE)" -fi - if [ "$CFG_RTOS_ENABLED" = "no" ]; then case `basename "$XPLATFORM"` in qnx-* | vxworks-*) @@ -2441,153 +2429,6 @@ if [ "$CFG_RTOS_ENABLED" = "no" ]; then esac fi -if [ -z "${CFG_HOST_ARCH}" ]; then - case "$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_MACHINE" in - GNU:*:*) - CFG_HOST_ARCH=`echo ${UNAME_MACHINE} | sed -e 's,[-/].*$,,'` - case "$CFG_HOST_ARCH" in - i?86) - CFG_HOST_ARCH=i386 - ;; - esac - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " GNU/Hurd ($CFG_HOST_ARCH)" - fi - ;; - IRIX*:*:*) - CFG_HOST_ARCH=`uname -p` - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " SGI ($CFG_HOST_ARCH)" - fi - ;; - SunOS:5*:*) - case "$UNAME_MACHINE" in - sun4u*|sun4v*) - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " Sun SPARC (sparc)" - fi - CFG_HOST_ARCH=sparc - ;; - i86pc) - case "$PLATFORM" in - *-64*) - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " 64-bit AMD 80x86 (x86_64)" - fi - CFG_HOST_ARCH=x86_64 - ;; - *) - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " 32-bit Intel 80x86 (i386)" - fi - CFG_HOST_ARCH=i386 - ;; - esac - esac - ;; - AIX:*:00????????00) - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " 64-bit IBM PowerPC (powerpc)" - fi - CFG_HOST_ARCH=powerpc - ;; - HP-UX:*:9000*) - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " HP PA-RISC (parisc)" - fi - CFG_HOST_ARCH=parisc - ;; - *:*:i?86) - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " 32-bit Intel 80x86 (i386)" - fi - CFG_HOST_ARCH=i386 - ;; - *:*:x86_64|*:*:amd64) - if [ "$PLATFORM" = "linux-g++-32" -o "$PLATFORM" = "linux-icc-32" ]; then - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " 32 bit on 64-bit AMD 80x86 (i386)" - fi - CFG_HOST_ARCH=i386 - else - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " 64-bit AMD 80x86 (x86_64)" - fi - CFG_HOST_ARCH=x86_64 - fi - ;; - *:*:ppc) - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " 32-bit PowerPC (powerpc)" - fi - CFG_HOST_ARCH=powerpc - ;; - *:*:ppc64) - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " 64-bit PowerPC (powerpc)" - fi - CFG_HOST_ARCH=powerpc - ;; - *:*:s390*) - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " IBM S/390 (s390)" - fi - CFG_HOST_ARCH=s390 - ;; - *:*:arm*) - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " ARM (arm)" - fi - CFG_HOST_ARCH=arm - ;; - Linux:*:sparc*) - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " Linux on SPARC" - fi - CFG_HOST_ARCH=sparc - ;; - QNX:*:*) - case "$UNAME_MACHINE" in - x86pc) - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " QNX on Intel 80x86 (i386)" - fi - CFG_HOST_ARCH=i386 - ;; - esac - ;; - *:*:*) - if [ "$OPT_VERBOSE" = "yes" ]; then - echo " Trying '$UNAME_MACHINE'..." - fi - CFG_HOST_ARCH="$UNAME_MACHINE" - ;; - esac -fi - -if [ "$XPLATFORM_MINGW" = "yes" ]; then - [ -z "$CFG_ARCH" ] && CFG_ARCH="windows" -elif [ "$PLATFORM_MAC" = "yes" ] || [ -z "$CFG_ARCH" ]; then - CFG_ARCH=$CFG_HOST_ARCH -fi - -# for compatibility -COMPAT_ARCH= -case "$CFG_ARCH" in -arm*) - # previously, armv6 was a different arch - CFG_ARCH=arm - COMPAT_ARCH=armv6 - ;; -esac - -if [ "$OPT_VERBOSE" = "yes" ]; then - echo "System architecture: '$CFG_ARCH'" - if [ "$PLATFORM_QPA" = "yes" ]; then - echo "Host architecture: '$CFG_HOST_ARCH'" - fi -fi - #------------------------------------------------------------------------------- # tests that don't need qmake (must be run before displaying help) #------------------------------------------------------------------------------- @@ -3548,9 +3389,6 @@ Qt/Mac only: * -dwarf2 ............ Enable dwarf2 debugging symbols. -no-dwarf2 ......... Disable dwarf2 debugging symbols. - -arch <arch> ....... Build Qt for <arch>. Supported arch values: x86 x86_64. - Only one arch value can be specified. - -sdk <sdk> ......... Build Qt using Apple provided SDK <sdk>. This option requires gcc 4. To use a different SDK with gcc 3.3, set the SDKROOT environment variable. @@ -4038,6 +3876,33 @@ fi # Build qmake # tests that need qmake #------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- +# determine the target and host architectures +#------------------------------------------------------------------------------- + +# Use config.tests/arch/arch.pro to has the compiler tell us what the target architecture is +CFG_ARCH=`"$outpath/bin/qmake" -spec "$XQMAKESPEC" -o /dev/null "$relpath/config.tests/arch/arch.pro" 2>&1 | sed -e "s,^Project MESSAGE: ,," -e "s,^#.*$,,g" | grep -v "^$"` +[ -z "$CFG_ARCH" ] && CFG_ARCH="unknown" +if [ "$QMAKESPEC" != "$XQMAKESPEC" ]; then + # Do the same test again, using the host compiler + CFG_HOST_ARCH=`"$outpath/bin/qmake" -spec "$QMAKESPEC" -o /dev/null "$relpath/config.tests/arch/arch.pro" 2>&1 | sed -e "s,^Project MESSAGE: ,," -e "s,^#.*$,,g" | grep -v "^$"` + [ -z "$CFG_HOST_ARCH" ] && CFG_HOST_ARCH="unknown" +else + # not cross compiling, host == target + CFG_HOST_ARCH="$CFG_ARCH" +fi + +if [ "$OPT_VERBOSE" = "yes" ]; then + echo "System architecture: '$CFG_ARCH'" + if [ "$PLATFORM_QPA" = "yes" ]; then + echo "Host architecture: '$CFG_HOST_ARCH'" + fi +fi + +#------------------------------------------------------------------------------- +# functionality tests +#------------------------------------------------------------------------------- + # detect availability of float math.h functions if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/floatmath "floatmath" $L_FLAGS $I_FLAGS $l_FLAGS; then CFG_USE_FLOATMATH=yes @@ -4143,6 +4008,8 @@ if [ "$CFG_ARCH" = "arm" ] && [ "${CFG_NEON}" = "auto" ]; then else CFG_NEON=no fi +elif [ "$CFG_ARCH" != "arm" ]; then + CFG_NEON=no fi [ "$XPLATFORM_MINGW" = "yes" ] && QMakeVar add styles "windowsxp windowsvista" @@ -5522,29 +5389,27 @@ if [ "$CFG_MAC_DWARF2" = "yes" ]; then QT_CONFIG="$QT_CONFIG dwarf2" fi -# Set the default Mac OS X arch if there are no "-arch" arguments on the configure line +# Detect the default arch (x86 or x86_64) on Mac OS X if [ "$BUILD_ON_MAC" = "yes" ]; then - DEFAULT_ARCH="$CFG_MAC_ARCHS" - if [ -z "$DEFAULT_ARCH" ]; then - case `file "${outpath}/bin/qmake"` in - *i?86) - DEFAULT_ARCH=x86 - ;; - *x86_64) - DEFAULT_ARCH=x86_64 - ;; - *ppc|*ppc64|*) - # unsupported/unknown - ;; - esac - fi + DEFAULT_ARCH= + case `file "${outpath}/bin/qmake"` in + *i?86) + DEFAULT_ARCH=x86 + ;; + *x86_64) + DEFAULT_ARCH=x86_64 + ;; + *ppc|*ppc64|*) + # unsupported/unknown + ;; + esac + if [ -n "$DEFAULT_ARCH" ]; then [ "$OPT_VERBOSE" = "yes" ] && echo "Setting default Mac OS X architechture to $DEFAULT_ARCH." QT_CONFIG="$QT_CONFIG $DEFAULT_ARCH" QMAKE_CONFIG="$QMAKE_CONFIG $DEFAULT_ARCH" - # Make the application arch follow the Qt arch for single arch builds. - # (for multiple-arch builds, set CONFIG manually in the application .pro file) - [ `echo "$DEFAULT_ARCH" | wc -w` -eq 1 ] && QTCONFIG_CONFIG="$QTCONFIG_CONFIG $DEFAULT_ARCH" + # Make the application arch follow the Qt arch + QTCONFIG_CONFIG="$QTCONFIG_CONFIG $DEFAULT_ARCH" fi fi @@ -6156,17 +6021,6 @@ cat >>"$outpath/src/corelib/global/qconfig.h.new" <<EOF #endif EOF -CFG_ARCH_STR=`echo $CFG_ARCH | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -CFG_HOST_ARCH_STR=`echo $CFG_HOST_ARCH | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` -cat >>"$outpath/src/corelib/global/qconfig.h.new" <<EOF -/* Machine Architecture */ -#ifndef QT_BOOTSTRAPPED -# define QT_ARCH_${CFG_ARCH_STR} -#else -# define QT_ARCH_${CFG_HOST_ARCH_STR} -#endif -EOF - echo '/* Compile time features */' >>"$outpath/src/corelib/global/qconfig.h.new" [ '!' -z "$LicenseKeyExt" ] && echo "#define QT_PRODUCT_LICENSEKEY \"$LicenseKeyExt\"" >>"$outpath/src/corelib/global/qconfig.h.new" @@ -6389,6 +6243,7 @@ cat >>"$QTCONFIG.tmp" <<EOF #configuration CONFIG += $QTCONFIG_CONFIG QT_ARCH = $CFG_ARCH +QT_HOST_ARCH = $CFG_HOST_ARCH QT_EDITION = $Edition QT_CONFIG += $QT_CONFIG @@ -6583,12 +6438,7 @@ else echo "Building for: $XPLATFORM" fi -if [ ! -z "$CFG_MAC_ARCHS" ]; then - echo "Architecture: $CFG_ARCH ($CFG_MAC_ARCHS )" -else - echo "Architecture: $CFG_ARCH" -fi - +echo "Architecture: $CFG_ARCH" if [ "$PLATFORM_QPA" = "yes" ]; then echo "Host architecture: $CFG_HOST_ARCH" fi @@ -6631,10 +6481,11 @@ fi echo "Declarative debugging ...$CFG_DECLARATIVE_DEBUG" echo "STL support ............ $CFG_STL" echo "PCH support ............ $CFG_PRECOMPILE" -echo "MMX/3DNOW/SSE/SSE2/SSE3. ${CFG_MMX}/${CFG_3DNOW}/${CFG_SSE}/${CFG_SSE2}/${CFG_SSE3}" -echo "SSSE3/SSE4.1/SSE4.2..... ${CFG_SSSE3}/${CFG_SSE4_1}/${CFG_SSE4_2}" -echo "AVX..................... ${CFG_AVX}" -if [ "$CFG_ARCH" = "arm" ] || [ "$CFG_ARCH" = "armv6" ]; then +if [ "$CFG_ARCH" = "i386" -o "$CFG_ARCH" = "x86_64" ]; then + echo "MMX/3DNOW/SSE/SSE2/SSE3. ${CFG_MMX}/${CFG_3DNOW}/${CFG_SSE}/${CFG_SSE2}/${CFG_SSE3}" + echo "SSSE3/SSE4.1/SSE4.2..... ${CFG_SSSE3}/${CFG_SSE4_1}/${CFG_SSE4_2}" + echo "AVX..................... ${CFG_AVX}" +elif [ "$CFG_ARCH" = "arm" ]; then echo "iWMMXt support ......... ${CFG_IWMMXT}" echo "NEON support ........... ${CFG_NEON}" fi @@ -6997,14 +6848,21 @@ rm -f .projects .projects.3 #------------------------------------------------------------------------------- # check for platforms that we don't yet know about #------------------------------------------------------------------------------- -if [ "$CFG_ARCH" = "generic" ]; then +if [ "$CFG_ARCH" = "unknown" ]; then cat <<EOF - NOTICE: Atomic operations are not yet supported for this - architecture. + NOTICE: configure was unable to determine the architecture + for the $XQMAKESPEC target. - Qt will use the 'generic' architecture instead, which uses a - single pthread_mutex_t to protect all atomic operations. This + Qt will not use a specialized implementation for any atomic + operations. Instead a generic implemention based on either GCC + intrinsics or C++11 std::atomic<T> will be used (when + available). The generic implementations are generally as fast + as and always as safe as a specialized implementation. + + If no generic implementation is available, Qt will use a + fallback UNIX implementation which uses a single + pthread_mutex_t to protect all atomic operations. This implementation is the slow (but safe) fallback implementation for architectures Qt does not yet support. EOF @@ -7043,6 +6901,21 @@ EOF fi #------------------------------------------------------------------------------- +# check if the user passed the obsoleted -arch or -host-arch options +#------------------------------------------------------------------------------- +if [ "$OPT_OBSOLETE_HOST_ARG" = "yes" ]; then +cat <<EOF + + NOTICE: The -arch and -host-arch options are obsolete. + + Qt now detects the target and host architectures based on compiler + output. Qt will be built using $CFG_ARCH for the target architecture + and $CFG_HOST_ARCH for the host architecture (note that these two + will be the same unless you are cross-compiling). +EOF +fi + +#------------------------------------------------------------------------------- # finally save the executed command to another script #------------------------------------------------------------------------------- if [ `basename $0` != "config.status" ]; then diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index d62794e706..04e0f19f06 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -58,6 +58,10 @@ Q_BYTE_ORDER appropriately for the target processor. For bi-endian processors, we try to auto-detect the byte order using the __BIG_ENDIAN__, __LITTLE_ENDIAN__, or __BYTE_ORDER__ preprocessor macros. + + Note: when adding support for new processors, be sure to update + config.tests/arch/arch.cpp to ensure that configure can detect the target + and host architectures. */ /* Machine byte-order, reuse preprocessor provided macros when available */ 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(); |