Re: PATCH: .SECONDARY target with no dependencies does not work correctly.
"Paul D. Smith" [EMAIL PROTECTED]: This is obliquely stated in the documentation: `.SECONDARY' The targets which `.SECONDARY' depends on are treated as intermediate files, except that they are never automatically deleted. *Note Chains of Implicit Rules: Chained Rules. `.SECONDARY' with no prerequisites marks all file targets mentioned ^^ in the makefile as secondary. Note the second paragraph. The targets you give aren't mentioned in the makefile; they're built using implicit rules. Yes, but aren't all explicitly mentioned targets considered secondary anyway? If so, it seems like ".SECONDARY: " serves no purpose... For the complex Makefiles I'm working on now, intermediate deletion was causing deletion of object files which should not be deleted, and I decided to just turn it off entirely. However, without .SECONDARY behaving as I'd like it to, I don't see how to acheive this. I agree with you, however, that this is a strange restriction and this area needs to be revisited, for all of PRECIOUS, INTERMEDIATE, and SECONDARY. I'll file an enhancement request about it. Thanks. Seth
PATCH: Multiple-target pattern rules do the wrong thing with subdirs.
(Make version 3.79.) Consider this Makefile: %.1 %.2: %.src cp $ $*.1 cp $ $*.2 Create a file sub/foo.src and 'make -Rp sub/foo.1'. Here's an excerpt from the output: # Not a target: sub/foo.1: sub/foo.src # Command-line target. # Implicit rule search has been done. # Implicit/static pattern stem: `sub/foo' # Also makes: foo.2 # Last modified 2000-06-15 17:49:23 # File has been updated. # Successfully updated. # automatic # ^ := sub/foo.src # automatic # @ := sub/foo.1 # automatic # + := sub/foo.src # automatic # ? := sub/foo.src # automatic # * := sub/foo # automatic # % := # automatic # := sub/foo.src # 7 variables in 23 hash buckets. # average of 0.3 variables per bucket, max 2 in one bucket. # commands to execute (from `Makefile', line 2): cp $ $*.1 cp $ $*.2 # Not a target: foo.2: # Implicit rule search has not been done. # File does not exist. # File has been updated. # Successfully updated. Note that make is incorrectly dropping the subdirectory path from the extra targets. Here's a patch to fix it: diff -rc /x/sethml/src/make-3.79/implicit.c ./implicit.c *** /x/sethml/src/make-3.79/implicit.c Fri Jan 21 21:43:03 2000 --- ./implicit.cThu Jun 15 17:28:50 2000 *** *** 117,122 --- 117,123 /* The start and length of the stem of FILENAME for the current rule. */ register char *stem = 0; register unsigned int stemlen = 0; + unsigned int fstemlen; /* Buffer in which we store all the rules that are possibly applicable. */ struct rule **tryrules *** *** 582,599 } if (!checked_lastslash[foundrule]) ! /* Always allocate new storage, since STEM might be !on the stack for an intermediate file. */ ! file-stem = savestring (stem, stemlen); else { /* We want to prepend the directory from the original FILENAME onto the stem. */ ! file-stem = (char *) xmalloc (((lastslash + 1) - filename) !+ stemlen + 1); bcopy (filename, file-stem, (lastslash + 1) - filename); bcopy (stem, file-stem + ((lastslash + 1) - filename), stemlen); ! file-stem[((lastslash + 1) - filename) + stemlen] = '\0'; } file-cmds = rule-cmds; --- 583,603 } if (!checked_lastslash[foundrule]) ! { ! /* Always allocate new storage, since STEM might be !on the stack for an intermediate file. */ ! file-stem = savestring (stem, stemlen); ! fstemlen = stemlen; ! } else { /* We want to prepend the directory from the original FILENAME onto the stem. */ ! fstemlen = ((lastslash + 1) - filename) + stemlen; ! file-stem = (char *) xmalloc (fstemlen + 1); bcopy (filename, file-stem, (lastslash + 1) - filename); bcopy (stem, file-stem + ((lastslash + 1) - filename), stemlen); ! file-stem[fstemlen] = '\0'; } file-cmds = rule-cmds; *** *** 606,617 if (i != matches[foundrule]) { struct dep *new = (struct dep *) xmalloc (sizeof (struct dep)); ! new-name = p = (char *) xmalloc (rule-lens[i] + stemlen + 1); bcopy (rule-targets[i], p, rule-suffixes[i] - rule-targets[i] - 1); p += rule-suffixes[i] - rule-targets[i] - 1; ! bcopy (stem, p, stemlen); ! p += stemlen; bcopy (rule-suffixes[i], p, rule-lens[i] - (rule-suffixes[i] - rule-targets[i]) + 1); new-file = enter_file (new-name); --- 610,621 if (i != matches[foundrule]) { struct dep *new = (struct dep *) xmalloc (sizeof (struct dep)); ! new-name = p = (char *) xmalloc (rule-lens[i] + fstemlen + 1); bcopy (rule-targets[i], p, rule-suffixes[i] - rule-targets[i] - 1); p += rule-suffixes[i] - rule-targets[i] - 1; ! bcopy (file-stem, p, fstemlen); ! p += fstemlen; bcopy (rule-suffixes[i], p, rule-lens[i] - (rule-suffixes[i] - rule-targets[i]) + 1); new-file = enter_file (new-name);
PATCH: .SECONDARY target with no dependencies does not work correctly.
(Make version 3.79.) Consider: % cat Makefile %.1: %.2 cp $ $@ %.2: %.3 cp $ $@ .SECONDARY: % ls Makefile foo.3 % make foo.1 cp foo.3 foo.2 cp foo.2 foo.1 rm foo.2 According to the documentation, the .SECONDARY target should cause all files to be considered secondary (and thus not deleted), but it doesn't work. I think that this is because the code to handle the .SECONDARY target with no dependencies marks all known files as secondary, but is run before pattern rules are followed and thus doesn't mark the results of pattern rules. Since .SECONDARY is only really useful on the targets of pattern rules, this rather defeats the purpose. At the end of this email is a rather crude patch to fix the problem. A more general issue: the documentation says: You can also list the target pattern of an implicit rule (such as `%.o') as a dependency file of the special target `.PRECIOUS' to preserve intermediate files created by rules whose target patterns match that file's name. This documents rather bizarre behaviour: it only works for pattern rules which specify the exact pattern mentioned (`%.o') and not ones which mention a different pattern which matches the same filenames (say, `%.foo.o'). It's easy for a user to expect different behaviour - e.g. that '.PRECIOUS: %' would make all files precious. It's also odd that .SECONDARY and .INTERMEDIATE don't seem to do anything useful with pattern dependencies. I propose that for special targets with pattern dependencies, all files should be matched against the patterns, and any files which match should have the special behaviour. Then the no-dependency case of .SECONDARY would be equivalent to '.SECONDARY: %'. Anyway, here's the patch: diff -rc /x/sethml/src/make-3.79/file.c ./file.c *** /x/sethml/src/make-3.79/file.c Mon Mar 27 08:20:40 2000 --- ./file.cThu Jun 15 16:09:10 2000 *** *** 34,39 --- 34,42 #endif static struct file *files[FILE_BUCKETS]; + /* Are all files considered secondary? */ + static int all_secondary = 0; + /* Number of files with the `intermediate' flag set. */ unsigned int num_intermediates = 0; *** *** 384,390 register struct file *f; char doneany; ! if (question_flag || touch_flag) return; if (sig just_print_flag) return; --- 387,393 register struct file *f; char doneany; ! if (question_flag || touch_flag || all_secondary) return; if (sig just_print_flag) return; *** *** 504,517 for (f2 = d-file; f2 != 0; f2 = f2-prev) f2-intermediate = f2-secondary = 1; } ! /* .SECONDARY with no deps listed marks *all* files that way. */ else ! { ! int i; ! for (i = 0; i FILE_BUCKETS; i++) ! for (f2 = files[i]; f2; f2= f2-next) ! f2-intermediate = f2-secondary = 1; ! } } f = lookup_file (".EXPORT_ALL_VARIABLES"); --- 507,516 for (f2 = d-file; f2 != 0; f2 = f2-prev) f2-intermediate = f2-secondary = 1; } ! /* .SECONDARY with no deps listed marks *all* files that way. !* We haven't seen all intermediate files yet, use a global flag. */ else ! all_secondary = 1; } f = lookup_file (".EXPORT_ALL_VARIABLES");