aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2020-05-07 16:09:46 +0300
committerDenis Shienkov <denis.shienkov@gmail.com>2020-05-11 09:20:48 +0000
commitc27911e40809c3fe295f1728d57b55c5a8045842 (patch)
tree20cd6e708762e2820d25d6ff17b4a6a9e6880a0c /src
parent8ddac72536e0e582f997e567e702ce2d12596a82 (diff)
baremetal: Auto-detect ARMCLANG compiler supplied in Keil MDK
In this case the utility creates the default profile starting with the 'keil-llvm-' string. Change-Id: I81dfe94210a9e291d491568e7e0d978021453d4b Reviewed-by: Ivan Komissarov <ABBAPOH@gmail.com> Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/app/qbs-setup-toolchains/keilprobe.cpp103
1 files changed, 76 insertions, 27 deletions
diff --git a/src/app/qbs-setup-toolchains/keilprobe.cpp b/src/app/qbs-setup-toolchains/keilprobe.cpp
index 67b14a802..ee0144c77 100644
--- a/src/app/qbs-setup-toolchains/keilprobe.cpp
+++ b/src/app/qbs-setup-toolchains/keilprobe.cpp
@@ -59,7 +59,8 @@ using Internal::HostOsInfo;
static QStringList knownKeilCompilerNames()
{
return {QStringLiteral("c51"), QStringLiteral("c251"),
- QStringLiteral("c166"), QStringLiteral("armcc")};
+ QStringLiteral("c166"), QStringLiteral("armcc"),
+ QStringLiteral("armclang")};
}
static QString guessKeilArchitecture(const QFileInfo &compiler)
@@ -73,9 +74,16 @@ static QString guessKeilArchitecture(const QFileInfo &compiler)
return QStringLiteral("c166");
if (baseName == QLatin1String("armcc"))
return QStringLiteral("arm");
+ if (baseName == QLatin1String("armclang"))
+ return QStringLiteral("arm");
return {};
}
+static bool isArmClangCompiler(const QFileInfo &compiler)
+{
+ return compiler.baseName() == QLatin1String("armclang");
+}
+
static Profile createKeilProfileHelper(const ToolchainInstallInfo &info,
Settings *settings,
QString profileName = QString())
@@ -90,13 +98,19 @@ static Profile createKeilProfileHelper(const ToolchainInstallInfo &info,
} else {
const QString version = info.compilerVersion.toString(QLatin1Char('_'),
QLatin1Char('_'));
- profileName = QStringLiteral("keil-%1-%2").arg(
- version, architecture);
+ if (architecture == QLatin1String("arm") && isArmClangCompiler(compiler)) {
+ profileName = QStringLiteral("keil-llvm-%1-%2").arg(
+ version, architecture);
+ } else {
+ profileName = QStringLiteral("keil-%1-%2").arg(
+ version, architecture);
+ }
}
}
Profile profile(profileName, settings);
profile.setValue(QStringLiteral("cpp.toolchainInstallPath"), compiler.absolutePath());
+ profile.setValue(QStringLiteral("cpp.compilerName"), compiler.fileName());
profile.setValue(QStringLiteral("qbs.toolchainType"), QStringLiteral("keil"));
if (!architecture.isEmpty())
profile.setValue(QStringLiteral("qbs.architecture"), architecture);
@@ -236,7 +250,7 @@ static Version dumpC166CompilerVersion(const QFileInfo &compiler)
return Version{verCode / 100, verCode % 100};
}
-static Version dumpArmCompilerVersion(const QFileInfo &compiler)
+static Version dumpArmCCCompilerVersion(const QFileInfo &compiler)
{
const QStringList args = {QStringLiteral("-E"),
QStringLiteral("--list-macros"),
@@ -263,6 +277,34 @@ static Version dumpArmCompilerVersion(const QFileInfo &compiler)
return Version{verCode / 1000000, (verCode / 10000) % 100, verCode % 10000};
}
+static Version dumpArmClangCompilerVersion(const QFileInfo &compiler)
+{
+ const QStringList args = {QStringLiteral("-dM"), QStringLiteral("-E"),
+ QStringLiteral("-xc"),
+ QStringLiteral("--target=arm-arm-none-eabi"),
+ QStringLiteral("-mcpu=cortex-m0"),
+ QStringLiteral("nul")};
+ QProcess p;
+ p.start(compiler.absoluteFilePath(), args);
+ p.waitForFinished(3000);
+ const auto es = p.exitStatus();
+ if (es != QProcess::NormalExit) {
+ const QByteArray out = p.readAll();
+ qbsWarning() << Tr::tr("Compiler dumping failed:\n%1")
+ .arg(QString::fromUtf8(out));
+ return Version{};
+ }
+ const QByteArray dump = p.readAll();
+ const int verCode = extractVersion(dump, "__ARMCC_VERSION ");
+ if (verCode < 0) {
+ qbsWarning() << Tr::tr("No '__ARMCC_VERSION' token was found "
+ "in the compiler dump:\n%1")
+ .arg(QString::fromUtf8(dump));
+ return Version{};
+ }
+ return Version{verCode / 1000000, (verCode / 10000) % 100, verCode % 10000};
+}
+
static Version dumpKeilCompilerVersion(const QFileInfo &compiler)
{
const QString arch = guessKeilArchitecture(compiler);
@@ -271,7 +313,9 @@ static Version dumpKeilCompilerVersion(const QFileInfo &compiler)
} else if (arch == QLatin1String("c166")) {
return dumpC166CompilerVersion(compiler);
} else if (arch == QLatin1String("arm")) {
- return dumpArmCompilerVersion(compiler);
+ if (isArmClangCompiler(compiler))
+ return dumpArmClangCompilerVersion(compiler);
+ return dumpArmCCCompilerVersion(compiler);
}
return Version{};
}
@@ -361,28 +405,33 @@ static std::vector<ToolchainInstallInfo> installedKeilsFromRegistry()
const QString productPath = registry.value(QStringLiteral("ProductDir"))
.toString();
// Fetch the toolchain executable path.
- QFileInfo keilPath;
- if (productPath.endsWith(QStringLiteral("ARM")))
- keilPath.setFile(productPath + QStringLiteral("\\ARMCC\\bin\\armcc.exe"));
- else if (productPath.endsWith(QStringLiteral("C51")))
- keilPath.setFile(productPath + QStringLiteral("\\BIN\\c51.exe"));
- else if (productPath.endsWith(QStringLiteral("C251")))
- keilPath.setFile(productPath + QStringLiteral("\\BIN\\c251.exe"));
- else if (productPath.endsWith(QStringLiteral("C166")))
- keilPath.setFile(productPath + QStringLiteral("\\BIN\\c166.exe"));
-
- if (keilPath.exists()) {
- // Fetch the toolchain version.
- const QDir rootPath(registry.value(QStringLiteral("Directory")).toString());
- const QString toolsIniFilePath = rootPath.absoluteFilePath(
- QStringLiteral("tools.ini"));
- for (auto index = 1; index <= 2; ++index) {
- const QString section = registry.value(
- QStringLiteral("Section %1").arg(index)).toString();
- const QString version = extractVersion(toolsIniFilePath, section);
- if (!version.isEmpty()) {
- infos.push_back({keilPath, Version::fromString(version)});
- break;
+ QVector<QFileInfo> keilPaths;
+ if (productPath.endsWith(QStringLiteral("ARM"))) {
+ keilPaths << QFileInfo(productPath + QStringLiteral("/ARMCC/bin/armcc.exe"));
+ keilPaths << QFileInfo(productPath + QStringLiteral("/ARMCLANG/bin/armclang.exe"));
+ } else if (productPath.endsWith(QStringLiteral("C51"))) {
+ keilPaths << QFileInfo(productPath + QStringLiteral("/BIN/c51.exe"));
+ } else if (productPath.endsWith(QStringLiteral("C251"))) {
+ keilPaths << QFileInfo(productPath + QStringLiteral("/BIN/c251.exe"));
+ } else if (productPath.endsWith(QStringLiteral("C166"))) {
+ keilPaths << QFileInfo(productPath + QStringLiteral("/BIN/c166.exe"));
+ }
+
+ // Fetch the toolchain version.
+ const QDir rootPath(registry.value(QStringLiteral("Directory")).toString());
+ const QString toolsIniFilePath = rootPath.absoluteFilePath(
+ QStringLiteral("tools.ini"));
+
+ for (const QFileInfo &keilPath : qAsConst(keilPaths)) {
+ if (keilPath.exists()) {
+ for (auto index = 1; index <= 2; ++index) {
+ const QString section = registry.value(
+ QStringLiteral("Section %1").arg(index)).toString();
+ const QString version = extractVersion(toolsIniFilePath, section);
+ if (!version.isEmpty()) {
+ infos.push_back({keilPath, Version::fromString(version)});
+ break;
+ }
}
}
}