hrp@boring.cray.com (Hal Peterson) (09/21/89)
I am using GNU Make 3.55 on a Sun-3/50 running SunOS 3.5. I built it with GCC 1.35. Stem handling isn't quite correct; it's deleting directories. Consider this Makefile: .SUFFIXES: .c .o .c.o: @echo This should be foo/bar: $* foo/bar.o: foo/bar.c If the directory foo exists and contains the file bar.c, here's what Make 3.54 does. I didn't keep around a copy of 3.55, but it does the same thing once it's been patched to handle rules without commands: 67 /usr/earth4/gnu/src/make-3.55 $ make -v GNU Make version 3.54, by Richard Stallman and Roland McGrath. Copyright (C) 1988, 1989 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This should be foo/bar: bar 68 /usr/earth4/gnu/src/make-3.55 $ Notice that $* strips leading directories from the target name, which it should not. From the manual, ``How Patterns Match'': When the target pattern does not contain a slash (and usually it does not), directory names in the file names are removed from the file name before it is compared with the target prefix and suffix. The directory names, along with the slash that ends them, are added back to the stem. Thus, `e%t' does match the file name `src/eat', with `src/a' as the stem. When dependencies are turned into file names, the directories from the stem are added at the front, while the rest of the stem is substituted for the `%'. The stem `src/a' with a dependency pattern `c%r' gives the file name `src/car'. The diffs that follow seem to make this better by using two different variables for pattern matching and for saving in file->stem. -- Hal Peterson Domain: hrp@cray.com Cray Research Old style: hrp%cray.com@uc.msc.umn.edu 1440 Northland Dr. UUCP: uunet!cray!hrp Mendota Hts, MN 55120 USA Telephone: +1 612 681 3145 ======================================================================== *** implicit-DIST.c Wed Sep 20 13:43:00 1989 --- implicit.c Wed Sep 20 16:14:35 1989 *************** *** 155,160 **** --- 155,162 ---- { int specific_rule_may_have_matched = 0; int check_lastslash; + char *stem_base; + int stem_baselen; /* If the pattern rule has deps but no commands, ignore it. Users cancel built-in rules by redefining them without commands. */ *************** *** 182,189 **** /* From the lengths of the filename and the pattern parts, find the stem: the part of the filename that matches the %. */ ! stem = filename + (suffix - target - 1); ! stemlen = namelen - rule->lens[i] + 1; /* Set CHECK_LASTSLASH if FILENAME contains a directory prefix and the target pattern does not contain a slash. */ --- 184,191 ---- /* From the lengths of the filename and the pattern parts, find the stem: the part of the filename that matches the %. */ ! stem_base = stem = filename + (suffix - target - 1); ! stem_baselen = stemlen = namelen - rule->lens[i] + 1; /* Set CHECK_LASTSLASH if FILENAME contains a directory prefix and the target pattern does not contain a slash. */ *************** *** 193,215 **** { /* In that case, don't include the directory prefix in STEM here. */ ! stem += lastslash - filename + 1; ! stemlen -= (lastslash - filename) + 1; } /* Check that filename is long enough to match the whole pattern. */ ! if (stemlen <= 0) continue; /* Check that the rule pattern matches the text before the stem. */ if (check_lastslash) { ! if (stem > (lastslash + 1) ! && strncmp (target, lastslash + 1, stem - lastslash - 1)) continue; } ! else if (stem > filename ! && strncmp (target, filename, stem - filename)) continue; /* Check that the rule pattern matches the text after the stem. --- 195,217 ---- { /* In that case, don't include the directory prefix in STEM here. */ ! stem_base += lastslash - filename + 1; ! stem_baselen -= (lastslash - filename) + 1; } /* Check that filename is long enough to match the whole pattern. */ ! if (stem_baselen <= 0) continue; /* Check that the rule pattern matches the text before the stem. */ if (check_lastslash) { ! if (stem_base > (lastslash + 1) ! && strncmp (target, lastslash + 1, stem_base - lastslash - 1)) continue; } ! else if (stem_base > filename ! && strncmp (target, filename, stem_base - filename)) continue; /* Check that the rule pattern matches the text after the stem. *************** *** 217,224 **** first two characters immediately. This saves time in the very common case where the first character matches because it is a period. */ ! if (*suffix != stem[stemlen] ! || (*suffix != '\0' && !streq (&suffix[1], &stem[stemlen + 1]))) continue; /* Record if we match a rule that not all filenames will match. */ --- 219,226 ---- first two characters immediately. This saves time in the very common case where the first character matches because it is a period. */ ! if (*suffix != stem_base[stem_baselen] ! || (*suffix != '\0' && !streq (&suffix[1], &stem_base[stem_baselen + 1]))) continue; /* Record if we match a rule that not all filenames will match. */ *************** *** 271,276 **** --- 273,280 ---- for (i = 0; i < nrules; i++) { int check_lastslash; + char *stem_base; + int stem_baselen; rule = tryrules[i]; *************** *** 290,308 **** /* From the lengths of the filename and the matching pattern parts, find the stem: the part of the filename that matches the %. */ ! stem = filename + (rule->suffixes[matches[i]] - rule->targets[matches[i]]) - 1; ! stemlen = namelen - rule->lens[matches[i]] + 1; check_lastslash = lastslash != 0 && index (rule->targets[matches[i]], '/') == 0; if (check_lastslash) { ! stem += lastslash - filename + 1; ! stemlen -= (lastslash - filename) + 1; } DEBUGP2 ("Trying pattern rule with stem `%.*s'.\n", ! stemlen, stem); /* Try each dependency; see if it "exists". */ --- 294,312 ---- /* From the lengths of the filename and the matching pattern parts, find the stem: the part of the filename that matches the %. */ ! stem_base = stem = filename + (rule->suffixes[matches[i]] - rule->targets[matches[i]]) - 1; ! stem_baselen = stemlen = namelen - rule->lens[matches[i]] + 1; check_lastslash = lastslash != 0 && index (rule->targets[matches[i]], '/') == 0; if (check_lastslash) { ! stem_base += lastslash - filename + 1; ! stem_baselen -= (lastslash - filename) + 1; } DEBUGP2 ("Trying pattern rule with stem `%.*s'.\n", ! stem_baselen, stem_base); /* Try each dependency; see if it "exists". */ *************** *** 323,330 **** i = 0; bcopy (dep_name (dep), depname + i, p - dep_name (dep)); i += p - dep_name (dep); ! bcopy (stem, depname + i, stemlen); ! i += stemlen; strcpy (depname + i, p + 1); p = depname; } --- 327,334 ---- i = 0; bcopy (dep_name (dep), depname + i, p - dep_name (dep)); i += p - dep_name (dep); ! bcopy (stem_base, depname + i, stem_baselen); ! i += stem_baselen; strcpy (depname + i, p + 1); p = depname; }