Bug 14167

Summary: make(1) always considers libraries as out-of-date + fix
Product: Base System Reporter: Sebastian Lederer <lederer>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.0-CURRENT   
Hardware: Any   
OS: Any   

Description Sebastian Lederer 1999-10-06 18:30:01 UTC
When you have static libraries as targets in makefiles, make always
thinks they
are out of date and rebuilds them.

Fix: The problem is in the file /usr/src/usr.bin/make/arch.c in line 809,
ArchFindMember(). The code is trying to remove path name components from
the
file names in the archive, by skipping everything up to the last '/'
character.
With ELF style linking, the global symbol table is named '/' in the
archive,
and the code at line 809 messes it up, so the symbol table is never
found.

Apply the following patch in /usr/src/usr.bin/make :
---------------------------------------------------


---------------------------------------------------


The same code fragment (with the special case added) already exists at
line 479
in ArchStatMember(), which calls ArchFindMember(). I have copied it from
there,
so it is probably safe to assume that this patch does not break
anything. And
it corrects the problem, too. With the patch applied, 'make -dm'
produces:
--------------------------------
$ /usr/obj/usr/src/usr.bin/make/make -dm
Examining test.c...modified 23:17:03 Oct 05, 1999...up-to-date.
Examining test.o...modified 23:17:40 Oct 05, 1999...up-to-date.
Examining libtest.a...modified 18:52:14 Oct 06, 1999...library.../
modified 18:52:14 Oct 06, 1999...up-to-date.
`libtest.a' is up to date.
--------------------------------

-- 
Sebastian Lederer
lederer@bonn-online.com--ZvIrWjopSKm78UPlRTHkBxsVa2Nb8nOSY7nFzJR03SY8PE4b
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

--- arch.c.orig	Tue Oct  5 22:45:25 1999
+++ arch.c	Wed Oct  6 12:02:29 1999
@@ -807,7 +807,7 @@
      * the comparisons easier...
      */
     cp = strrchr (member, '/');
-    if (cp != (char *) NULL) {
+    if ((cp != NULL) && (strcmp(member, RANLIBMAG) != 0)) {
 	member = cp + 1;
     }
     len = tlen = strlen (member);
How-To-Repeat: 
Create the following Makefile:
--- Makefile ---------------------------
libtest.a: test.o
	ar rv $@ test.o
	ranlib $@
----------------------------------------
and a file 'test.c':
---- test.c ----------------------------
void test()
{
}
----------------------------------------

Then, type 'make' multiple times. The library libtest.a is always
rebuilt.
Using 'make -dm' shows:
------------------------------------------------------
$ make -dm
Examining test.c...modified 23:17:03 Oct 05, 1999...up-to-date.
Examining test.o...modified 23:17:40 Oct 05, 1999...up-to-date.
Examining libtest.a...modified 18:52:12 Oct 06, 1999...library...No
t.o.c....out-of-date.
								  ^^^^^^^^
ar rv libtest.a test.o
r - test.o
ranlib libtest.a
update time: 18:52:14 Oct 06, 1999
-------------------------------------------------------

It appears that make fails to read the global symbol table of the
archive file,
making it think that the library needs to be rebuilt (see the 'No
t.o.c.'
part).
Comment 1 Julian Elischer freebsd_committer freebsd_triage 1999-10-10 21:33:29 UTC
State Changed
From-To: open->closed

patch applied to 4.x and 3.x