🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.utils.bug
Article #329

Re: Some questions about GNU Make 3.54

#329
From: Jay Schuster
Date: Fri, 28 Jul 1989 20:57
145 lines
4897 bytes
In article <10822@watcgl.waterloo.edu> andrewt@watnext.waterloo.edu (Andrew Thomas) writes:
>I find myself in a position where I have to keep an archive up to
>date, where the files in the archive are the objecs produced by
>compiling all of the C files in the directory.  The directory is very
>large, so I would like to compile all of the C files which need
>compiling first, and then perform the 'ar' command at the end, thereby
>saving the (significant) time spent calling ar over and over again.

I ran into this problem starting at make 3.05 and continuing up
to make 3.54.  In SystemV-land we are encouraged (by the manual) to
do archives like this (converted to GNUish):

(%.o): %.c ;

$(LIB): \
	$(LIB)(erasebox.o) \
	$(LIB)(command.o) \
	$(LIB)(errlog.o) \
	$(LIB)(fmt.o) \
	$(LIB)(printlib+.o)
	$(CC) -c $(CFLAGS) $(?:.o=.c)
	ar rv $(LIB) $?
	rm $?

.PRECIOUS: $(LIB)

The idea being that we should defeat the default rule as to how to
make $(LIB)(foo.o), collect up what was out of date, and then just
issue one `$(CC)' command, one `ar', and one `rm'.

GNU make doesn't let you do this because when it runs across a rule
with no command, it still pretends that the targets were updated,
even though they weren't.  Also, In SystemV, if $? would be a list
of archive members `lib(member)', then $? actually becomes the list
of `member's.

Here is what I do to fix it (this is an excerpt from a larger patch,
so your line numbers will be off) :

*** commands.c~	Thu Jul 27 12:17:47 1989
--- commands.c	Thu Jul 27 15:43:55 1989
***************
*** 102,108 ****
    DEFINE_VARIABLE ("%D", 2, DIRONLY (percent));
    DEFINE_VARIABLE ("%F", 2, FILEONLY (percent));
  
!   /* Compute the values for $^ and $? and their F and D versions.  */
  
    {
      register unsigned int caret_len, qmark_len;
--- 108,117 ----
    DEFINE_VARIABLE ("%D", 2, DIRONLY (percent));
    DEFINE_VARIABLE ("%F", 2, FILEONLY (percent));
  
!   /* Compute the values for $^ and $? and their F and D versions.
!      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 caret_len, qmark_len;
***************
*** 116,122 ****
      caret_len = qmark_len = 0;
      for (d = file->deps; d != 0; d = d->next)
        {
! 	register unsigned int i = strlen (dep_name (d)) + 1;
  	caret_len += i;
  	if (d->changed)
  	  qmark_len += i;
--- 125,137 ----
      caret_len = qmark_len = 0;
      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;
! 
  	caret_len += i;
  	if (d->changed)
  	  qmark_len += i;
***************
*** 138,143 ****
--- 153,165 ----
  
  	c = dep_name (d);
  	len = strlen (c);
+ 
+ 	if (ar_name (c))
+ 	  {
+ 	    c = (1 + index (c, '('));
+ 	    len = strlen (c) - 1;
+ 	  }
+ 
  	bcopy (c, cp, len);
  	cp += len;
  	*cp++ = ' ';
*** remake.c~	Thu Jul 27 12:17:56 1989
--- remake.c	Thu Jul 27 15:35:49 1989
***************
*** 414,423 ****
       register struct file *file;
  {
    file->updated = 1;
!   if (just_print_flag)
!     file->last_mtime = time ((time_t *) 0);
!   else
!     file->last_mtime = name_mtime (file->name);
  
    if (file->also_make != 0)
      {
--- 414,440 ----
       register struct file *file;
  {
    file->updated = 1;
! 
!   /* 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);
!     }
!   }
  
    if (file->also_make != 0)
      {
-- 
Jay Schuster			uunet!uvm-gen!banzai!jay, attmail!banzai!jay
The People's Computer Company	`Revolutionary Programming'
Technical Details
Message-ID: <1286@banzai.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!watmath!uunet!uvm-gen!banzai!jay
References: <10822@watcgl.waterloo.edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!watmath!uunet!uvm-gen!banzai!jay
From: jay@banzai.UUCP (Jay Schuster)
Newsgroups: gnu.utils.bug
Subject: Re: Some questions about GNU Make 3.54
Message-ID: <1286@banzai.UUCP>
Date: 28 Jul 89 20:57:03 GMT
References: <10822@watcgl.waterloo.edu>
Reply-To: jay@banzai.UUCP (Jay Schuster)
Organization: People's Computer Company, Williston, VT
Lines: 145