From 7d549788813157f17670930b875a23b68ad588c3 Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Wed, 3 Jul 2019 17:43:20 +0300 Subject: 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 Reviewed-by: Ivan Komissarov Reviewed-by: Christian Kandeler --- src/app/qbs-setup-toolchains/sdccprobe.cpp | 56 +++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) (limited to 'src') 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 #include -#include +#include #include +#include 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 installedSdccsFromPath() { std::vector infos; @@ -107,8 +147,10 @@ static std::vector 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 installedSdccsFromRegistry() } } + std::sort(infos.begin(), infos.end()); return infos; } @@ -162,9 +205,14 @@ void sdccProbe(Settings *settings, QList &profiles) { qbsInfo() << Tr::tr("Trying to detect SDCC toolchains..."); - std::vector allInfos = installedSdccsFromRegistry(); + // Make sure that a returned infos are sorted before using the std::set_union! + const std::vector regInfos = installedSdccsFromRegistry(); const std::vector pathInfos = installedSdccsFromPath(); - allInfos.insert(std::end(allInfos), std::begin(pathInfos), std::end(pathInfos)); + std::vector 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); -- cgit v1.2.3