Compile: add ability to parse standard output in build

When working with make wrapper scripts, sometimes they forward
everything to stdout. When this happens failures are not parsed,
and the are not "clickable" in QtC.
This patch adds an option to enable parsing of standard output.

Change-Id: I44b283dbdf6286f90c546898d496bff41de0d5ed
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Petar Perisin
2021-08-05 22:47:23 +02:00
parent 81cbb0a33c
commit fe9a1f52c1
5 changed files with 28 additions and 2 deletions

View File

@@ -217,6 +217,7 @@ public:
bool boldFontEnabled = true; bool boldFontEnabled = true;
bool prependCarriageReturn = false; bool prependCarriageReturn = false;
bool prependLineFeed = false; bool prependLineFeed = false;
bool forwardStdOutToStdError = false;
}; };
OutputFormatter::OutputFormatter() : d(new Private) { } OutputFormatter::OutputFormatter() : d(new Private) { }
@@ -574,6 +575,11 @@ void OutputFormatter::setBoldFontEnabled(bool enabled)
d->formats[ErrorMessageFormat].setFontWeight(fontWeight); d->formats[ErrorMessageFormat].setFontWeight(fontWeight);
} }
void OutputFormatter::setForwardStdOutToStdError(bool enabled)
{
d->forwardStdOutToStdError = enabled;
}
void OutputFormatter::flush() void OutputFormatter::flush()
{ {
if (!d->incompleteLine.first.isEmpty()) if (!d->incompleteLine.first.isEmpty())
@@ -608,7 +614,7 @@ void OutputFormatter::dropSearchDir(const FilePath &dir)
OutputFormat OutputFormatter::outputTypeForParser(const OutputLineParser *parser, OutputFormat OutputFormatter::outputTypeForParser(const OutputLineParser *parser,
OutputFormat type) const OutputFormat type) const
{ {
if (type == StdOutFormat && parser->needsRedirection()) if (type == StdOutFormat && (parser->needsRedirection() || d->forwardStdOutToStdError))
return StdErrFormat; return StdErrFormat;
return type; return type;
} }

View File

@@ -155,6 +155,7 @@ public:
bool handleFileLink(const QString &href); bool handleFileLink(const QString &href);
void handleLink(const QString &href); void handleLink(const QString &href);
void setBoldFontEnabled(bool enabled); void setBoldFontEnabled(bool enabled);
void setForwardStdOutToStdError(bool enabled);
bool hasFatalErrors() const; bool hasFatalErrors() const;

View File

@@ -69,6 +69,7 @@ const char BUILD_STEP_LIST_PREFIX[] = "ProjectExplorer.BuildConfiguration.BuildS
const char CLEAR_SYSTEM_ENVIRONMENT_KEY[] = "ProjectExplorer.BuildConfiguration.ClearSystemEnvironment"; const char CLEAR_SYSTEM_ENVIRONMENT_KEY[] = "ProjectExplorer.BuildConfiguration.ClearSystemEnvironment";
const char USER_ENVIRONMENT_CHANGES_KEY[] = "ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"; const char USER_ENVIRONMENT_CHANGES_KEY[] = "ProjectExplorer.BuildConfiguration.UserEnvironmentChanges";
const char CUSTOM_PARSERS_KEY[] = "ProjectExplorer.BuildConfiguration.CustomParsers"; const char CUSTOM_PARSERS_KEY[] = "ProjectExplorer.BuildConfiguration.CustomParsers";
const char PARSE_STD_OUT_KEY[] = "ProjectExplorer.BuildConfiguration.ParseStandardOutput";
namespace ProjectExplorer { namespace ProjectExplorer {
namespace Internal { namespace Internal {
@@ -117,9 +118,17 @@ class CustomParsersBuildWidget : public NamedWidget
public: public:
CustomParsersBuildWidget(BuildConfiguration *bc) : NamedWidget(tr("Custom Output Parsers")) CustomParsersBuildWidget(BuildConfiguration *bc) : NamedWidget(tr("Custom Output Parsers"))
{ {
const auto selectionWidget = new CustomParsersSelectionWidget(this);
const auto layout = new QVBoxLayout(this); const auto layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
const auto pasteStdOutCB = new QCheckBox(tr("Parse standard output during build"), this);
pasteStdOutCB->setToolTip(tr("Check this to make output parsers look for diagnostics "
"on stdout rather than stderr"));
pasteStdOutCB->setChecked(bc->parseStdOut());
layout->addWidget(pasteStdOutCB);
connect(pasteStdOutCB, &QCheckBox::clicked, bc, &BuildConfiguration::setParseStdOut);
const auto selectionWidget = new CustomParsersSelectionWidget(this);
layout->addWidget(selectionWidget); layout->addWidget(selectionWidget);
connect(selectionWidget, &CustomParsersSelectionWidget::selectionChanged, connect(selectionWidget, &CustomParsersSelectionWidget::selectionChanged,
@@ -152,6 +161,7 @@ public:
QList<Utils::Id> m_initialBuildSteps; QList<Utils::Id> m_initialBuildSteps;
QList<Utils::Id> m_initialCleanSteps; QList<Utils::Id> m_initialCleanSteps;
Utils::MacroExpander m_macroExpander; Utils::MacroExpander m_macroExpander;
bool m_parseStdOut = false;
QList<Utils::Id> m_customParsers; QList<Utils::Id> m_customParsers;
// FIXME: Remove. // FIXME: Remove.
@@ -387,6 +397,7 @@ QVariantMap BuildConfiguration::toMap() const
map.insert(QLatin1String(BUILD_STEP_LIST_PREFIX) + QString::number(0), d->m_buildSteps.toMap()); map.insert(QLatin1String(BUILD_STEP_LIST_PREFIX) + QString::number(0), d->m_buildSteps.toMap());
map.insert(QLatin1String(BUILD_STEP_LIST_PREFIX) + QString::number(1), d->m_cleanSteps.toMap()); map.insert(QLatin1String(BUILD_STEP_LIST_PREFIX) + QString::number(1), d->m_cleanSteps.toMap());
map.insert(PARSE_STD_OUT_KEY, d->m_parseStdOut);
map.insert(CUSTOM_PARSERS_KEY, transform(d->m_customParsers,&Utils::Id::toSetting)); map.insert(CUSTOM_PARSERS_KEY, transform(d->m_customParsers,&Utils::Id::toSetting));
return map; return map;
@@ -421,6 +432,7 @@ bool BuildConfiguration::fromMap(const QVariantMap &map)
} }
} }
d->m_parseStdOut = map.value(PARSE_STD_OUT_KEY).toBool();
d->m_customParsers = transform(map.value(CUSTOM_PARSERS_KEY).toList(), &Utils::Id::fromSetting); d->m_customParsers = transform(map.value(CUSTOM_PARSERS_KEY).toList(), &Utils::Id::fromSetting);
const bool res = ProjectConfiguration::fromMap(map); const bool res = ProjectConfiguration::fromMap(map);
@@ -518,6 +530,9 @@ void BuildConfiguration::setCustomParsers(const QList<Utils::Id> &parsers)
d->m_customParsers = parsers; d->m_customParsers = parsers;
} }
bool BuildConfiguration::parseStdOut() const { return d->m_parseStdOut; }
void BuildConfiguration::setParseStdOut(bool b) { d->m_parseStdOut = b; }
bool BuildConfiguration::useSystemEnvironment() const bool BuildConfiguration::useSystemEnvironment() const
{ {
return !d->m_clearSystemEnvironment; return !d->m_clearSystemEnvironment;

View File

@@ -79,6 +79,8 @@ public:
virtual void addToEnvironment(Utils::Environment &env) const; virtual void addToEnvironment(Utils::Environment &env) const;
bool parseStdOut() const;
void setParseStdOut(bool b);
const QList<Utils::Id> customParsers() const; const QList<Utils::Id> customParsers() const;
void setCustomParsers(const QList<Utils::Id> &parsers); void setCustomParsers(const QList<Utils::Id> &parsers);

View File

@@ -282,6 +282,8 @@ void BuildStep::setupOutputFormatter(OutputFormatter *formatter)
if (Internal::CustomParser * const parser = Internal::CustomParser::createFromId(id)) if (Internal::CustomParser * const parser = Internal::CustomParser::createFromId(id))
formatter->addLineParser(parser); formatter->addLineParser(parser);
} }
formatter->setForwardStdOutToStdError(buildConfiguration()->parseStdOut());
} }
Utils::FileInProjectFinder fileFinder; Utils::FileInProjectFinder fileFinder;
fileFinder.setProjectDirectory(project()->projectDirectory()); fileFinder.setProjectDirectory(project()->projectDirectory());