meta.c: add .MAKE.META.CMP_FILTER

On rare occasions it is useful to be able to filter command lines
before comparison.
This commit is contained in:
sjg 2022-01-13 04:51:50 +00:00
parent 4cb00b5924
commit 3e72ec5137
2 changed files with 52 additions and 4 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: make.1,v 1.300 2021/12/12 20:45:48 sjg Exp $
.\" $NetBSD: make.1,v 1.301 2022/01/13 04:51:50 sjg Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
.Dd December 12, 2021
.Dd January 12, 2022
.Dt MAKE 1
.Os
.Sh NAME
@ -954,6 +954,12 @@ If a file that was generated outside of
.Va .OBJDIR
but within said bailiwick is missing,
the current target is considered out-of-date.
.It Va .MAKE.META.CMP_FILTER
In "meta" mode, it can (very rarely!) be useful to filter command
lines before comparison.
This variable can be set to a set of modifiers that will be applied to
each line of the old and new command that differ, if the filtered
commands still differ, the target is considered out-of-date.
.It Va .MAKE.META.CREATED
In "meta" mode, this variable contains a list of all the meta files
updated.

View File

@ -1,4 +1,4 @@
/* $NetBSD: meta.c,v 1.186 2021/12/13 01:51:12 rillig Exp $ */
/* $NetBSD: meta.c,v 1.187 2022/01/13 04:51:50 sjg Exp $ */
/*
* Implement 'meta' mode.
@ -65,6 +65,9 @@ static char *metaIgnorePathsStr; /* string storage for the list */
#ifndef MAKE_META_IGNORE_FILTER
#define MAKE_META_IGNORE_FILTER ".MAKE.META.IGNORE_FILTER"
#endif
#ifndef MAKE_META_CMP_FILTER
#define MAKE_META_CMP_FILTER ".MAKE.META.CMP_FILTER"
#endif
bool useMeta = false;
static bool useFilemon = false;
@ -76,6 +79,7 @@ static bool metaVerbose = false;
static bool metaIgnoreCMDs = false; /* ignore CMDs in .meta files */
static bool metaIgnorePatterns = false; /* do we need to do pattern matches */
static bool metaIgnoreFilter = false; /* do we have more complex filtering? */
static bool metaCmpFilter = false; /* do we have CMP_FILTER ? */
static bool metaCurdirOk = false; /* write .meta in .CURDIR Ok? */
static bool metaSilent = false; /* if we have a .meta be SILENT */
@ -661,6 +665,11 @@ meta_mode_init(const char *make_mode)
metaIgnoreFilter = true;
FStr_Done(&value);
}
value = Var_Value(SCOPE_GLOBAL, MAKE_META_CMP_FILTER);
if (value.str != NULL) {
metaCmpFilter = true;
FStr_Done(&value);
}
}
/*
@ -1077,6 +1086,39 @@ append_if_new(StringList *list, const char *str)
Lst_Append(list, bmake_strdup(str));
}
static char *
meta_filter_cmd(Buffer *buf, GNode *gn, char *s)
{
Buf_Clear(buf);
Buf_AddStr(buf, "${");
Buf_AddStr(buf, s);
Buf_AddStr(buf, ":L:${" MAKE_META_CMP_FILTER ":ts:}}");
Var_Subst(buf->data, gn, VARE_WANTRES, &s);
return s;
}
static int
meta_cmd_cmp(GNode *gn, char *a, char *b)
{
static int once = 0;
static Buffer buf;
int rc;
rc = strcmp(a, b);
if (rc == 0 || !metaCmpFilter)
return rc;
if (!once) {
once++;
Buf_InitSize(&buf, BUFSIZ);
}
a = meta_filter_cmd(&buf, gn, a);
b = meta_filter_cmd(&buf, gn, b);
rc = strcmp(a, b);
free(a);
free(b);
return rc;
}
bool
meta_oodate(GNode *gn, bool oodate)
{
@ -1552,7 +1594,7 @@ meta_oodate(GNode *gn, bool oodate)
if (p != NULL &&
!hasOODATE &&
!(gn->type & OP_NOMETA_CMP) &&
(strcmp(p, cmd) != 0)) {
(meta_cmd_cmp(gn, p, cmd) != 0)) {
DEBUG4(META, "%s: %d: a build command has changed\n%s\nvs\n%s\n",
fname, lineno, p, cmd);
if (!metaIgnoreCMDs)