]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 65739] Add warning circular-dep.
authorDmitry Goncharov <dgoncharov@users.sf.net>
Sun, 19 May 2024 22:56:12 +0000 (18:56 -0400)
committerPaul Smith <psmith@gnu.org>
Sun, 4 Aug 2024 19:21:59 +0000 (15:21 -0400)
Add a warning to control circular dependency detection.  Use "warn" as
the default action to be backward-compatible.

* src/warning.h (enum warning_type): Add warning type wt_circular_dep.
* src/warning.c (warn_init): Set default wt_circular_dep to w_warn.
* src/remake.c (update_file_1): Consult the circular-dep warning to
handle circular dependencies.
* tests/scripts/options/warn: Test --warn circular-dep flag.
* tests/scripts/variables/WARNINGS: Test .WARNINGS circular-dep flag.
* doc/make.texi: Document circular-dep warning.
* doc/make.1: Ditto.

NEWS
doc/make.1
doc/make.texi
src/remake.c
src/warning.c
src/warning.h
tests/scripts/options/warn
tests/scripts/variables/WARNINGS

diff --git a/NEWS b/NEWS
index c9d8ff5e433cd8d2fe2493ec095a4782cc9d6af3..216e17cc31d434d29e15500d90bd767e651df27b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -83,6 +83,9 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=111&se
   defined in the makefiles, one per line, then exit with success.  No recipes
   are invoked and no makefiles are re-built.
 
+* Warnings for detecting circular dependencies are controllable via warning
+  reporting, with the name "circular-dep".
+
 * 'make --print-data-base' (or 'make -p') now outputs time of day
   using the same form as for file timestamps, e.g., "2023-05-10
   10:43:57.570558743".  Previously it used the form "Wed May 10
index bb394bde9811df907a4e4cf94fa478a9c93a1ec3..059bf7521c440401739caf73e6a57fda39f51126 100644 (file)
@@ -379,10 +379,13 @@ can be an action; one of
 or
 .I error
 to set the default action for all warnings, or it can be a specific warning:
+.I circular-dep
+(finding a circular dependency),
+.I invalid-ref
+(referencing an invalid variable name),
 .I invalid-var
 (assigning to an invalid variable name),
-.I invalid-ref
-(referencing an invalid variable name), or
+or
 .I undefined-var
 (referencing an undefined variable).  The behavior of each warning can be set
 by adding
index 8b0f45068e7599f20c72079cfbcff46db35c19db..a7e7bd40b37122f8af0dab4b73a6e68289166914 100644 (file)
@@ -9447,11 +9447,13 @@ Show an error for the usage and immediately stop processing the makefile.
 The types of warnings GNU Make can detect are:
 
 @table @samp
-@item invalid-var
-@findex invalid-var
-@cindex warning invalid variable
-Assigning to an invalid variable name (e.g., a name containing whitespace).
-The default action is @samp{warn}.
+@item circular-dep
+@findex circular-dep
+@cindex warning circular dependency
+Finding a loop in the dependency graph (the prerequisites of a target contain
+or depend on the target itself).  If the action is not @samp{error}, the
+circular reference is dropped from the graph before continuing.  The default
+action is @samp{warn}.
 
 @item invalid-ref
 @findex invalid-ref
@@ -9459,6 +9461,12 @@ The default action is @samp{warn}.
 Using an invalid variable name in a variable reference.  The default action is
 @samp{warn}.
 
+@item invalid-var
+@findex invalid-var
+@cindex warning invalid variable
+Assigning to an invalid variable name (e.g., a name containing whitespace).
+The default action is @samp{warn}.
+
 @item undefined-var
 @findex undefined-var
 @cindex warning undefined variable
index ee8971e75d5cb6f81dc08a888d38ca12143975ed..fcc5cc12a194d4afc5c176372723dbc7932f84a0 100644 (file)
@@ -20,6 +20,7 @@ this program.  If not, see <https://www.gnu.org/licenses/>.  */
 #include "commands.h"
 #include "dep.h"
 #include "variable.h"
+#include "warning.h"
 #include "debug.h"
 
 #include <assert.h>
