Improve the architecture-detection mechanism

For the Unix part, this now obeys the -v option, printing the full
command-line it used to compile, allowing testers to identify why
something went wrong.

Unfortunately, it requires a full compilation cycle, instead of just
preprocessing. Just one more among the many on Unix, but maybe a
noticeable slow-down on Windows.

Change-Id: I654b70d99887e04c96731a5b91be9ad555e4d8fe
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
Reviewed-by: Girish Ramakrishnan <girish.1.ramakrishnan@nokia.com>
This commit is contained in:
Thiago Macieira 2012-03-27 14:43:45 -03:00 committed by Qt by Nokia
parent d17cf14185
commit 1533bfc5fc
5 changed files with 130 additions and 45 deletions

View File

@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Copyright (C) 2012 Intel Corporation
** Contact: http://www.qt-project.org/
**
** This file is part of the FOO module of the Qt Toolkit.
@ -39,46 +40,43 @@
**
****************************************************************************/
// NOTE: This file is not meant to be compiled, only preprocessed.
#define QGLOBAL_H
#include "../../src/corelib/global/qprocessordetection.h"
#undef alpha
#undef arm
#undef avr32
#undef bfin
#undef i386
#undef x86_64
#undef ia64
#undef mips
#undef power
#undef s390
#undef sh
#undef sparc
#undef unknown
#include <stdio.h>
extern const char msg[];
const char msg[] = "==Qt=magic=Qt== Architecture:"
#if defined(Q_PROCESSOR_ALPHA)
Architecture: alpha
"alpha"
#elif defined(Q_PROCESSOR_ARM)
Architecture: arm
"arm"
#elif defined(Q_PROCESSOR_AVR32)
Architecture: avr32
"avr32"
#elif defined(Q_PROCESSOR_BLACKFIN)
Architecture: bfin
"bfin"
#elif defined(Q_PROCESSOR_X86_32)
Architecture: i386
"i386"
#elif defined(Q_PROCESSOR_X86_64)
Architecture: x86_64
"x86_64"
#elif defined(Q_PROCESSOR_IA64)
Architecture: ia64
"ia64"
#elif defined(Q_PROCESSOR_MIPS)
Architecture: mips
"mips"
#elif defined(Q_PROCESSOR_POWER)
Architecture: power
"power"
#elif defined(Q_PROCESSOR_S390)
Architecture: s390
"s390"
#elif defined(Q_PROCESSOR_SH)
Architecture: sh
"sh"
#elif defined(Q_PROCESSOR_SPARC)
Architecture: sparc
"sparc"
#else
Architecture: unknown
"unknown"
#endif
;
int main()
{
puts(msg);
}

View File

@ -1,7 +1,4 @@
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
# system function converts newline in output into spaces
COMPILER_ARCH = $$system($$COMMAND)
# Message back to configure so that it can set QT_ARCH and QT_HOST_ARCH
message($$COMPILER_ARCH)
SOURCES = arch.cpp
CONFIG -= qt dylib release debug_and_release
CONFIG += debug console
mac:CONFIG -= app_bundle

41
config.tests/unix/arch.test Executable file
View File

@ -0,0 +1,41 @@
#!/bin/sh
QMKSPEC=$1
VERBOSE=$2
SRCDIR=$3
OUTDIR=$4
RESULTFILE=$5
# debuggery
[ "$VERBOSE" = "yes" ] && echo "Determining architecture... ($*)"
# build a test program but don't run it
test -d "$OUTDIR/config.tests/arch" || mkdir -p "$OUTDIR/config.tests/arch"
[ -f Makefile ] && $MAKE distclean >/dev/null 2>&1
"$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "QT_BUILD_TREE=$OUTDIR" "LIBS+=$SYSROOT_FLAG" "QMAKE_CXXFLAGS+=$SYSROOT_FLAG" "$SRCDIR/config.tests/arch/arch.pro" -o "$OUTDIR/config.tests/arch/Makefile" >/dev/null 2>&1 || echo "qmake is broken" >&2
cd "$OUTDIR/config.tests/arch"
ARCH=""
[ "$VERBOSE" = "yes" ] && $MAKE || $MAKE >/dev/null 2>&1
if [ -f ./arch.exe ]; then
binary=./arch.exe
elif [ -f ./arch ]; then
binary=./arch
else
[ "$VERBOSE" = "yes" ] && echo "Unable to determine architecture!"
exit 2
fi
ARCH=`strings - $binary 2>/dev/null | awk -F: '/==Qt=magic=Qt==/ { print $2 }'` ||
{
[ "$VERBOSE" = "yes" ] && echo "Unable to determine architecture!"
exit 2
}
$MAKE distclean >/dev/null 2>&1
[ "$VERBOSE" = "yes" ] && echo " Found '$ARCH' in binary"
echo "$ARCH" > $5

