Subject: lib/14325: linking with '-static -lresolv' fails due to "multiple definition of `__res_opt'"
To: None <gnats-bugs@gnats.netbsd.org>
From: Greg A. Woods <woods@weird.com>
List: netbsd-bugs
Date: 10/22/2001 19:19:14
>Number:         14325
>Category:       lib
>Synopsis:       linking with '-static -lresolv' fails due to "multiple definition of `__res_opt'"
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Oct 22 16:20:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Greg A. Woods
>Release:        NetBSD-current 2001/06/24
>Organization:
Planix, Inc.; Toronto, Ontario; Canada
>Environment:

System: NetBSD 1.5W
Architecture: i386
Machine: i386

>Description:

	Programs which use the DNS resolver functions cannot be linked
	statically if '-lresolv' is also specified in LDFLAGS.  Attempts
	to do so result in complaints of multiple definitions of __res_opt.

	This is caused by libc.a's version of res_mkquery.o defining
	only a weak reference to res_mkquery(), and containing only a
	proper definition for _res_mkquery().  However libresolv.a's
	version of res_mkquery.o contains only a proper definition of
	res_mkquery() and no definition of _res_mkquery().  Since other
	libc functions using res_mkquery() are actually using only
	_res_mkquery(), the libc.a version of res_mkquery.o will be
	referenced even though the libresolv.a version has already been
	referenced.

>How-To-Repeat:

	$ make LDFLAGS='-v -static' RES='-lresolv'                                 
	cc -v -static -o host main.o info.o list.o addr.o geth.o util.o misc.o test.o  file.o send.o vers.o -lresolv  
	Using builtin specs.
	gcc version egcs-2.91.66 19990314 (egcs-1.1.2 release)
	 /usr/libexec/collect2 -m elf_i386 -dc -dp -e __start -static -o host /usr/lib/crt0.o /usr/lib/crtbegin.o -L/usr/libexec main.o info.o list.o addr.o geth.o util.o misc.o test.o file.o send.o vers.o -lresolv -lgcc -lc -lgcc /usr/lib/crtend.o
	/usr/lib/libc.a(res_mkquery.o): In function `__res_opt':
	res_mkquery.o(.text+0x230): multiple definition of `__res_opt'
	/usr/lib/libresolv.a(res_mkquery.o)(.text+0x204): first defined here
	collect2: ld returned 1 exit status
	*** Error code 1

	$ nm /var/NetBSD-obj/lib/libc/res_mkquery.o                                                             
	         U __dn_comp
	         U __putlong
	         U __putshort
	00000230 T __res_opt
	         U _res
	         U _res_init
	00000000 T _res_mkquery
	         U h_errno
	         U memcpy
	         U printf
	00000000 W res_mkquery

	$ nm /var/NetBSD-obj/lib/libresolv/res_mkquery.o
	         U __dn_comp
	         U __putlong
	         U __putshort
	00000204 T __res_opt
	         U _res
	         U h_errno
	         U memcpy
	         U res_init
	00000000 T res_mkquery

	$ nm /usr/lib/libc.a | fgrep res_mkquery
	         U _res_mkquery
	         U _res_mkquery
	         U _res_mkquery
	res_mkquery.o:
	00000000 T _res_mkquery
	00000000 W res_mkquery


>Fix:

	I'm not sure this is the best solution, but it seems the
	weak_alias trick used in libc needs to be enabled for
	libresolv.a too.

	I suppose this could be done by adding "CPPFLAGS+=-D_LIBC" to
	src/lib/libresolv/Makefile, but I don't know if there'd be other
	undesired fallout from doing this.

	Better though might be to add a new "CPPFLAGS+=-D_RESOLV" in
	that file and appropriate uses of "#if defined(_RESOLV)" in the
	various source files in src/lib/libc/net/.

	The obvious work-around is of course to simply remove '-lresov'
	from the builds fo any programs since it's strictly redundant
	when libc is also used.  However this is undesirable because in
	many cases it's something far easier said than done.  If
	libresolv.a is to be offered to simplify builds, it should
	actually work!  :-)

>Release-Note:
>Audit-Trail:
>Unformatted: