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:
parent
d17cf14185
commit
1533bfc5fc
@ -1,6 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
** Copyright (C) 2012 Intel Corporation
|
||||||
** Contact: http://www.qt-project.org/
|
** Contact: http://www.qt-project.org/
|
||||||
**
|
**
|
||||||
** This file is part of the FOO module of the Qt Toolkit.
|
** 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
|
#define QGLOBAL_H
|
||||||
#include "../../src/corelib/global/qprocessordetection.h"
|
#include "../../src/corelib/global/qprocessordetection.h"
|
||||||
#undef alpha
|
#include <stdio.h>
|
||||||
#undef arm
|
|
||||||
#undef avr32
|
extern const char msg[];
|
||||||
#undef bfin
|
const char msg[] = "==Qt=magic=Qt== Architecture:"
|
||||||
#undef i386
|
|
||||||
#undef x86_64
|
|
||||||
#undef ia64
|
|
||||||
#undef mips
|
|
||||||
#undef power
|
|
||||||
#undef s390
|
|
||||||
#undef sh
|
|
||||||
#undef sparc
|
|
||||||
#undef unknown
|
|
||||||
#if defined(Q_PROCESSOR_ALPHA)
|
#if defined(Q_PROCESSOR_ALPHA)
|
||||||
Architecture: alpha
|
"alpha"
|
||||||
#elif defined(Q_PROCESSOR_ARM)
|
#elif defined(Q_PROCESSOR_ARM)
|
||||||
Architecture: arm
|
"arm"
|
||||||
#elif defined(Q_PROCESSOR_AVR32)
|
#elif defined(Q_PROCESSOR_AVR32)
|
||||||
Architecture: avr32
|
"avr32"
|
||||||
#elif defined(Q_PROCESSOR_BLACKFIN)
|
#elif defined(Q_PROCESSOR_BLACKFIN)
|
||||||
Architecture: bfin
|
"bfin"
|
||||||
#elif defined(Q_PROCESSOR_X86_32)
|
#elif defined(Q_PROCESSOR_X86_32)
|
||||||
Architecture: i386
|
"i386"
|
||||||
#elif defined(Q_PROCESSOR_X86_64)
|
#elif defined(Q_PROCESSOR_X86_64)
|
||||||
Architecture: x86_64
|
"x86_64"
|
||||||
#elif defined(Q_PROCESSOR_IA64)
|
#elif defined(Q_PROCESSOR_IA64)
|
||||||
Architecture: ia64
|
"ia64"
|
||||||
#elif defined(Q_PROCESSOR_MIPS)
|
#elif defined(Q_PROCESSOR_MIPS)
|
||||||
Architecture: mips
|
"mips"
|
||||||
#elif defined(Q_PROCESSOR_POWER)
|
#elif defined(Q_PROCESSOR_POWER)
|
||||||
Architecture: power
|
"power"
|
||||||
#elif defined(Q_PROCESSOR_S390)
|
#elif defined(Q_PROCESSOR_S390)
|
||||||
Architecture: s390
|
"s390"
|
||||||
#elif defined(Q_PROCESSOR_SH)
|
#elif defined(Q_PROCESSOR_SH)
|
||||||
Architecture: sh
|
"sh"
|
||||||
#elif defined(Q_PROCESSOR_SPARC)
|
#elif defined(Q_PROCESSOR_SPARC)
|
||||||
Architecture: sparc
|
"sparc"
|
||||||
#else
|
#else
|
||||||
Architecture: unknown
|
"unknown"
|
||||||
#endif
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
puts(msg);
|
||||||
|
}
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
CONFIG -= qt debug_and_release
|
SOURCES = arch.cpp
|
||||||
# Detect target by preprocessing a file that uses Q_PROCESSOR_* macros from qprocessordetection.h
|
CONFIG -= qt dylib release debug_and_release
|
||||||
COMMAND = $$QMAKE_CXX $$QMAKE_CXXFLAGS -E $$PWD/arch.cpp
|
CONFIG += debug console
|
||||||
# system function converts newline in output into spaces
|
mac:CONFIG -= app_bundle
|
||||||
COMPILER_ARCH = $$system($$COMMAND)
|
|
||||||
# Message back to configure so that it can set QT_ARCH and QT_HOST_ARCH
|
|
||||||
message($$COMPILER_ARCH)
|
|
||||||
|
41
config.tests/unix/arch.test
Executable file
41
config.tests/unix/arch.test
Executable 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
24
configure
vendored
@ -3667,17 +3667,35 @@ fi
|
|||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
# Use config.tests/arch/arch.pro to has the compiler tell us what the target architecture is
|
# 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"
|
[ -z "$CFG_ARCH" ] && CFG_ARCH="unknown"
|
||||||
|
|
||||||
if [ "$QMAKESPEC" != "$XQMAKESPEC" ]; then
|
if [ "$QMAKESPEC" != "$XQMAKESPEC" ]; then
|
||||||
# Do the same test again, using the host compiler
|
# 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"
|
[ -z "$CFG_HOST_ARCH" ] && CFG_HOST_ARCH="unknown"
|
||||||
else
|
else
|
||||||
# not cross compiling, host == target
|
# not cross compiling, host == target
|
||||||
CFG_HOST_ARCH="$CFG_ARCH"
|
CFG_HOST_ARCH="$CFG_ARCH"
|
||||||
fi
|
fi
|
||||||
|
unset OUTFILE
|
||||||
|
|
||||||
if [ "$OPT_VERBOSE" = "yes" ]; then
|
if [ "$OPT_VERBOSE" = "yes" ]; then
|
||||||
echo "System architecture: '$CFG_ARCH'"
|
echo "System architecture: '$CFG_ARCH'"
|
||||||
|
@ -2561,16 +2561,47 @@ void Configure::detectArch()
|
|||||||
QString qmakespec = dictionary.value(pair.first);
|
QString qmakespec = dictionary.value(pair.first);
|
||||||
QString key = pair.second;
|
QString key = pair.second;
|
||||||
|
|
||||||
|
// run qmake
|
||||||
QString command =
|
QString command =
|
||||||
fixSeparators(QString("%1/bin/qmake.exe -spec %2 %3/config.tests/arch/arch.pro -o %4/Makefile.unused 2>&1")
|
fixSeparators(QString("%1/bin/qmake.exe -spec %2 %3/config.tests/arch/arch.pro 2>&1")
|
||||||
.arg(buildPath, qmakespec, sourcePath, newpwd));
|
.arg(buildPath, qmakespec, sourcePath));
|
||||||
QString output = Environment::execute(command);
|
Environment::execute(command);
|
||||||
if (output.isEmpty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
QRegExp re("Project MESSAGE:.*Architecture: ([a-zA-Z0-9_]*)");
|
// compile
|
||||||
if (re.indexIn(output) != -1)
|
command = dictionary[ "MAKE" ];
|
||||||
dictionary[key] = re.cap(1);
|
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"))
|
if (!dictionary.contains("QT_HOST_ARCH"))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user