jay@UUNET.UU.NET (Jay Schuster) (11/01/88)
Hope this helps the effort. Jay Schuster uunet!uvm-gen!banzai!jay The People's Computer Company `Revolutionary Programming' What follows are diff's from when we tried to get GNU make version 3.05 working on our Sys5r2 machine. They represent fixes to the following problems: O_RDONLY, etc. are in <fcntl.h> not <sys/file.h>, and <sys/file.h> doesn't have anything necessary that <fcntl.h> doesn't provide. Some #ifdef USG's for bcopy(), bcmp(), <memory.h>, and for what wait() returns and how to tell if how what was waited for terminated. In our archives, filenames have a trailing slash. So in addition to wiping out the trailing spaces, I wipe out the trailing slashes as well. I do not know if that is just our system, or a general Sys5ism. In our make, $?, when used in the commands associated with building an archive, expands to the member .o files, and not archive.a(member.o). I added code to do this, and to change $^ similarly. Sometimes xmalloc() was being called with zero, and then the space allocated was written into. I changed it to always allocate at least one character. This happened in both glob.c and commands.c. SIGINT, SIGHUP, and SIGQUIT should remain ignored if they were ignored upon entrance. In read.c, the name of the included file being read was being freed when it still had references to it, causing -p to print out garbage as to where the rules came from. In read.c, there were two if statements following each other that were redundant. It looked like one of them could have been removed. maxsuffix was being calculated after it was used. I moved the calculation out of the function count_implicit_rule_limits() and into convert_to_pattern(), but left the declaration global. When converting the .X.a rules, savestring was being called with an incorrect argument. install_default_pattern_rules() was *always* replacing the current suffix rules with the defaults, thus overriding and .c.o, etc. rules you had in your makefiles. In new_environ(), when loading in the new environment, vcnt was being incremented regardless of whether an environment entry was loaded, leading to a hole in the environment. The amount of space being allocated still can be one entry too large, because the counting loop doesn't take into account an entry might be skipped. In remake.c, I added a change to partially implement a common SysVism. Often, in library makefiles, we do something like the following: .c.a: ; $(LIB): $(LIB)(foo.o) $(LIB)(bar.o) $(CC) -c $(CFLAGS) $(?:.o=.c) ar rv $(LIB) $? rm $? This has the effect of only invoking the c compiler once, and only invoking ar once, a big win. Unfortunately, make -n shows the correct output, but a true make does not. Apparently, make was thinking that it executed a command, so it was updating its internal status as to when the file was modified, believing it had remade the file. UNRESOLVED PROBLEMS Duplicates in the .SUFFIXES list will cause make to do bizarre things and eventually dump core. This is triggered most commonly by adding a .c into the SUFFIXES list. With the library hack above, if I change the rule to a double-colon rule, and add the following: .c.a: ; .y.a: ; $(LIB):: $(LIB)(foo.o) $(LIB)(bar.o) $(CC) -c $(CFLAGS) $(?:.o=.c) ar rv $(LIB) $? rm $? $(LIB):: $(LIB)(parse.o) $(MAKE) $(?:.o=.y) ar rv $(LIB) $? rm $? Make dumps core. THINGS YOU CAN IGNORE We added a tab to print before echoing the command that gets executed. It was easier to leave it in this diff than to take it out and have all the line numbers be off. DESIRES: I would really like it if make did an implicit `make Makefile' if it couldn't find one in the current directory. Here's the diff: *** arscan.c~ Sat Apr 30 03:22:40 1988 --- arscan.c Wed Oct 5 14:58:11 1988 *************** *** 82,90 **** what you give them. Help stamp out software-hoarding! */ #include <ar.h> - #include <sys/file.h> #include <sys/types.h> #include <sys/stat.h> /* Takes three arguments ARCHIVE, FUNCTION and ARG. --- 82,97 ---- what you give them. Help stamp out software-hoarding! */ #include <ar.h> #include <sys/types.h> #include <sys/stat.h> + #ifdef USG + #include <fcntl.h> + #include <memory.h> + #define bcopy(s, d, n) memcpy ((d), (s), (n)) + #define bcmp(s1, s2, cnt) memcmp((s1), (s2), (cnt)) + #else /* not USG */ + #include <sys/file.h> + #endif /* not USG */ /* Takes three arguments ARCHIVE, FUNCTION and ARG. *************** *** 162,169 **** } bcopy (member_header.ar_name, name, sizeof member_header.ar_name); { register char *p = name + sizeof member_header.ar_name; ! while (p > name && *--p == ' ') *p = 0; } sscanf (member_header.ar_mode, "%o", &eltmode); --- 169,177 ---- } bcopy (member_header.ar_name, name, sizeof member_header.ar_name); { + /* Remove trailing spaces (all) and slashes (SystemV) */ register char *p = name + sizeof member_header.ar_name; ! while (p > name && (*--p == ' ' || *p == '/')) *p = 0; } sscanf (member_header.ar_mode, "%o", &eltmode); *** commands.c~ Wed Aug 10 00:15:11 1988 --- commands.c Wed Oct 5 18:16:40 1988 *************** *** 18,31 **** #include "commands.h" #include "file.h" #include "variable.h" - #include <sys/wait.h> - #ifdef USG #define vfork fork #define VFORK_NAME "fork" #else /* not USG */ #define VFORK_NAME "vfork" #endif /* USG */ extern int vfork (), execvp (), wait (), kill (), getpid (); --- 18,40 ---- #include "commands.h" #include "file.h" #include "variable.h" #ifdef USG #define vfork fork #define VFORK_NAME "fork" + #define WAITTYPE int + #define WIFEXITED(status) (((status)&0xff)==0) + #define WIFEXITretcode(status) (((status)>>8)&0xff) + #define WIFSIGNALED(status) (((status)&0xff)!=0) + #define WIFSIGNALtermsig(status) ((status)&0x7f) + #define WIFSIGNALcoredump(status) ((status)&0x80) #else /* not USG */ + #include <sys/wait.h> #define VFORK_NAME "vfork" + #define WAITTYPE union wait + #define WIFEXITretcode(status) (status.w_retcode) + #define WIFSIGNALtermsig(status) (status.w_termsig) + #define WIFSIGNALcoredump(status) (status.w_coredump) #endif /* USG */ extern int vfork (), execvp (), wait (), kill (), getpid (); *************** *** 165,171 **** #undef FILEONLY #undef DIRONLY ! /* Compute the values for $^ and $?. */ { register unsigned int dep_size = 0, c_size = 0; --- 174,183 ---- #undef FILEONLY #undef DIRONLY ! /* Compute the values for $^ and $?. ! In SystemV, if $? is a list of archive members `lib(member)'', ! then $? is the list of `member''s. We do a similar thing with ! $^ */ { register unsigned int dep_size = 0, c_size = 0; *************** *** 174,187 **** for (d = file->deps; d != 0; d = d->next) { ! register unsigned int i = strlen (dep_name (d)) + 1; c_size += i; if (d->changed) dep_size += i; } ! line = (char *) xmalloc (dep_size); ! cline = (char *) xmalloc (c_size); *line = *cline = '\0'; if (c_size > 0 && dep_size > 0) --- 186,205 ---- for (d = file->deps; d != 0; d = d->next) { ! register unsigned int i; ! ! if (ar_name (dep_name(d))) ! i = strlen (1 + index (dep_name(d), '(')); ! else ! i = strlen (dep_name (d)) + 1; ! c_size += i; if (d->changed) dep_size += i; } ! line = (char *) xmalloc (dep_size == 0 ? 1 : dep_size); ! cline = (char *) xmalloc (c_size == 0 ? 1 : c_size); *line = *cline = '\0'; if (c_size > 0 && dep_size > 0) *************** *** 190,201 **** for (d = file->deps; d != 0; d = d->next) { unsigned int len = strlen (dep_name (d)); ! bcopy (dep_name (d), cp, len); cp += len; *cp++ = ' '; if (d->changed) { ! bcopy (dep_name (d), lp, len); lp += len; *lp++ = ' '; } --- 208,227 ---- for (d = file->deps; d != 0; d = d->next) { unsigned int len = strlen (dep_name (d)); ! char *dep = dep_name(d); ! ! if (ar_name (dep)) ! { ! dep = (1 + index (dep, '(')); ! len = strlen (dep) - 1; ! } ! ! bcopy (dep, cp, len); cp += len; *cp++ = ' '; if (d->changed) { ! bcopy (dep, lp, len); lp += len; *lp++ = ' '; } *************** *** 286,291 **** --- 312,318 ---- if (just_print_flag || (!silent_flag && !noprint)) { + putchar ('\t'); puts (line); fflush (stdout); } *************** *** 357,363 **** register char *ap; char *end; int instring; ! union wait status; int pid; char **new_argv; --- 384,390 ---- register char *ap; char *end; int instring; ! WAITTYPE status; int pid; char **new_argv; *************** *** 499,505 **** else if (wpid != pid) continue; else if (WIFEXITED (status)) ! return (status.w_retcode); else if (WIFSIGNALED (status)) { int s; --- 526,532 ---- else if (wpid != pid) continue; else if (WIFEXITED (status)) ! return (WIFEXITretcode(status)); else if (WIFSIGNALED (status)) { int s; *************** *** 519,526 **** /* Treat this as failure. */ ! s = status.w_termsig | SIGNAL_STATUS; ! if (status.w_coredump) s |= SIGNAL_COREDUMP; return s; } --- 546,553 ---- /* Treat this as failure. */ ! s = WIFSIGNALtermsig(status) | SIGNAL_STATUS; ! if (WIFSIGNALcoredump(status)) s |= SIGNAL_COREDUMP; return s; } *** make.c~ Sun Aug 21 00:36:52 1988 --- make.c Wed Oct 5 16:27:54 1988 *************** *** 235,243 **** reading_filename = 0; reading_lineno_ptr = 0; ! signal (SIGHUP, fatal_error_signal); ! signal (SIGQUIT, fatal_error_signal); ! signal (SIGINT, fatal_error_signal); signal (SIGILL, fatal_error_signal); signal (SIGTRAP, fatal_error_signal); signal (SIGIOT, fatal_error_signal); --- 235,246 ---- reading_filename = 0; reading_lineno_ptr = 0; ! if (SIG_IGN != signal (SIGHUP, SIG_IGN)) ! signal (SIGHUP, fatal_error_signal); ! if (SIG_IGN != signal (SIGQUIT, SIG_IGN)) ! signal (SIGQUIT, fatal_error_signal); ! if (SIG_IGN != signal (SIGINT, SIG_IGN)) ! signal (SIGINT, fatal_error_signal); signal (SIGILL, fatal_error_signal); signal (SIGTRAP, fatal_error_signal); signal (SIGIOT, fatal_error_signal); *** read.c~ Mon Sep 5 20:15:45 1988 --- read.c Wed Oct 5 16:16:29 1988 *************** *** 320,326 **** p = variable_expand (p); p = savestring (p, strlen (p)); read_makefile (p, 1, 1); ! free (p); conditionals = save; continue; } --- 320,326 ---- p = variable_expand (p); p = savestring (p, strlen (p)); read_makefile (p, 1, 1); ! /* Don't free (p); because commands point to it. */ conditionals = save; continue; } *************** *** 943,949 **** even if the file already has one. */ f = lookup_file (name); if (f != 0 && !f->double_colon) - if (!f->double_colon) fatal ("target file `%s' has both : and :: entries", f->name); f = enter_file (name); f->double_colon = 1; --- 943,948 ---- *** remake.c~ Sat Sep 3 22:12:53 1988 --- remake.c Fri Oct 14 21:28:53 1988 *************** *** 17,23 **** --- 17,27 ---- #include "commands.h" #include "dep.h" #include "file.h" + #ifdef USG + #include <fcntl.h> + #else /* !USG */ #include <sys/file.h> + #endif extern int open (), fstat (), read (), lseek (), write (), close (); *************** *** 360,367 **** --- 364,393 ---- status = execute_file_commands (file); file->update_status = status; + /* If the command we just tried to execute was empty, pretend that + we did something anyway. This way things that depended on this + file get updated as well. This is a hack, and not correct, but it + will make the efficient library update method work. */ + { + if (just_print_flag) + file->last_mtime = time ((time_t *) 0); + else { + if (file->cmds != 0) { + char *p; + for (p = file->cmds->commands; *p != '\0'; ++p) + if (*p != ' ' && *p != '\t' && *p != '\n') + break; + file->last_mtime = (*p == '\0') + ? time ((time_t *) 0) : name_mtime (file->name); + } + else + file->last_mtime = name_mtime (file->name); + } + } + /* file->last_mtime = just_print_flag ? time ((time_t *) 0) : name_mtime (file->name); + */ file->updated = 1; if (file->also_make != 0) *** rule.c~ Mon Sep 5 20:25:40 1988 --- rule.c Wed Oct 5 17:59:49 1988 *************** *** 342,351 **** unsigned int deps_found; /* Names of possible dependencies are constructed in this buffer. */ ! register char *depname = (char *) alloca (namelen + max_pattern_dep_length); /* The start and length of the stem of FILENAME for the current rule. */ ! register char *stem; register unsigned int stemlen; /* Buffer in which we store all the rules that are possibly applicable. */ --- 342,351 ---- unsigned int deps_found; /* Names of possible dependencies are constructed in this buffer. */ ! /* register */ char *depname = (char *) alloca (namelen + max_pattern_dep_length); /* The start and length of the stem of FILENAME for the current rule. */ ! /* register */ char *stem; register unsigned int stemlen; /* Buffer in which we store all the rules that are possibly applicable. */ *************** *** 812,829 **** char *name; unsigned int namelen; register struct rule *rule, *lastrule; - register struct dep *d; - /* Compute maximum length of all the suffixes. */ - - maxsuffix = 0; - for (d = suffix_file->deps; d != 0; d = d->next) - { - namelen = strlen (dep_name (d)); - if (namelen > maxsuffix) - maxsuffix = namelen; - } - num_pattern_rules = 0; name = 0; --- 812,818 ---- *************** *** 895,903 **** { register struct dep *d, *d2, *newd; register struct file *f; ! register char *rulename = (char *) alloca ((maxsuffix * 2) + 1); register unsigned int slen, s2len; register char *name, **names; for (d = suffix_file->deps; d != 0; d = d->next) { --- 884,904 ---- { register struct dep *d, *d2, *newd; register struct file *f; ! register char *rulename; register unsigned int slen, s2len; register char *name, **names; + unsigned int namelen; + + /* Compute maximum length of all the suffixes. */ + + maxsuffix = 0; + for (d = suffix_file->deps; d != 0; d = d->next) + { + namelen = strlen (dep_name (d)); + if (namelen > maxsuffix) + maxsuffix = namelen; + } + rulename = (char *) alloca ((maxsuffix * 2) + 1); for (d = suffix_file->deps; d != 0; d = d->next) { *************** *** 946,952 **** { /* The suffix rule `.X.a:' is converted to the pattern rule `(%.o): %.X'. */ ! name = savestring ("(%.o)", 4); newd->name = (char *) xmalloc (1 + s2len + 1); newd->name[0] = '%'; bcopy (dep_name (d2), newd->name + 1, s2len + 1); --- 947,953 ---- { /* The suffix rule `.X.a:' is converted to the pattern rule `(%.o): %.X'. */ ! name = savestring ("(%.o)", 5); newd->name = (char *) xmalloc (1 + s2len + 1); newd->name[0] = '%'; bcopy (dep_name (d2), newd->name + 1, s2len + 1); *************** *** 1163,1172 **** for (s = default_suffix_rules; *s != 0; s += 2) { register struct file *f = enter_file (s[0]); ! f->cmds = (struct commands *) xmalloc (sizeof (struct commands)); ! f->cmds->filename = 0; ! f->cmds->commands = s[1]; ! f->cmds->recursive = 0; } for (s = default_variables; *s != 0; s += 2) --- 1164,1178 ---- for (s = default_suffix_rules; *s != 0; s += 2) { register struct file *f = enter_file (s[0]); ! ! /* Don't replace rules already read in from the makefiles */ ! if (f->cmds == 0) ! { ! f->cmds = (struct commands *) xmalloc (sizeof (struct commands)); ! f->cmds->filename = 0; ! f->cmds->commands = s[1]; ! f->cmds->recursive = 0; ! } } for (s = default_variables; *s != 0; s += 2) *** variable.c~ Wed Aug 24 22:30:52 1988 --- variable.c Mon Oct 3 18:13:28 1988 *************** *** 1384,1391 **** environ[vcnt] = (char *) xmalloc (strlen (v->name) + strlen (v->value) + 2); sprintf (environ[vcnt], "%s=%s", v->name, v->value); } - ++vcnt; } } --- 1384,1391 ---- environ[vcnt] = (char *) xmalloc (strlen (v->name) + strlen (v->value) + 2); sprintf (environ[vcnt], "%s=%s", v->name, v->value); + ++vcnt; } } }