[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: TODO
From: |
Daniel Reed |
Subject: |
Re: TODO |
Date: |
Mon, 15 Nov 2004 22:21:16 -0500 (EST) |
On 2004-11-15T19:27-0600, Bob Friesenhahn wrote:
) >> Yes. When you're making a distribution, Libtool's behaviour of directly
) >> linking indirect-dependencies is insane. For a SONAME change to a
) >> library deep in the stack, that only affects the library immediately
) >> above it, you suddenly need to rebuild your entire desktop environment.
Iteration 1:
libgeneral provides general_utility().
libadmiral provides admiral_electric() and admiral_water().
libcadet provides cadet_dance(), which uses general_utility() and
admiral_electric().
service uses cadet_dance() and admiral_water() in its main().
libcadet is linked to libgeneral and libadmiral.
service is linked to libcadet and libadmiral.
The resulting service executable is indirectly linked to libgeneral to
satisfy libcadet's dependency.
Iteration 2:
libcadet is changed to use libgeneral2's general2_utility().
service is now indirectly linked to libgeneral2 to satisfy libcadet's
dependency, and libgeneral is no longer in use.
(21:43)address@hidden:~/test> make service COMPILE=gcc LINK=gcc
gcc libgeneral.c -c -o libgeneral.o
gcc libgeneral.o -shared -o libgeneral.so
gcc libadmiral.c -c -o libadmiral.o
gcc libadmiral.o -shared -o libadmiral.so
gcc libcadet.c -c -o libcadet.o
gcc libcadet.o -shared -o libcadet.so -L. -Wl,-rpath,. -lgeneral -ladmiral
gcc service.c -c -o service.o
gcc service.o -o service -L. -Wl,-rpath,. -lcadet -ladmiral
(21:44)address@hidden:~/test> ldd service
libcadet.so => ./libcadet.so (0xf6ffe000)
libadmiral.so => ./libadmiral.so (0xf6ffb000)
libc.so.6 => /lib/tls/libc.so.6 (0x00703000)
libgeneral.so => ./libgeneral.so (0xf6fd9000)
/lib/ld-linux.so.2 (0x006ea000)
(21:44)address@hidden:~/test> ./service
main
cadet_dance
general_utility
admiral_electric
admiral_water
(21:44)address@hidden:~/test>
The base case is sane.
(21:46)address@hidden:~/test> make service COMPILE="libtool --mode=compile gcc"
LINK="libtool --mode=link gcc"
libtool --mode=compile gcc libgeneral.c -c -o libgeneral.o
mkdir .libs
gcc libgeneral.c -c -fPIC -DPIC -o .libs/libgeneral.o
gcc libgeneral.c -c -o libgeneral.o >/dev/null 2>&1
libtool --mode=link gcc libgeneral.o -shared -o libgeneral.so
gcc libgeneral.o -shared -o libgeneral.so
libtool --mode=compile gcc libadmiral.c -c -o libadmiral.o
gcc libadmiral.c -c -fPIC -DPIC -o .libs/libadmiral.o
gcc libadmiral.c -c -o libadmiral.o >/dev/null 2>&1
libtool --mode=link gcc libadmiral.o -shared -o libadmiral.so
gcc libadmiral.o -shared -o libadmiral.so
libtool --mode=compile gcc libcadet.c -c -o libcadet.o
gcc libcadet.c -c -fPIC -DPIC -o .libs/libcadet.o
gcc libcadet.c -c -o libcadet.o >/dev/null 2>&1
libtool --mode=link gcc libcadet.o -shared -o libcadet.so -L. -Wl,-rpath,.
-lgeneral -ladmiral
gcc libcadet.o -shared -o libcadet.so -Wl,-rpath -Wl,.
-L/home/boston/dreed/test -lgeneral -ladmiral
libtool --mode=compile gcc service.c -c -o service.o
gcc service.c -c -fPIC -DPIC -o .libs/service.o
gcc service.c -c -o service.o >/dev/null 2>&1
libtool --mode=link gcc service.o -o service -L. -Wl,-rpath,. -lcadet -ladmiral
gcc service.o -o service -Wl,-rpath -Wl,. -L/home/boston/dreed/test -lcadet
-ladmiral
(21:46)address@hidden:~/test> ldd service
libcadet.so => ./libcadet.so (0xf6ffe000)
libadmiral.so => ./libadmiral.so (0xf6ffb000)
libc.so.6 => /lib/tls/libc.so.6 (0x00703000)
libgeneral.so => ./libgeneral.so (0xf6fd9000)
/lib/ld-linux.so.2 (0x006ea000)
(21:46)address@hidden:~/test>
Looks good. Let's try iteration 2's change...
(21:50)address@hidden:~/test> make service2 COMPILE="libtool --mode=compile
gcc" LINK="libtool --mode=link gcc"
libtool --mode=compile gcc libgeneral2.c -c -o libgeneral2.o
gcc libgeneral2.c -c -fPIC -DPIC -o .libs/libgeneral2.o
gcc libgeneral2.c -c -o libgeneral2.o >/dev/null 2>&1
libtool --mode=link gcc libgeneral2.o -shared -o libgeneral2.so
gcc libgeneral2.o -shared -o libgeneral2.so
libtool --mode=compile gcc libcadet2.c -c -o libcadet2.o
gcc libcadet2.c -c -fPIC -DPIC -o .libs/libcadet2.o
gcc libcadet2.c -c -o libcadet2.o >/dev/null 2>&1
libtool --mode=link gcc libcadet2.o -shared -o libcadet.so -L. -Wl,-rpath,.
-lgeneral2 -ladmiral
gcc libcadet2.o -shared -o libcadet.so -Wl,-rpath -Wl,.
-L/home/boston/dreed/test -lgeneral2 -ladmiral
(21:50)address@hidden:~/test> ldd service
libcadet.so => ./libcadet.so (0xf6ffe000)
libadmiral.so => ./libadmiral.so (0xf6ffb000)
libc.so.6 => /lib/tls/libc.so.6 (0x00703000)
libgeneral2.so => ./libgeneral2.so (0xf6fd9000)
/lib/ld-linux.so.2 (0x006ea000)
(21:50)address@hidden:~/test> ./service
main
cadet_dance
general2_utility
admiral_electric
admiral_water
(21:50)address@hidden:~/test>
Still good. The service executable is no longer linked to libgeneral.so in
any way and works as expected. Let's try "full blown" Libtool (using .la
files)...
(22:00)address@hidden:~/test> make servicela COMPILE="libtool --mode=compile
gcc" LINK="libtool --mode=link gcc"
libtool --mode=compile gcc libgeneral.c -c -o libgeneral.lo
mkdir .libs
gcc libgeneral.c -c -fPIC -DPIC -o .libs/libgeneral.o
gcc libgeneral.c -c -o libgeneral.o >/dev/null 2>&1
libtool --mode=link gcc libgeneral.lo -shared -o libgeneral.la -rpath /tmp
gcc -shared .libs/libgeneral.o -Wl,-soname -Wl,libgeneral.so.0 -o
.libs/libgeneral.so.0.0.0
(cd .libs && rm -f libgeneral.so.0 && ln -s libgeneral.so.0.0.0 libgeneral.so.0)
(cd .libs && rm -f libgeneral.so && ln -s libgeneral.so.0.0.0 libgeneral.so)
ar cru .libs/libgeneral.a libgeneral.o
ranlib .libs/libgeneral.a
creating libgeneral.la
(cd .libs && rm -f libgeneral.la && ln -s ../libgeneral.la libgeneral.la)
libtool --mode=compile gcc libadmiral.c -c -o libadmiral.lo
gcc libadmiral.c -c -fPIC -DPIC -o .libs/libadmiral.o
gcc libadmiral.c -c -o libadmiral.o >/dev/null 2>&1
libtool --mode=link gcc libadmiral.lo -shared -o libadmiral.la -rpath /tmp
gcc -shared .libs/libadmiral.o -Wl,-soname -Wl,libadmiral.so.0 -o
.libs/libadmiral.so.0.0.0
(cd .libs && rm -f libadmiral.so.0 && ln -s libadmiral.so.0.0.0 libadmiral.so.0)
(cd .libs && rm -f libadmiral.so && ln -s libadmiral.so.0.0.0 libadmiral.so)
ar cru .libs/libadmiral.a libadmiral.o
ranlib .libs/libadmiral.a
creating libadmiral.la
(cd .libs && rm -f libadmiral.la && ln -s ../libadmiral.la libadmiral.la)
libtool --mode=compile gcc libcadet.c -c -o libcadet.lo
gcc libcadet.c -c -fPIC -DPIC -o .libs/libcadet.o
gcc libcadet.c -c -o libcadet.o >/dev/null 2>&1
libtool --mode=link gcc libcadet.lo -shared -o libcadet.la -rpath /tmp -L.
-Wl,-rpath,. -lgeneral -ladmiral
gcc -shared .libs/libcadet.o -Wl,--rpath -Wl,/home/boston/dreed/test/.libs
-Wl,--rpath -Wl,/tmp -L/home/boston/dreed/test
/home/boston/dreed/test/.libs/libgeneral.so
/home/boston/dreed/test/.libs/libadmiral.so -Wl,-rpath -Wl,. -Wl,-soname
-Wl,libcadet.so.0 -o .libs/libcadet.so.0.0.0
(cd .libs && rm -f libcadet.so.0 && ln -s libcadet.so.0.0.0 libcadet.so.0)
(cd .libs && rm -f libcadet.so && ln -s libcadet.so.0.0.0 libcadet.so)
ar cru .libs/libcadet.a libcadet.o
ranlib .libs/libcadet.a
creating libcadet.la
(cd .libs && rm -f libcadet.la && ln -s ../libcadet.la libcadet.la)
libtool --mode=compile gcc service.c -c -o service.o
gcc service.c -c -fPIC -DPIC -o .libs/service.o
gcc service.c -c -o service.o >/dev/null 2>&1
libtool --mode=link gcc service.o -o service -L. -Wl,-rpath,. -lcadet -ladmiral
gcc service.o -o .libs/service -Wl,-rpath -Wl,. -L/home/boston/dreed/test
/home/boston/dreed/test/.libs/libcadet.so
/home/boston/dreed/test/.libs/libgeneral.so
/home/boston/dreed/test/.libs/libadmiral.so -Wl,--rpath -Wl,/tmp
creating service
(22:00)address@hidden:~/test> env LD_LIBRARY_PATH=.libs ldd .libs/service
libcadet.so.0 => .libs/libcadet.so.0 (0xf6ffe000)
libgeneral.so.0 => .libs/libgeneral.so.0 (0xf6ffb000)
libadmiral.so.0 => .libs/libadmiral.so.0 (0xf6ff9000)
libc.so.6 => /lib/tls/libc.so.6 (0x00703000)
/lib/ld-linux.so.2 (0x006ea000)
(22:00)address@hidden:~/test>
We're beginning to see trouble here. Libtool explicitly linked service
against .libs/libgeneral.so, even though I did not specify it as a
dependency of the service executable (no explicit -lgeneral). Let's try
iteration 2...
(22:07)address@hidden:~/test> make servicela2 COMPILE="libtool --mode=compile
gcc" LINK="libtool --mode=link gcc"
libtool --mode=compile gcc libgeneral2.c -c -o libgeneral2.lo
gcc libgeneral2.c -c -fPIC -DPIC -o .libs/libgeneral2.o
gcc libgeneral2.c -c -o libgeneral2.o >/dev/null 2>&1
libtool --mode=link gcc libgeneral2.lo -shared -o libgeneral2.la -rpath /tmp
gcc -shared .libs/libgeneral2.o -Wl,-soname -Wl,libgeneral2.so.0 -o
.libs/libgeneral2.so.0.0.0
(cd .libs && rm -f libgeneral2.so.0 && ln -s libgeneral2.so.0.0.0
libgeneral2.so.0)
(cd .libs && rm -f libgeneral2.so && ln -s libgeneral2.so.0.0.0 libgeneral2.so)
ar cru .libs/libgeneral2.a libgeneral2.o
ranlib .libs/libgeneral2.a
creating libgeneral2.la
(cd .libs && rm -f libgeneral2.la && ln -s ../libgeneral2.la libgeneral2.la)
libtool --mode=compile gcc libcadet2.c -c -o libcadet2.lo
gcc libcadet2.c -c -fPIC -DPIC -o .libs/libcadet2.o
gcc libcadet2.c -c -o libcadet2.o >/dev/null 2>&1
libtool --mode=link gcc libcadet2.lo -shared -o libcadet.la -rpath /tmp -L.
-Wl,-rpath,. -lgeneral2 -ladmiral
rm -fr .libs/libcadet.a .libs/libcadet.la .libs/libcadet.lai .libs/libcadet.so
.libs/libcadet.so.0 .libs/libcadet.so.0.0.0
gcc -shared .libs/libcadet2.o -Wl,--rpath -Wl,/home/boston/dreed/test/.libs
-Wl,--rpath -Wl,/tmp -L/home/boston/dreed/test
/home/boston/dreed/test/.libs/libgeneral2.so
/home/boston/dreed/test/.libs/libadmiral.so -Wl,-rpath -Wl,. -Wl,-soname
-Wl,libcadet.so.0 -o .libs/libcadet.so.0.0.0
(cd .libs && rm -f libcadet.so.0 && ln -s libcadet.so.0.0.0 libcadet.so.0)
(cd .libs && rm -f libcadet.so && ln -s libcadet.so.0.0.0 libcadet.so)
ar cru .libs/libcadet.a libcadet2.o
ranlib .libs/libcadet.a
creating libcadet.la
(cd .libs && rm -f libcadet.la && ln -s ../libcadet.la libcadet.la)
(22:07)address@hidden:~/test> env LD_LIBRARY_PATH=.libs ldd .libs/service
libcadet.so.0 => .libs/libcadet.so.0 (0xf6ffe000)
libgeneral.so.0 => .libs/libgeneral.so.0 (0xf6ffb000)
libadmiral.so.0 => .libs/libadmiral.so.0 (0xf6ff9000)
libc.so.6 => /lib/tls/libc.so.6 (0x00703000)
libgeneral2.so.0 => /home/boston/dreed/test/.libs/libgeneral2.so.0
(0xf6fd7000)
/lib/ld-linux.so.2 (0x006ea000)
(22:07)address@hidden:~/test>
Brilliant. Because service was not recompiled against the new libcadet.la,
it now links against both libgeneral.so and libgeneral2.so (the latter by
way of the new libcadet.so) :(
In situations where only the .so is present, Libtool arguably does the right
thing. (It does not try to guess dependency dependencies based on ldd or
anything like that; it just doesn't link in dependency dependencies.)
In situations where the .la is present, Libtool *does* try to link in
dependency dependencies, even though that isn't necessary.
I believe the point of this proposed change is to eliminate that latter
behavior. It would be a benefit on Linux and similar systems without
directly hindering dissimilar systems (as the behavior would not change on
those systems).
As far as encouraging developers to list dependencies incorrectly or not at
all, in the above scenario, even if the package developer had caused the
service executable's build scripts to link explicitly against its
dependencies dependencies (libgeneral, in this case), it still would have
broken on systems that do not implicitly link dependencies dependencies at
run time (as service would have been explicitly linked with libgeneral, not
libgeneral2, just as with the current Libtool behavior when dealing with .la
files). I do not believe there is a developer education danger from this
proposed change.
--
Daniel Reed <address@hidden> http://people.redhat.com/djr/
http://naim.n.ml.org/
"Murphy's Law is recursive. Washing your car to make it rain doesn't
work."
- Re: TODO, (continued)
- Re: TODO, Scott James Remnant, 2004/11/16
- Re: TODO, Jacob Meuser, 2004/11/16
- Re: TODO, Scott James Remnant, 2004/11/16
- Re: TODO, Jacob Meuser, 2004/11/16
- Re: TODO, Ralf Wildenhues, 2004/11/17
- Re: TODO, Jacob Meuser, 2004/11/17
- Re: TODO, Ralf Wildenhues, 2004/11/16
- Re: TODO, Joe Orton, 2004/11/15
- Re: TODO, Scott James Remnant, 2004/11/15
- Re: TODO, Bob Friesenhahn, 2004/11/15
- Re: TODO,
Daniel Reed <=
- Re: TODO, Bob Friesenhahn, 2004/11/15
- Re: TODO, Jacob Meuser, 2004/11/14
- Re: TODO, Scott James Remnant, 2004/11/14
- Re: TODO, Jacob Meuser, 2004/11/14
- Re: TODO ... solution to the pkg-config "conflict"?, Jacob Meuser, 2004/11/14
- Re: TODO ... solution to the pkg-config "conflict"?, Scott James Remnant, 2004/11/15
- Re: TODO, Scott James Remnant, 2004/11/14
- Re: TODO, Daniel Reed, 2004/11/14
- Re: TODO, Scott James Remnant, 2004/11/15
Re: TODO, Bob Friesenhahn, 2004/11/09