aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2019-07-03 17:43:20 +0300
committerDenis Shienkov <denis.shienkov@gmail.com>2019-07-09 10:59:31 +0000
commit7d549788813157f17670930b875a23b68ad588c3 (patch)
tree3ad0dedcea3cc0530c7254df9715bdda84f8fe1a /src
parent81041af9ac15f8a0d0a5b6ba2ce4aab98614c34c (diff)
baremetal: Detect SDCC compiler version if it is found in a path
Previously we have only the SDCC toolchain version detection from the Windows registry. This patch adds a compiler version detection in case the compiler path specified in a PATH environment variable. Change-Id: I6a9b74efbd8e4a8cd7a596bdf4946745d820f7f9 Reviewed-by: Qbs CI Bot <travis-bot@weickelt.de> 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/sdccprobe.cpp56
1 files changed, 52 insertions, 4 deletions
diff --git a/src/app/qbs-setup-toolchains/sdccprobe.cpp b/src/app/qbs-setup-toolchains/sdccprobe.cpp
index 41bd45e2a..e1f85efd6 100644
--- a/src/app/qbs-setup-toolchains/sdccprobe.cpp
+++ b/src/app/qbs-setup-toolchains/sdccprobe.cpp
@@ -47,8 +47,9 @@
#include <tools/hostosinfo.h>
#include <tools/profile.h>
-#include <QtCore/qlist.h>
+#include <QtCore/qprocess.h>
#include <QtCore/qsettings.h>
+#include <QtCore/qtemporaryfile.h>
using namespace qbs;
using Internal::Tr;
@@ -97,6 +98,45 @@ static Profile createSdccProfileHelper(const ToolchainInstallInfo &info,
return profile;
}
+
+static Version dumpSdccCompilerVersion(const QFileInfo &compiler)
+{
+ QTemporaryFile fakeIn(QStringLiteral("XXXXXX.c"));
+ if (!fakeIn.open()) {
+ qbsWarning() << Tr::tr("Unable to open temporary file %1 for output: %2")
+ .arg(fakeIn.fileName(), fakeIn.errorString());
+ return Version{};
+ }
+ fakeIn.close();
+
+ const QStringList args = {QStringLiteral("-dM"),
+ QStringLiteral("-E"),
+ fakeIn.fileName()};
+ 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.readAllStandardOutput();
+ const int major = extractVersion(dump, "__SDCC_VERSION_MAJOR ");
+ const int minor = extractVersion(dump, "__SDCC_VERSION_MINOR ");
+ const int patch = extractVersion(dump, "__SDCC_VERSION_PATCH ");
+ if (major < 0 || minor < 0 || patch < 0) {
+ qbsWarning() << Tr::tr("No '__SDCC_VERSION_xxx' token was found "
+ "in the compiler dump:\n%1")
+ .arg(QString::fromUtf8(dump));
+ return Version{};
+ }
+
+ return Version{major, minor, patch};
+}
+
static std::vector<ToolchainInstallInfo> installedSdccsFromPath()
{
std::vector<ToolchainInstallInfo> infos;
@@ -107,8 +147,10 @@ static std::vector<ToolchainInstallInfo> installedSdccsFromPath()
HostOsInfo::appendExecutableSuffix(compilerName)));
if (!sdccPath.exists())
continue;
- infos.push_back({sdccPath, Version{}});
+ const Version version = dumpSdccCompilerVersion(sdccPath);
+ infos.push_back({sdccPath, version});
}
+ std::sort(infos.begin(), infos.end());
return infos;
}
@@ -140,6 +182,7 @@ static std::vector<ToolchainInstallInfo> installedSdccsFromRegistry()
}
}
+ std::sort(infos.begin(), infos.end());
return infos;
}
@@ -162,9 +205,14 @@ void sdccProbe(Settings *settings, QList<Profile> &profiles)
{
qbsInfo() << Tr::tr("Trying to detect SDCC toolchains...");
- std::vector<ToolchainInstallInfo> allInfos = installedSdccsFromRegistry();
+ // Make sure that a returned infos are sorted before using the std::set_union!
+ const std::vector<ToolchainInstallInfo> regInfos = installedSdccsFromRegistry();
const std::vector<ToolchainInstallInfo> pathInfos = installedSdccsFromPath();
- allInfos.insert(std::end(allInfos), std::begin(pathInfos), std::end(pathInfos));
+ std::vector<ToolchainInstallInfo> allInfos;
+ allInfos.reserve(regInfos.size() + pathInfos.size());
+ std::set_union(regInfos.cbegin(), regInfos.cend(),
+ pathInfos.cbegin(), pathInfos.cend(),
+ std::back_inserter(allInfos));
for (const ToolchainInstallInfo &info : allInfos) {
const auto profile = createSdccProfileHelper(info, settings);