Subject: bin/1488: 'make' does wrong thing with sys.mk .c.a rule
To: None <gnats-bugs@NetBSD.ORG>
From: Chris G. Demetriou <cgd@NetBSD.ORG>
List: netbsd-bugs
Date: 09/20/1995 21:05:02
>Number:         1488
>Category:       bin
>Synopsis:       'make' does wrong thing with sys.mk .c.a rule
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Sep 20 21:20:01 1995
>Last-Modified:
>Originator:     Chris G. Demetriou
>Organization:
Kernel Hackers 'r' Us
>Release:        NetBSD-current as of 9/12
>Environment:
	NetBSD/Alpha, NetBSD/i386, current as of that date.
	also present in (much) earlier versions of -current.

>Description:
	when the .c.a rule is present in sys.mk, 'make' seems to
	mistakenly want to build .a files from .c files in other
	directories.  for instance:

foo: foo.o ../bar/libbar.a
        cc -o foo foo.o ../bar/libbar.a

	if ../bar/libbar.a and ../bar/libbar.c exist, and the latter
	has a later mod time than the former, make will try compile
	../bar/libbar.c into libbar.a (in the current directory).

	Other systems (ULTRIX, OSF/1, SunOS) don't display this
	behaviour.

>How-To-Repeat:

	unshar the following shar file.  cd into 'make-bfd'.
	compare the results of 'make all' vs. 'make break'.

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	make-bfd
#	make-bfd/Makefile
#	make-bfd/bfd
#	make-bfd/bfd/libbfd.c
#	make-bfd/bfd/foo.c
#	make-bfd/bfd/bar.c
#	make-bfd/bfd/Makefile
#	make-bfd/foo
#	make-bfd/foo/foo.c
#	make-bfd/foo/Makefile
#
echo c - make-bfd
mkdir -p make-bfd > /dev/null 2>&1
echo x - make-bfd/Makefile
sed 's/^X//' >make-bfd/Makefile << 'END-of-make-bfd/Makefile'
X
Xall:
X	cd bfd ; make
X	cd foo ; make
X
Xclean:
X	cd bfd ; make clean
X	cd foo ; make clean
X
Xbreak:
X	cd bfd ; make		# or clean
X	sleep 2			# lest the time remain the same
X	touch bfd/libbfd.c	# or, perhaps, if file mod times screwed
X	cd foo ; make
END-of-make-bfd/Makefile
echo c - make-bfd/bfd
mkdir -p make-bfd/bfd > /dev/null 2>&1
echo x - make-bfd/bfd/libbfd.c
sed 's/^X//' >make-bfd/bfd/libbfd.c << 'END-of-make-bfd/bfd/libbfd.c'
X
X
X#ifndef SPECIAL_FLAG_THAT_IS_ONLY_HERE
X#error special flag not present.  neener neener neener.
X#endif
X
X
Xlibbfd_func()
X{
X
X}
X
END-of-make-bfd/bfd/libbfd.c
echo x - make-bfd/bfd/foo.c
sed 's/^X//' >make-bfd/bfd/foo.c << 'END-of-make-bfd/bfd/foo.c'
Xfoo_func(){}
END-of-make-bfd/bfd/foo.c
echo x - make-bfd/bfd/bar.c
sed 's/^X//' >make-bfd/bfd/bar.c << 'END-of-make-bfd/bfd/bar.c'
Xbar_func(){}
END-of-make-bfd/bfd/bar.c
echo x - make-bfd/bfd/Makefile
sed 's/^X//' >make-bfd/bfd/Makefile << 'END-of-make-bfd/bfd/Makefile'
X
XOFILES=	libbfd.o foo.o bar.o
XCFLAGS=	-DSPECIAL_FLAG_THAT_IS_ONLY_HERE
X
Xlibbfd.a: ${OFILES}
X	ar crv libbfd.a ${OFILES}
X	ranlib libbfd.a
X
Xclean:
X	/bin/rm -f ${OFILES} libbfd.a
END-of-make-bfd/bfd/Makefile
echo c - make-bfd/foo
mkdir -p make-bfd/foo > /dev/null 2>&1
echo x - make-bfd/foo/foo.c
sed 's/^X//' >make-bfd/foo/foo.c << 'END-of-make-bfd/foo/foo.c'
Xmain(){
Xfoo_func();
Xlibbfd_func();
X}
END-of-make-bfd/foo/foo.c
echo x - make-bfd/foo/Makefile
sed 's/^X//' >make-bfd/foo/Makefile << 'END-of-make-bfd/foo/Makefile'
X
Xfoo: foo.o ../bfd/libbfd.a
X	cc -o foo foo.o ../bfd/libbfd.a
X
Xclean:
X	/bin/rm -f foo *.o
END-of-make-bfd/foo/Makefile
exit


>Fix:
	Yanking the .c.a rule from sys.mk fixes the problem, but since
	POSIX (?) specifies that a .c.a rule should exist, it's not the
	right solution.

	I'm not sure of what the 'correct' behaviour is here.  it might
	be "don't apply the .X.Y rules to files that aren't in the
	current directory."
>Audit-Trail:
>Unformatted: