forked from qt-creator/qt-creator
BareMetal: Add support for Keil C251 toolchain
This patch adds support for the C251 toolchain, provided by KEIL: * http://www.keil.com/c251/ Now the auto-detected C251 compiler will be displayed with an appropriate ABI on the "Options->Kits->Compilers" page. Change-Id: I40cf2b82117420b2eddb09cad902c9f264bac062 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -74,12 +74,14 @@ static Abi::Architecture guessArchitecture(const FilePath &compilerPath)
|
||||
const QString bn = fi.baseName().toLower();
|
||||
if (bn == "c51" || bn == "cx51")
|
||||
return Abi::Architecture::Mcs51Architecture;
|
||||
if (bn == "c251")
|
||||
return Abi::Architecture::Mcs251Architecture;
|
||||
if (bn == "armcc")
|
||||
return Abi::Architecture::ArmArchitecture;
|
||||
return Abi::Architecture::UnknownArchitecture;
|
||||
}
|
||||
|
||||
// Note: The KEIL 8051 compiler does not support the predefined
|
||||
// Note: The KEIL C51 compiler does not support the predefined
|
||||
// macros dumping. So, we do it with following trick where we try
|
||||
// to compile a temporary file and to parse the console output.
|
||||
static Macros dumpC51PredefinedMacros(const FilePath &compiler, const QStringList &env)
|
||||
@@ -124,6 +126,41 @@ static Macros dumpC51PredefinedMacros(const FilePath &compiler, const QStringLis
|
||||
return macros;
|
||||
}
|
||||
|
||||
// Note: The KEIL C251 compiler does not support the predefined
|
||||
// macros dumping. So, we do it with following trick where we try
|
||||
// to compile a temporary file and to parse the console output.
|
||||
static Macros dumpC251PredefinedMacros(const FilePath &compiler, const QStringList &env)
|
||||
{
|
||||
QTemporaryFile fakeIn;
|
||||
if (!fakeIn.open())
|
||||
return {};
|
||||
fakeIn.write("#define VALUE_TO_STRING(x) #x\n");
|
||||
fakeIn.write("#define VALUE(x) VALUE_TO_STRING(x)\n");
|
||||
fakeIn.write("#define VAR_NAME_VALUE(var) \"\"|#var|VALUE(var)|\"\n");
|
||||
fakeIn.write("#ifdef __C251__\n");
|
||||
fakeIn.write("#warning(VAR_NAME_VALUE(__C251__))\n");
|
||||
fakeIn.write("#endif\n");
|
||||
fakeIn.close();
|
||||
|
||||
SynchronousProcess cpp;
|
||||
cpp.setEnvironment(env);
|
||||
cpp.setTimeoutS(10);
|
||||
|
||||
const CommandLine cmd(compiler, {fakeIn.fileName()});
|
||||
const SynchronousProcessResponse response = cpp.runBlocking(cmd);
|
||||
QString output = response.allOutput();
|
||||
Macros macros;
|
||||
QTextStream stream(&output);
|
||||
QString line;
|
||||
while (stream.readLineInto(&line)) {
|
||||
const QStringList parts = line.split("\"|\"");
|
||||
if (parts.count() != 4)
|
||||
continue;
|
||||
macros.push_back({parts.at(1).toUtf8(), parts.at(2).toUtf8()});
|
||||
}
|
||||
return macros;
|
||||
}
|
||||
|
||||
static Macros dumpArmPredefinedMacros(const FilePath &compiler, const QStringList &env)
|
||||
{
|
||||
SynchronousProcess cpp;
|
||||
@@ -152,6 +189,8 @@ static Macros dumpPredefinedMacros(const FilePath &compiler, const QStringList &
|
||||
switch (arch) {
|
||||
case Abi::Architecture::Mcs51Architecture:
|
||||
return dumpC51PredefinedMacros(compiler, env);
|
||||
case Abi::Architecture::Mcs251Architecture:
|
||||
return dumpC251PredefinedMacros(compiler, env);
|
||||
case Abi::Architecture::ArmArchitecture:
|
||||
return dumpArmPredefinedMacros(compiler, env);
|
||||
default:
|
||||
@@ -159,6 +198,12 @@ static Macros dumpPredefinedMacros(const FilePath &compiler, const QStringList &
|
||||
}
|
||||
}
|
||||
|
||||
static bool isMcsArchitecture(Abi::Architecture arch)
|
||||
{
|
||||
return arch == Abi::Architecture::Mcs51Architecture
|
||||
|| arch == Abi::Architecture::Mcs251Architecture;
|
||||
}
|
||||
|
||||
static HeaderPaths dumpHeaderPaths(const FilePath &compiler)
|
||||
{
|
||||
if (!compiler.exists())
|
||||
@@ -171,7 +216,7 @@ static HeaderPaths dumpHeaderPaths(const FilePath &compiler)
|
||||
HeaderPaths headerPaths;
|
||||
|
||||
const Abi::Architecture arch = guessArchitecture(compiler);
|
||||
if (arch == Abi::Architecture::Mcs51Architecture) {
|
||||
if (isMcsArchitecture(arch)) {
|
||||
QDir includeDir(toolkitDir);
|
||||
if (includeDir.cd("inc"))
|
||||
headerPaths.push_back({includeDir.canonicalPath(), HeaderPathType::BuiltIn});
|
||||
@@ -191,15 +236,17 @@ static Abi::Architecture guessArchitecture(const Macros ¯os)
|
||||
return Abi::Architecture::ArmArchitecture;
|
||||
if (macro.key == "__C51__" || macro.key == "__CX51__")
|
||||
return Abi::Architecture::Mcs51Architecture;
|
||||
if (macro.key == "__C251__")
|
||||
return Abi::Architecture::Mcs251Architecture;
|
||||
}
|
||||
return Abi::Architecture::UnknownArchitecture;
|
||||
}
|
||||
|
||||
static unsigned char guessWordWidth(const Macros ¯os, Abi::Architecture arch)
|
||||
{
|
||||
// Check for C51 compiler first.
|
||||
if (arch == Abi::Architecture::Mcs51Architecture)
|
||||
return 16; // C51 always have 16-bit word width.
|
||||
// Check for C51 or C251 compiler first.
|
||||
if (isMcsArchitecture(arch))
|
||||
return 16; // C51 or C251 always have 16-bit word width.
|
||||
|
||||
const Macro sizeMacro = Utils::findOrDefault(macros, [](const Macro &m) {
|
||||
return m.key == "__sizeof_int";
|
||||
@@ -213,7 +260,7 @@ static Abi::BinaryFormat guessFormat(Abi::Architecture arch)
|
||||
{
|
||||
if (arch == Abi::Architecture::ArmArchitecture)
|
||||
return Abi::BinaryFormat::ElfFormat;
|
||||
if (arch == Abi::Architecture::Mcs51Architecture)
|
||||
if (isMcsArchitecture(arch))
|
||||
return Abi::BinaryFormat::OmfFormat;
|
||||
return Abi::BinaryFormat::UnknownFormat;
|
||||
}
|
||||
@@ -471,6 +518,8 @@ QList<ToolChain *> KeilToolChainFactory::autoDetect(const QList<ToolChain *> &al
|
||||
compilerPath = productPath.pathAppended("\\ARMCC\\bin\\armcc.exe");
|
||||
else if (productPath.endsWith("C51"))
|
||||
compilerPath = productPath.pathAppended("\\BIN\\c51.exe");
|
||||
else if (productPath.endsWith("C251"))
|
||||
compilerPath = productPath.pathAppended("\\BIN\\c251.exe");
|
||||
|
||||
if (compilerPath.exists()) {
|
||||
// Fetch the toolchain version.
|
||||
@@ -529,9 +578,8 @@ QList<ToolChain *> KeilToolChainFactory::autoDetectToolchain(
|
||||
|
||||
const Abi abi = guessAbi(macros);
|
||||
const Abi::Architecture arch = abi.architecture();
|
||||
if (arch == Abi::Architecture::Mcs51Architecture
|
||||
&& language == ProjectExplorer::Constants::CXX_LANGUAGE_ID) {
|
||||
// KEIL C51 compiler does not support C++ language.
|
||||
if (isMcsArchitecture(arch) && language == ProjectExplorer::Constants::CXX_LANGUAGE_ID) {
|
||||
// KEIL C51 or C251 compiler does not support C++ language.
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@@ -705,6 +705,8 @@ QString Abi::toString(const Architecture &a)
|
||||
return QLatin1String("x86");
|
||||
case Mcs51Architecture:
|
||||
return QLatin1String("mcs51");
|
||||
case Mcs251Architecture:
|
||||
return QLatin1String("mcs251");
|
||||
case MipsArchitecture:
|
||||
return QLatin1String("mips");
|
||||
case PowerPCArchitecture:
|
||||
@@ -849,6 +851,8 @@ Abi::Architecture Abi::architectureFromString(const QStringRef &a)
|
||||
return X86Architecture;
|
||||
if (a == "mcs51")
|
||||
return Mcs51Architecture;
|
||||
if (a == "mcs251")
|
||||
return Mcs251Architecture;
|
||||
if (a == "mips")
|
||||
return MipsArchitecture;
|
||||
if (a == "ppc")
|
||||
|
@@ -58,6 +58,7 @@ public:
|
||||
AvrArchitecture,
|
||||
XtensaArchitecture,
|
||||
Mcs51Architecture,
|
||||
Mcs251Architecture,
|
||||
AsmJsArchitecture,
|
||||
Stm8Architecture,
|
||||
Msp430Architecture,
|
||||
|
Reference in New Issue
Block a user