From e9dd614d73fc625845a0de089edae3a8433e30c1 Mon Sep 17 00:00:00 2001 From: Dmitry Goncharov Date: Mon, 20 Feb 2023 15:17:24 -0500 Subject: [SV 63821] Don't set up default suffix rules if makefile sets -r When built-in rules are disabled by adding -r to MAKEFLAGS in the makefile, don't add suffix rules at all so that if suffixes are added back via .SUFFIXES, the rules are still not there. * src/main.c (main): Set default suffix rules after parsing makefiles. * src/default.c (install_default_suffix_rules): Install a default suffix rule only if there is no user defined rule. * tests/scripts/features/suffixrules: Add tests. --- src/default.c | 20 ++++++------ src/main.c | 12 +++---- tests/scripts/features/suffixrules | 65 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 16 deletions(-) diff --git a/src/default.c b/src/default.c index ffb5f98c..e396269b 100644 --- a/src/default.c +++ b/src/default.c @@ -707,7 +707,7 @@ set_default_suffixes (void) installed after. */ void -install_default_suffix_rules (void) +install_default_suffix_rules () { const char **s; @@ -717,14 +717,16 @@ install_default_suffix_rules (void) for (s = default_suffix_rules; *s != 0; s += 2) { struct file *f = enter_file (strcache_add (s[0])); - /* This function should run before any makefile is parsed. */ - assert (f->cmds == 0); - f->cmds = xmalloc (sizeof (struct commands)); - f->cmds->fileinfo.filenm = 0; - f->cmds->commands = xstrdup (s[1]); - f->cmds->command_lines = 0; - f->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT; - f->builtin = 1; + /* Install the default rule only if there is no user defined rule. */ + if (!f->cmds) + { + f->cmds = xmalloc (sizeof (struct commands)); + f->cmds->fileinfo.filenm = NULL; + f->cmds->commands = xstrdup (s[1]); + f->cmds->command_lines = NULL; + f->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT; + f->builtin = 1; + } } } diff --git a/src/main.c b/src/main.c index dde0d77d..e62aee60 100644 --- a/src/main.c +++ b/src/main.c @@ -2028,13 +2028,6 @@ main (int argc, char **argv, char **envp) /* Define the initial list of suffixes for old-style rules. */ set_default_suffixes (); - /* Define the file rules for the built-in suffix rules. These will later - be converted into pattern rules. We used to do this in - install_default_implicit_rules, but since that happens after reading - makefiles, it results in the built-in pattern rules taking precedence - over makefile-specified suffix rules, which is wrong. */ - install_default_suffix_rules (); - /* Define some internal and special variables. */ define_automatic_variables (); @@ -2280,6 +2273,11 @@ main (int argc, char **argv, char **envp) define_makeflags (0); + /* Define the file rules for the built-in suffix rules. These will later + be converted into pattern rules. */ + + install_default_suffix_rules (); + /* Make each 'struct goaldep' point at the 'struct file' for the file depended on. Also do magic for special targets. */ diff --git a/tests/scripts/features/suffixrules b/tests/scripts/features/suffixrules index b8f46526..5e969b2a 100644 --- a/tests/scripts/features/suffixrules +++ b/tests/scripts/features/suffixrules @@ -95,5 +95,70 @@ run_make_test(undef, unlink('foo.baz', 'foo.biz', 'foo.bar'); + +touch('hello.c'); +unlink('hello.o'); + +# sv 63821. +# Default suffix rule .c.o. + +run_make_test('all: hello.o', 'COMPILE.c=@echo OUTPUT_OPTION=', 'hello.c'); + +# User defined rules beat built-in rules. + +run_make_test(q! +all: hello.o +.c.o:; $(info $@ user defined .c.o rule) +!, '', "hello.o user defined .c.o rule\n#MAKE#: Nothing to be done for 'all'.\n"); + +# sv 63821. +# The same as above, but suffixes are cleared. + +run_make_test(q! +all: hello.o +.SUFFIXES: +.c.o:; $(info $@ user defined .c.o rule) +!, '', "#MAKE#: *** No rule to make target 'hello.o', needed by 'all'. Stop.\n", 512); + +# sv 63821. +# Suffixes are cleared and defined in the makefile. + +run_make_test(q! +all: hello.o +.SUFFIXES: +.SUFFIXES: .c .o +.c.o:; $(info $@ user defined .c.o rule) +!, '', "hello.o user defined .c.o rule\n#MAKE#: Nothing to be done for 'all'.\n"); + +# sv 63821. +# When built-in rules are disabled, but certain suffixes are added to +# .SUFFIXES, make should exit with the 'No rule...' error message. + +run_make_test(q! +.SUFFIXES: .c .o +all: hello.o +!, '-r', "#MAKE#: *** No rule to make target 'hello.o', needed by 'all'. Stop.\n", 512); + +# sv 63821. +# Same as above, but this time built-in rules are disabled inside the makefile. + +run_make_test(q! +MAKEFLAGS += -r +.SUFFIXES: .c .o +all: hello.o +!, '', "#MAKE#: *** No rule to make target 'hello.o', needed by 'all'. Stop.\n", 512); + +# sv 63821. +# Same as above, but this time there is a rule. + +run_make_test(q! +all: hello.o +MAKEFLAGS += -r +.SUFFIXES: .c .o +.c.o:; $(info $@ user defined .c.o rule) +!, '', "hello.o user defined .c.o rule\n#MAKE#: Nothing to be done for 'all'.\n"); + +unlink('hello.c', 'hello.o'); + # Complete 1; -- cgit v1.2.3