24
configure vendored
View File

@ -3667,17 +3667,35 @@ fi
#-------------------------------------------------------------------------------
# Use config.tests/arch/arch.pro to has the compiler tell us what the target architecture is
CFG_ARCH=`OUTDIR="$outpath" "$outpath/bin/qmake" -spec "$XQMAKESPEC" -o /dev/null "$relpath/config.tests/arch/arch.pro" 2>&1 | sed -n -e 's,^Project MESSAGE:.*Architecture: \([a-zA-Z0-9_]*\).*,\1,p'`
OUTFILE=$outpath/arch.result
"$unixtests/arch.test" "$XQMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" "$OUTFILE"
if [ $? -eq 0 ]; then
CFG_ARCH=`cat "$OUTFILE"`
else
echo
echo "Could not determine the target architecture!"
echo "Turn on verbose messaging (-v) to see the final report."
fi
rm -f "$OUTFILE" 2>/dev/null
[ -z "$CFG_ARCH" ] && CFG_ARCH="unknown"
if [ "$QMAKESPEC" != "$XQMAKESPEC" ]; then
# Do the same test again, using the host compiler
CFG_HOST_ARCH=`OUTDIR="$outpath" "$outpath/bin/qmake" -spec "$QMAKESPEC" -o /dev/null "$relpath/config.tests/arch/arch.pro" 2>&1 | sed -n -e 's,^Project MESSAGE:.*Architecture: \([a-zA-Z0-9_]*\).*,\1,p'`
SYSROOT_FLAG= "$unixtests/arch.test" "$QMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" "$OUTFILE"
if [ $? -eq 0 ]; then
CFG_HOST_ARCH=`cat "$OUTFILE"`
else
echo
echo "Could not determine the host architecture!"
echo "Turn on verbose messaging (-v) to see the final report."
fi
rm -f "$OUTFILE" 2>/dev/null
[ -z "$CFG_HOST_ARCH" ] && CFG_HOST_ARCH="unknown"
else
# not cross compiling, host == target
CFG_HOST_ARCH="$CFG_ARCH"
fi
unset OUTFILE
if [ "$OPT_VERBOSE" = "yes" ]; then
echo "System architecture: '$CFG_ARCH'"

View File

@ -2561,16 +2561,47 @@ void Configure::detectArch()
QString qmakespec = dictionary.value(pair.first);
QString key = pair.second;
// run qmake
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;
fixSeparators(QString("%1/bin/qmake.exe -spec %2 %3/config.tests/arch/arch.pro 2>&1")
.arg(buildPath, qmakespec, sourcePath));
Environment::execute(command);
QRegExp re("Project MESSAGE:.*Architecture: ([a-zA-Z0-9_]*)");
if (re.indexIn(output) != -1)
dictionary[key] = re.cap(1);
// compile
command = dictionary[ "MAKE" ];
if (command.contains("nmake"))
command += " /NOLOGO";
command += " -s";
Environment::execute(command);
// find the executable that was generated
QFile exe("arch.exe");
if (!exe.open(QFile::ReadOnly)) { // no Text, this is binary
cout << "Could not find output file: " << qPrintable(exe.errorString()) << endl;
dictionary["DONE"] = "error";
return;
}
QByteArray exeContents = exe.readAll();
exe.close();
static const char magic[] = "==Qt=magic=Qt== Architecture:";
int magicPos = exeContents.indexOf(magic);
if (magicPos == -1) {
cout << "Internal error, could not find the architecture of the executable" << endl;
dictionary["DONE"] = "error";
return;
}
//cout << "Found magic at offset 0x" << hex << magicPos << endl;
// the conversion from QByteArray will stop at the ending NUL anyway
QString arch = QString::fromLatin1(exeContents.constData() + magicPos
+ sizeof(magic) - 1);
dictionary[key] = arch;
//cout << "Detected arch '" << qPrintable(arch) << "'\n";
// clean up
Environment::execute(command + " distclean");
}
if (!dictionary.contains("QT_HOST_ARCH"))