@@ -635,8 +636,14 @@ update_file_1 (struct file *file, unsigned int depth)
 
           if (is_updating (d->file))
             {
-              OSS (error, NILF, _("circular %s <- %s dependency dropped"),
-                   file->name, d->file->name);
+              /* Avoid macro warning, bacause its output differs from that of
+                 older makes. */
+              if (warn_error (wt_circular_dep))
+                OSS (fatal, NILF, _("circular %s <- %s dependency detected"),
+                     file->name, d->file->name);
+              if (warn_check (wt_circular_dep))
+                OSS (error, NILF, _("circular %s <- %s dependency dropped"),
+                     file->name, d->file->name);
 
               if (lastd == 0)
                 file->deps = du->next;
index 35950f77002260c587b53bd5a0c70a95ece8c72e..26584e92761ae07ad73f998628045f00b85a95ca 100644 (file)
@@ -34,7 +34,8 @@ static const char *w_action_map[w_error+1] = {NULL, "ignore", "warn", "error"};
 static const char *w_name_map[wt_max] = {
                                           "invalid-var",
                                           "invalid-ref",
-                                          "undefined-var"
+                                          "undefined-var",
+                                          "circular-dep"
                                         };
 
 #define encode_warn_action(_b,_s) \
@@ -66,6 +67,7 @@ warn_init ()
   warn_default.actions[wt_invalid_var] = w_warn;
   warn_default.actions[wt_invalid_ref] = w_warn;
   warn_default.actions[wt_undefined_var] = w_ignore;
+  warn_default.actions[wt_circular_dep] = w_warn;
 
   set_warnings ();
 }
index b8fcae973cd1f712e6a881028b39298d44d3ff31..fabbe01a5a423261c462cc8f8a0947b861ed0073 100644 (file)
@@ -20,6 +20,7 @@ enum warning_type
     wt_invalid_var = 0, /* Assign to an invalid variable name.  */
     wt_invalid_ref,     /* Reference an invalid variable name.  */
     wt_undefined_var,   /* Reference an undefined variable name.  */
+    wt_circular_dep,    /* A target depends on itself.  */
     wt_max
   };
 
index 2b862a58b9b2ce0f2292658f091f3c376757a119..5285d8734d07633ce4fd830f99c74fc3f551fc83 100644 (file)
@@ -166,4 +166,17 @@ run_make_test(undef, '--warn=no-such-warn',
 run_make_test(undef, '--warn=invalid-var:no-such-action',
     "#MAKE#: *** unknown warning action 'no-such-action'.  Stop.", 512);
 
+# sv 65739. Circular dependency.
+run_make_test(q!
+hello: hello; @:
+!,
+              '', "#MAKE#: circular hello <- hello dependency dropped\n");
+
+run_make_test(undef, '--warn=error', "#MAKE#: *** circular hello <- hello dependency detected.  Stop.\n", 512);
+run_make_test(undef, '--warn=circular-dep:error', "#MAKE#: *** circular hello <- hello dependency detected.  Stop.\n", 512);
+run_make_test(undef, '--warn=warn', "#MAKE#: circular hello <- hello dependency dropped\n");
+run_make_test(undef, '--warn=circular-dep:warn', "#MAKE#: circular hello <- hello dependency dropped\n");
+run_make_test(undef, '--warn=ignore', '');
+run_make_test(undef, '--warn=circular-dep:ignore', '');
+
 1;
index 870a41d01a16f9148fd5ec8bbb147411b2482312..b6ce2613dc7ccc9c5f030f5b510ffdf08e3185f2 100644 (file)
@@ -154,6 +154,27 @@ all:;
 !,
     '',"#MAKEFILE#:2: unknown warning action 'no-such-action': ignored\n#MAKE#: 'all' is up to date.");
 
+# sv 65739. Circular dependency.
+run_make_test(q!
+hello: hello; @:
+!,
+              '', "#MAKE#: circular hello <- hello dependency dropped\n");
+run_make_test(q!
+.WARNINGS = circular-dep:error
+hello: hello; @:
+!,
+              '', "#MAKE#: *** circular hello <- hello dependency detected.  Stop.\n", 512);
+run_make_test(q!
+.WARNINGS = circular-dep:warn
+hello: hello; @:
+!,
+              '', "#MAKE#: circular hello <- hello dependency dropped\n");
+run_make_test(q!
+.WARNINGS = circular-dep:ignore
+hello: hello; @:
+!,
+              '', '');
+
 
 # Validate .WARNINGS set as target-specific variables
 # This is not supported (yet...?)