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: