diff options
author | Denis Shienkov <denis.shienkov@gmail.com> | 2022-02-13 13:39:48 +0300 |
---|---|---|
committer | Denis Shienkov <denis.shienkov@gmail.com> | 2022-02-17 15:46:04 +0000 |
commit | b0207aae78fcd5f28dd2bfadef2874e11365ef50 (patch) | |
tree | be77280d728fe5aa6182fdfcd4adae2375acf196 /src | |
parent | 2ddbafe29872d43245a7fba544dbdced21a09b7f (diff) | |
download | qbs-b0207aae78fcd5f28dd2bfadef2874e11365ef50.tar.gz |
baremetal: Refactor SDCC compiler detection
This patch fixes a bug with the missing profiles.push_back() call
in the createSdccProfileHelper() function.
Also this patch simplifies a code:
* Used the common public dumpMacros() function to dump the pre-defined
compiler macros.
* It is enough to read only the `__SDCC` macro to parse the compiler
version, because this macro exists on all compiler versions (unlike
the `__SDCC_VERSION_xxx` macro which is available only on the versions
more than 3.x).
* Removed extra line breaks to make the code as compact as possible.
Change-Id: Icda1bc0189ef4e374db4b82a29af490b1d2931db
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/app/qbs-setup-toolchains/sdccprobe.cpp | 96 |
1 files changed, 33 insertions, 63 deletions
diff --git a/src/app/qbs-setup-toolchains/sdccprobe.cpp b/src/app/qbs-setup-toolchains/sdccprobe.cpp index a8a27fb96..b53615218 100644 --- a/src/app/qbs-setup-toolchains/sdccprobe.cpp +++ b/src/app/qbs-setup-toolchains/sdccprobe.cpp @@ -48,6 +48,7 @@ #include <tools/profile.h> #include <QtCore/qprocess.h> +#include <QtCore/qregularexpression.h> #include <QtCore/qsettings.h> #include <QtCore/qtemporaryfile.h> @@ -60,8 +61,7 @@ static QStringList knownSdccCompilerNames() return {QStringLiteral("sdcc")}; } -static QByteArray dumpSdccMacros(const QFileInfo &compiler, - const QString &targetFlag = QString()) +static QStringList dumpOutput(const QFileInfo &compiler, const QString &targetFlag = QString()) { QTemporaryFile fakeIn(QStringLiteral("XXXXXX.c")); if (!fakeIn.open()) { @@ -71,39 +71,37 @@ static QByteArray dumpSdccMacros(const QFileInfo &compiler, } fakeIn.close(); - const QStringList args = {QStringLiteral("-dM"), - QStringLiteral("-E"), - targetFlag, - fakeIn.fileName()}; + const QStringList args = {QStringLiteral("-dM"), QStringLiteral("-E"), + targetFlag, 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)); + qbsWarning() << Tr::tr("Compiler dumping failed:\n%1").arg(QString::fromUtf8(out)); return {}; } - return p.readAllStandardOutput(); + static QRegularExpression re(QStringLiteral("\\r?\\n")); + const QStringList lines = QString::fromUtf8(p.readAllStandardOutput()).split(re); + return lines; } static bool supportsSdccArchitecture(const QFileInfo &compiler, QStringView flag) { - const auto targetFlag = QStringLiteral("-m%1").arg(flag); - const auto macros = dumpSdccMacros(compiler, targetFlag); + const auto target = QStringLiteral("-m%1").arg(flag); + const auto macros = dumpMacros([&compiler, &target]() { + return dumpOutput(compiler, target); }); const auto token = QStringLiteral("__SDCC_%1").arg(flag); - return macros.contains(token.toLatin1()); + return macros.contains(token); } -static std::vector<Profile> createSdccProfileHelper( - const ToolchainInstallInfo &info, - Settings *settings, - const QString &profileName = QString()) +static std::vector<Profile> createSdccProfileHelper(const ToolchainInstallInfo &info, + Settings *settings, + const QString &profileName = QString()) { const QFileInfo compiler = info.compilerPath; - std::vector<Profile> profiles; static constexpr struct KnownArch { @@ -122,8 +120,7 @@ static std::vector<Profile> createSdccProfileHelper( // Create a full profile name in case we is // in auto-detecting mode. if (!info.compilerVersion.isValid()) { - fullProfileName = QStringLiteral("sdcc-unknown-%1") - .arg(knownArch.architecture); + fullProfileName = QStringLiteral("sdcc-unknown-%1").arg(knownArch.architecture); } else { const QString version = info.compilerVersion.toString( QLatin1Char('_'), QLatin1Char('_')); @@ -133,61 +130,34 @@ static std::vector<Profile> createSdccProfileHelper( } else { // Append the detected actual architecture name // to the proposed profile name. - fullProfileName = QStringLiteral("%1-%2").arg( - profileName, knownArch.architecture); + fullProfileName = QStringLiteral("%1-%2").arg(profileName, knownArch.architecture); } Profile profile(fullProfileName, settings); - profile.setValue(QStringLiteral("cpp.toolchainInstallPath"), - compiler.absolutePath()); - profile.setValue(QStringLiteral("qbs.toolchainType"), - QStringLiteral("sdcc")); - profile.setValue(QStringLiteral("qbs.architecture"), - knownArch.architecture.toString()); + profile.setValue(QStringLiteral("cpp.toolchainInstallPath"), compiler.absolutePath()); + profile.setValue(QStringLiteral("qbs.toolchainType"), QStringLiteral("sdcc")); + profile.setValue(QStringLiteral("qbs.architecture"), knownArch.architecture.toString()); qbsInfo() << Tr::tr("Profile '%1' created for '%2'.").arg( profile.name(), compiler.absoluteFilePath()); + + profiles.push_back(std::move(profile)); } return profiles; } -static Version dumpOldSddcCompilerVersion(const QByteArray ¯oDump) -{ - const auto keyToken = QByteArrayLiteral("__SDCC "); - const int startIndex = macroDump.indexOf(keyToken); - if (startIndex == -1) - return Version{}; - const int endIndex = macroDump.indexOf('\n', startIndex); - if (endIndex == -1) - return Version{}; - const auto keyLength = keyToken.length(); - return Version::fromString(QString::fromLatin1( - macroDump.mid(startIndex + keyLength, - endIndex - startIndex - keyLength).replace('_', '.'))); -} - -static Version dumpSdccCompilerVersion(const QFileInfo &compiler) +static Version dumpSdccVersion(const QFileInfo &compiler) { - const QByteArray dump = dumpSdccMacros(compiler); - if (dump.isEmpty()) + const auto macros = dumpMacros([&compiler]() { return dumpOutput(compiler); }); + if (!macros.contains(QLatin1String("__SDCC"))) { + qbsWarning() << Tr::tr("No __SDCC token was found in the compiler dump"); return Version{}; - - 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) { - const auto version = dumpOldSddcCompilerVersion(dump); - if (!version.isValid()) { - qbsWarning() << Tr::tr("No '__SDCC_VERSION_xxx' or '__SDCC' token was found " - "in the compiler dump:\n%1") - .arg(QString::fromUtf8(dump)); - return Version{}; - } - return version; } - return Version{major, minor, patch}; + auto value = macros.value(QLatin1String("__SDCC")); + value.replace(QLatin1Char('_'), QLatin1Char('.')); + return Version::fromString(value); } static std::vector<ToolchainInstallInfo> installedSdccsFromPath() @@ -200,7 +170,7 @@ static std::vector<ToolchainInstallInfo> installedSdccsFromPath() HostOsInfo::appendExecutableSuffix(compilerName))); if (!sdccPath.exists()) continue; - const Version version = dumpSdccCompilerVersion(sdccPath); + const Version version = dumpSdccVersion(sdccPath); infos.push_back({sdccPath, version}); } std::sort(infos.begin(), infos.end()); @@ -293,13 +263,13 @@ void sdccProbe(Settings *settings, std::vector<Profile> &profiles) pathInfos.cbegin(), pathInfos.cend(), std::back_inserter(allInfos)); + if (allInfos.empty()) + qbsInfo() << Tr::tr("No SDCC toolchains found."); + for (const ToolchainInstallInfo &info : allInfos) { const auto newProfiles = createSdccProfileHelper(info, settings); profiles.reserve(profiles.size() + int(newProfiles.size())); std::copy(newProfiles.cbegin(), newProfiles.cend(), std::back_inserter(profiles)); } - - if (allInfos.empty()) - qbsInfo() << Tr::tr("No SDCC toolchains found."); } |