[gnome-builder] pipeline: add IdeBuildStage:check-stdout
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] pipeline: add IdeBuildStage:check-stdout
- Date: Sat, 25 Mar 2017 04:49:37 +0000 (UTC)
commit 230954077d461df81e502e9d0eeb768e406f36b7
Author: Christian Hergert <chergert redhat com>
Date: Fri Mar 24 21:48:29 2017 -0700
pipeline: add IdeBuildStage:check-stdout
This property is used to notify the pipeline that it needs to look at
stdout to extract errors using the error regexes. Typical build systems
such as make, will pass stderr on to the caller. However, others like
Ninja coalesce everything into a single stream, complicating the matter.
This means we burn extra overhead parsing stdout, but in practice, the
output we get from ninja is small enough that it should be roughly
equivalent.
libide/buildsystem/ide-build-pipeline.c | 32 ++++++++++++++++--
libide/buildsystem/ide-build-stage.c | 54 +++++++++++++++++++++++++++++++
libide/buildsystem/ide-build-stage.h | 3 ++
3 files changed, 86 insertions(+), 3 deletions(-)
---
diff --git a/libide/buildsystem/ide-build-pipeline.c b/libide/buildsystem/ide-build-pipeline.c
index 763e331..e109323 100644
--- a/libide/buildsystem/ide-build-pipeline.c
+++ b/libide/buildsystem/ide-build-pipeline.c
@@ -201,6 +201,13 @@ struct _IdeBuildPipeline
* If we are in the middle of a clean operation.
*/
guint in_clean : 1;
+
+ /*
+ * Precalculation if we need to look for errors on stdout. We can't rely
+ * on @current_stage for this, becase log entries might come in
+ * asynchronously and after the processes/stage has completed.
+ */
+ guint errors_on_stdout : 1;
};
typedef enum
@@ -425,7 +432,7 @@ create_diagnostic (IdeBuildPipeline *self,
if (g_str_has_prefix (basedir, self->errfmt_top_dir))
{
basedir += strlen (self->errfmt_top_dir);
- if (*basedir == '/')
+ if (*basedir == G_DIR_SEPARATOR)
basedir++;
}
@@ -466,8 +473,8 @@ ide_build_pipeline_log_observer (IdeBuildLogStream stream,
gpointer user_data)
{
IdeBuildPipeline *self = user_data;
- const gchar *enterdir;
g_autofree gchar *filtered_message = NULL;
+ const gchar *enterdir;
g_assert (stream == IDE_BUILD_LOG_STDOUT || stream == IDE_BUILD_LOG_STDERR);
g_assert (IDE_IS_BUILD_PIPELINE (self));
@@ -519,7 +526,13 @@ ide_build_pipeline_log_observer (IdeBuildLogStream stream,
return;
}
}
- else if (stream == IDE_BUILD_LOG_STDERR)
+
+ /*
+ * Unfortunately, some build engines such as Ninja refuse to pass errors on
+ * stderr like the tooling they abstract. So we must parse stdout in addition
+ * to stderr to extract errors.
+ */
+ if (stream == IDE_BUILD_LOG_STDERR || self->errors_on_stdout)
{
for (guint i = 0; i < self->errfmts->len; i++)
{
@@ -664,6 +677,19 @@ ide_build_pipeline_real_started (IdeBuildPipeline *self)
g_assert (IDE_IS_BUILD_PIPELINE (self));
+ self->errors_on_stdout = FALSE;
+
+ for (guint i = 0; i < self->pipeline->len; i++)
+ {
+ PipelineEntry *entry = &g_array_index (self->pipeline, PipelineEntry, i);
+
+ if (ide_build_stage_get_check_stdout (entry->stage))
+ {
+ self->errors_on_stdout = TRUE;
+ break;
+ }
+ }
+
IDE_EXIT;
}
diff --git a/libide/buildsystem/ide-build-stage.c b/libide/buildsystem/ide-build-stage.c
index b91ab2e..e0742be 100644
--- a/libide/buildsystem/ide-build-stage.c
+++ b/libide/buildsystem/ide-build-stage.c
@@ -37,12 +37,14 @@ typedef struct
guint completed : 1;
guint disabled : 1;
guint transient : 1;
+ guint check_stdout : 1;
} IdeBuildStagePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (IdeBuildStage, ide_build_stage, IDE_TYPE_OBJECT)
enum {
PROP_0,
+ PROP_CHECK_STDOUT,
PROP_COMPLETED,
PROP_DISABLED,
PROP_NAME,
@@ -265,6 +267,10 @@ ide_build_stage_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_CHECK_STDOUT:
+ g_value_set_boolean (value, ide_build_stage_get_check_stdout (self));
+ break;
+
case PROP_COMPLETED:
g_value_set_boolean (value, ide_build_stage_get_completed (self));
break;
@@ -296,6 +302,10 @@ ide_build_stage_set_property (GObject *object,
switch (prop_id)
{
+ case PROP_CHECK_STDOUT:
+ ide_build_stage_set_check_stdout (self, g_value_get_boolean (value));
+ break;
+
case PROP_COMPLETED:
ide_build_stage_set_completed (self, g_value_get_boolean (value));
break;
@@ -334,6 +344,23 @@ ide_build_stage_class_init (IdeBuildStageClass *klass)
klass->chain = ide_build_stage_real_chain;
/**
+ * IdeBuildStage:check-stdout:
+ *
+ * Most build systems will preserve stderr for the processes they call, such
+ * as gcc, clang, and others. However, if your build system redirects all
+ * output to stdout, you may need to set this property to %TRUE to ensure
+ * that Builder will extract errors from stdout.
+ *
+ * One such example is Ninja.
+ */
+ properties [PROP_CHECK_STDOUT] =
+ g_param_spec_boolean ("check-stdout",
+ "Check STDOUT",
+ "If STDOUT should be checked for errors using error regexes",
+ FALSE,
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+ /**
* IdeBuildStage:completed:
*
* The "completed" property is set to %TRUE after the pipeline has
@@ -999,3 +1026,30 @@ ide_build_stage_set_disabled (IdeBuildStage *self,
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_DISABLED]);
}
}
+
+gboolean
+ide_build_stage_get_check_stdout (IdeBuildStage *self)
+{
+ IdeBuildStagePrivate *priv = ide_build_stage_get_instance_private (self);
+
+ g_return_val_if_fail (IDE_IS_BUILD_STAGE (self), FALSE);
+
+ return priv->check_stdout;
+}
+
+void
+ide_build_stage_set_check_stdout (IdeBuildStage *self,
+ gboolean check_stdout)
+{
+ IdeBuildStagePrivate *priv = ide_build_stage_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_BUILD_STAGE (self));
+
+ check_stdout = !!check_stdout;
+
+ if (check_stdout != priv->check_stdout)
+ {
+ priv->check_stdout = check_stdout;
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_CHECK_STDOUT]);
+ }
+}
diff --git a/libide/buildsystem/ide-build-stage.h b/libide/buildsystem/ide-build-stage.h
index 832dc61..57e6b6a 100644
--- a/libide/buildsystem/ide-build-stage.h
+++ b/libide/buildsystem/ide-build-stage.h
@@ -192,6 +192,9 @@ void ide_build_stage_set_completed (IdeBuildStage *self,
gboolean ide_build_stage_get_disabled (IdeBuildStage *self);
void ide_build_stage_set_disabled (IdeBuildStage *self,
gboolean disabled);
+gboolean ide_build_stage_get_check_stdout (IdeBuildStage *self);
+void ide_build_stage_set_check_stdout (IdeBuildStage *self,
+ gboolean check_stdout);
gboolean ide_build_stage_get_transient (IdeBuildStage *self);
void ide_build_stage_set_transient (IdeBuildStage *self,
gboolean transient);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]