From f907a4d90c895f04ee7497a5f1b58ad1fd3cddb5 Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Mon, 28 Sep 2009 23:08:49 +0000 Subject: [PATCH] - Update manual description for pattern rule search algorithm - Add new "-all" flag to the test suite to run tests that don't pass yet - Add some non-passing tests - Fix from Andreas Buening for OS/2. --- ChangeLog | 16 ++++++ doc/make.texi | 83 +++++++++++++++++++----------- job.c | 7 ++- tests/ChangeLog | 13 +++++ tests/run_make_tests.pl | 23 +++++---- tests/scripts/features/se_explicit | 27 ++++++++++ tests/scripts/functions/shell | 9 ++++ tests/test_driver.pl | 1 + 8 files changed, 138 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3b4a6dcc..177a2016 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2009-09-28 Paul Smith + + * doc/make.texi (Pattern Intro): Move the match algorithm + discussion into the "Pattern Match" node. + (Pattern Match): Expand on the pattern rule matching algorithm. + +2009-09-28 Andreas Buening + + * job.c (construct_command_argv_internal) [OS2]: Don't eat too + much of the command line on a single pass. + 2009-09-28 Boris Kolpackov * varible.c (create_pattern_var): Insert variables into the @@ -18,6 +29,11 @@ * NEWS: Add a note about the new behavior. +2009-09-27 Paul Smith + + * doc/make.texi (Double-Colon): Mention that pattern rules with + double-colons have a different meaning. Savannah bug #27497. + 2009-09-27 Juan Manuel Guerrero * configh.dos.template: Remove unconditional definition of diff --git a/doc/make.texi b/doc/make.texi index 82df90a2..8f86c0cc 100644 --- a/doc/make.texi +++ b/doc/make.texi @@ -3190,9 +3190,11 @@ to precisely the targets specified. @cindex multiple rules for one target (@code{::}) @cindex @code{::} rules (double-colon) -@dfn{Double-colon} rules are rules written with @samp{::} instead of -@samp{:} after the target names. They are handled differently from -ordinary rules when the same target appears in more than one rule. +@dfn{Double-colon} rules are explicit rules written with @samp{::} +instead of @samp{:} after the target names. They are handled +differently from ordinary rules when the same target appears in more +than one rule. Pattern rules with double-colons have an entirely +different meaning (@pxref{Match-Anything Rules}). When a target appears in multiple rules, all the rules must be the same type: all ordinary, or all double-colon. If they are double-colon, each @@ -9148,6 +9150,10 @@ in fact any prerequisites at all. Such a rule is effectively a general wildcard. It provides a way to make any file that matches the target pattern. @xref{Last Resort}. +More than one pattern rule may match a target. In this case +@code{make} will choose the ``best fit'' rule. @xref{Pattern Match, +,How Patterns Match}. + @c !!! The end of of this paragraph should be rewritten. --bob Pattern rules may have more than one target. Unlike normal rules, this does not act as many different rules with the same prerequisites @@ -9163,33 +9169,6 @@ updated themselves. @cindex multiple targets, in pattern rule @cindex target, multiple in pattern rule -It is possible that several pattern rules can be used to update a -target. In this case @code{make} considers rules which produce -shorter stems first. This results in more specific rules being -preferred to the more generic ones, for example: - -@example -%.o: %.c - $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@@ - -lib/%.o: lib/%.c - $(CC) -fPIC -c $(CFLAGS) $(CPPFLAGS) $< -o $@@ - -all: foo.o lib/bar.o -@end example - -In this example the second rule will be used to update @file{lib/bar.o} -even though the first rule can also be used. - -Pattern rules which result in the same stem length are considered in -the order in which they appear in the makefile. Of equally applicable -rules, only the first one found is used. The rules you write take -precedence over those that are built in. Note however, that a rule whose -prerequisites actually exist or are mentioned always takes priority over a -rule with prerequisites that must be made by chaining other implicit rules. -@cindex pattern rules, order of -@cindex order of pattern rules - @node Pattern Examples, Automatic Variables, Pattern Intro, Pattern Rules @subsection Pattern Rule Examples @@ -9502,6 +9481,50 @@ rest of the stem is substituted for the @samp{%}. The stem @samp{src/a} with a prerequisite pattern @samp{c%r} gives the file name @file{src/car}.@refill +@cindex pattern rules, order of +@cindex order of pattern rules +A pattern rule can be used to build a given file only if there is a +target pattern that matches the file name, @emph{and} all +prerequisites in that rule either exist or can be built. The rules +you write take precedence over those that are built in. Note however, +that a rule whose prerequisites actually exist or are mentioned always +takes priority over a rule with prerequisites that must be made by +chaining other implicit rules. + +@cindex stem, shortest +It is possible that more than one pattern rule will meet these +criteria. In that case, @code{make} will choose the rule with the +shortest stem (that is, the pattern that matches most specifically). +If more than one pattern rule has the shortest stem, @code{make} will +choose the first one found in the makefile. + +This algorithm results in more specific rules being preferred over +more generic ones; for example: + +@example +%.o: %.c + $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@@ + +%.o : %.f + $(COMPILE.F) $(OUTPUT_OPTION) $< + +lib/%.o: lib/%.c + $(CC) -fPIC -c $(CFLAGS) $(CPPFLAGS) $< -o $@@ +@end example + +Given these rules and asked to build @file{bar.o} where both +@file{bar.c} and @file{bar.f} exist, @code{make} will choose the first +rule and compile @file{bar.c} into @file{bar.o}. In the same +situation where @file{bar.c} does not exist, then @code{make} will +choose the second rule and compile @file{bar.f} into @file{bar.o}. + +If @code{make} is asked to build @file{lib/bar.o} and both +@file{lib/bar.c} and @file{lib/bar.f} exist, then the third rule will +be chosen since the stem for this rule (@samp{bar}) is shorter than +the stem for the first rule (@samp{lib/bar}). If @file{lib/bar.c} +does not exist then the third rule is not eligible and the second rule +will be used, even though the stem is longer. + @node Match-Anything Rules, Canceling Rules, Pattern Match, Pattern Rules @subsection Match-Anything Pattern Rules diff --git a/job.c b/job.c index b3fef25e..54e17c4d 100644 --- a/job.c +++ b/job.c @@ -2845,8 +2845,11 @@ construct_command_argv_internal (char *line, char **restp, char *shell, char *p = new_line; char *q = new_line; memcpy (new_line, line, line_len + 1); - /* replace all backslash-newline combination and also following tabs */ - while (*q != '\0') + /* Replace all backslash-newline combination and also following tabs. + Important: stop at the first '\n' because that's what the loop above + did. The next line starting at restp[0] will be executed during the + next call of this function. */ + while (*q != '\0' && *q != '\n') { if (q[0] == '\\' && q[1] == '\n') q += 2; /* remove '\\' and '\n' */ diff --git a/tests/ChangeLog b/tests/ChangeLog index 7110e4a1..5800d667 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,16 @@ +2009-09-28 Paul Smith + + * scripts/functions/shell: Add regression test for Savannah bug + #20513 (still open). + + * scripts/features/se_explicit: Add regression tests for Savannah + bug #25780 (still open). + + * run_make_tests.pl (valid_option): Add a new flag, -all([-_]?tests)? + that runs tests we know will fail. This allows us to add + regression tests to the test suite for bugs that haven't been + fixed yet. + 2009-09-28 Boris Kolpackov * scripts/features/patspecific_vars: Add a test for the shortest diff --git a/tests/run_make_tests.pl b/tests/run_make_tests.pl index 2071b176..65dba2a2 100755 --- a/tests/run_make_tests.pl +++ b/tests/run_make_tests.pl @@ -37,6 +37,8 @@ $pure_log = undef; $command_string = ''; +$all_tests = 0; + require "test_driver.pl"; # Some target systems might not have the POSIX module... @@ -48,15 +50,18 @@ sub valid_option { local($option) = @_; - if ($option =~ /^-make([-_]?path)?$/) - { - $make_path = shift @argv; - if (!-f $make_path) - { - print "$option $make_path: Not found.\n"; - exit 0; - } - return 1; + if ($option =~ /^-make([-_]?path)?$/i) { + $make_path = shift @argv; + if (!-f $make_path) { + print "$option $make_path: Not found.\n"; + exit 0; + } + return 1; + } + + if ($option =~ /^-all([-_]?tests)?$/i) { + $all_tests = 1; + return 1; } if ($option =~ /^-(valgrind|memcheck)$/i) { diff --git a/tests/scripts/features/se_explicit b/tests/scripts/features/se_explicit index adf6b33f..1b514749 100644 --- a/tests/scripts/features/se_explicit +++ b/tests/scripts/features/se_explicit @@ -130,5 +130,32 @@ endef !, '', "#MAKE#: *** prerequisites cannot be defined in recipes. Stop.\n", 512); + +if ($all_tests) { + # Automatic $$+ variable expansion issue. Savannah bug #25780 + run_make_test(q! +all : foo foo +.SECONDEXPANSION: +all : $$+ ; @echo '$+' +foo : ; +!, + '', "foo foo foo foo\n"); + +} + +if ($all_tests) { + # Automatic $$+ variable expansion issue. Savannah bug #25780 + run_make_test(q! +all : bar bar +bar : ; +q%x : ; +.SECONDEXPANSION: +a%l: q1x $$+ q2x ; @echo '$+' +!, + '', "q1x bar bar q2x bar bar\n"); + +} + + # This tells the test driver that the perl test script executed properly. 1; diff --git a/tests/scripts/functions/shell b/tests/scripts/functions/shell index ecea4cf6..723cd0ed 100644 --- a/tests/scripts/functions/shell +++ b/tests/scripts/functions/shell @@ -11,6 +11,15 @@ all: ; @echo $(shell echo hi) ','','hi'); +# Test unescaped comment characters in shells. Savannah bug #20513 +if ($all_tests) { + run_make_test(q! +FOO := $(shell echo '#') +foo: ; echo '$(FOO)' +!, + '', "#\n"); +} + # Test shells inside exported environment variables. # This is the test that fails if we try to put make exported variables into # the environment for a $(shell ...) call. diff --git a/tests/test_driver.pl b/tests/test_driver.pl index d38868c7..d7fa6c0b 100644 --- a/tests/test_driver.pl +++ b/tests/test_driver.pl @@ -461,6 +461,7 @@ sub run_each_test # Run the actual test! $tests_run = 0; $tests_passed = 0; + $code = do $perl_testname; $total_tests_run += $tests_run;