This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
developingpld:advanceddeveloping:fixingasneeded [2006-08-07 21:55] SamChi |
developingpld:advanceddeveloping:fixingasneeded [2007-05-27 20:51] (current) arekm |
||
---|---|---|---|
Line 4: | Line 4: | ||
- | ==== Quick Workaround ==== | + | ===== Quick and ugly workaround (DON'T USE IT!) ===== |
- | Put in spec file this line: | + | Put this line in ''spec'' file: |
+ | |||
<file>%define filterout_ld -Wl,--as-needed | <file>%define filterout_ld -Wl,--as-needed | ||
</file> | </file> | ||
- | But **don't use it** unless you really need. | + | But **don't use it** unless you really need to quickly build a package. Never ever try to commit such a change. It might be tempting to do so but if you think about it ''--as-needed'' did it's job well and disabled unneeded libraries. If building fails, it's the package that needs to get fixed, not the linker flags. |
- | + | ||
- | Why ? Because it's very stupid. If something fails to build normally it's a sign ''--as-needed'' did well it's job and disabled unneeded libraries. | + | |
Line 20: | Line 20: | ||
- | == About positions == | + | ==== Why it fails for some packages ==== |
+ | In other words, if you list 10 libraries and only 3 of them contain referenced symbols, others are silently discarded. This is a good thing but unfortunately some projects fail to list all their dependencies properly. | ||
+ | |||
+ | This normally works because if project requires libraries //A// and //B// and //A// itself lists //B// as a dependency, both //A// and //B// get pulled in even if the project itself only lists //A//. | ||
+ | |||
+ | Now assume that //A// is a superfluous (unneeded) dependency which gets dropped (or //A// requiring //B// is superfluous and //B// gets dropped from //A//). The symbols are no longer available. | ||
+ | |||
+ | |||
+ | |||
+ | ==== About positions ==== | ||
Linker options are positional, and position is very important. It looks for missing symbols only in libraries coming after object file. | Linker options are positional, and position is very important. It looks for missing symbols only in libraries coming after object file. | ||
Line 41: | Line 50: | ||
<file>$ gcc -l<library> -Wl,--as-needed <objects.o> | <file>$ gcc -l<library> -Wl,--as-needed <objects.o> | ||
</file> | </file> | ||
- | library will allways be linked, even if it's not required. | + | library will __allways__ be linked, even if it isn't required. |
==== Short examples ==== | ==== Short examples ==== | ||
- | Most of problems are with readline/ncurses and tinfo, and it's nice example: tinfo is required by both readline and ncurses, and both are linked with this library (now, when I've [[http://cvs.pld-linux.org/cgi-bin/cvsweb/SOURCES/readline-shared.patch?r1=1.6&r2=1.7|fixed readline]]). | + | Most of problems are with readline/ncurses and tinfo, and it's nice example: tinfo is required by both readline and ncurses, and both are linked with this library (now, when [[http://cvs.pld-linux.org/cgi-bin/cvsweb/SOURCES/readline-shared.patch?r1=1.6&r2=1.7|fixed readline]] is fixed). |
- | But some packages link with readline or ncurses while they use __only__ symbols from tinfo. //Without// ''--as-needed'' those executables work because they are linked with tinfo from readline/ncurses library. //With// ''--as-needed'' it will not work, because readline/ncurses contain no symbols required by executable so they are not linked, it's dependencies naturally are neither linked. Thats why there is a need to pass ''-ltinfo''. If it requires only symbols from tinfo it's ok to ''s/ncurses/tinfo/''. But if it really requires readline/ncurses but there is some executable (or ./configure) which requires only tinfo both ''-lreadline''/''-lncurses'' and ''-ltinfo'' should be passed. | + | But some packages link with readline or ncurses while they use __only__ symbols from tinfo. //Without// ''--as-needed'' those executables work because they are linked with tinfo from readline/ncurses library. //With// ''--as-needed'' linking will not work, because readline/ncurses contain no symbols required by executable so they are not linked, it's dependencies naturally are neither linked. Thats why there is a need to pass ''-ltinfo''. If it requires only symbols from tinfo it's ok to ''s/ncurses/tinfo/''. But if it really requires readline/ncurses but there is some executable (or ./configure) which requires only tinfo both ''-lreadline''/''-lncurses'' and ''-ltinfo'' should be passed. |
For a longer example take a look at real example nr. 1. | For a longer example take a look at real example nr. 1. | ||
Line 75: | Line 84: | ||
- | <file>x86_64-pld-linux-g++ -Wl,--as-needed -o xmoto-edit BuiltInFont.o [...object files...] Packager.o -lGL -lcurl -lode -llualib50 -llua50 -lSDL_mixer -lbz2 -lz -lpng -ljpeg | + | <file>g++ -Wl,--as-needed -o xmoto-edit BuiltInFont.o [...object files...] Packager.o -lGL -lcurl -lode -llualib50 -llua50 -lSDL_mixer -lbz2 -lz -lpng -ljpeg |
VApp.o: In function `vapp::App::getRealTime()': | VApp.o: In function `vapp::App::getRealTime()': | ||
Line 106: | Line 115: | ||
- | <file>x86_64-pld-linux-g++ -Wl,--as-needed -o xmoto-edit BuiltInFont.o [...object files...] Packager.o -lcurl -lode -llualib50 -llua50 -lSDL_mixer -lSDL -lbz2 -lz -lpng -ljpeg | + | <file>g++ -Wl,--as-needed -o xmoto-edit BuiltInFont.o [...object files...] Packager.o -lcurl -lode -llualib50 -llua50 -lSDL_mixer -lSDL -lbz2 -lz -lpng -ljpeg |
VApp.o: In function `vapp::App::grabScreen()': | VApp.o: In function `vapp::App::grabScreen()': | ||
Line 139: | Line 148: | ||
- | <file>x86_64-pld-linux-g++ -Wl,--as-needed -o xmoto-edit BuiltInFont.o [...object files...] Packager.o -lcurl -lode -llualib50 -llua50 -lSDL_mixer -lSDL -lGL -lbz2 -lz -lpng -ljpeg | + | <file>g++ -Wl,--as-needed -o xmoto-edit BuiltInFont.o [...object files...] Packager.o -lcurl -lode -llualib50 -llua50 -lSDL_mixer -lSDL -lGL -lbz2 -lz -lpng -ljpeg |
make[1]: Leaving directory `/home/users/sparky/rpm/BUILD/xmoto-0.2.0' | make[1]: Leaving directory `/home/users/sparky/rpm/BUILD/xmoto-0.2.0' | ||
Line 180: | Line 189: | ||
- | <file>/bin/sh ../libtool --tag=CC --mode=link x86_64-pld-linux-gcc -Wl,--as-needed -o test-source-selector test-source-selector.o libedataserverui-1.2.la ../libedataserver/libedataserver-1.2.la -pthread -lglade-2.0 [...many -l libraries...] | + | <file>/bin/sh ../libtool --tag=CC --mode=link gcc -Wl,--as-needed -o test-source-selector test-source-selector.o libedataserverui-1.2.la ../libedataserver/libedataserver-1.2.la -pthread -lglade-2.0 [...many -l libraries...] |
-lgnome-keyring -lpthread | -lgnome-keyring -lpthread | ||
- | x86_64-pld-linux-gcc -Wl,--as-needed -o .libs/test-source-selector test-source-selector.o -pthread ./.libs/libedataserverui-1.2.so [...many, many .so and -l libraries...] -lpthread | + | gcc -Wl,--as-needed -o .libs/test-source-selector test-source-selector.o -pthread ./.libs/libedataserverui-1.2.so [...many, many .so and -l libraries...] -lpthread |
./.libs/libedataserverui-1.2.so: undefined reference to `glade_xml_new' | ./.libs/libedataserverui-1.2.so: undefined reference to `glade_xml_new' | ||
Line 249: | Line 258: | ||
collect2: ld returned 1 exit status | collect2: ld returned 1 exit status | ||
</file> | </file> | ||
- | And inclorrectly linked one: | + | And incorrectly linked one: |
- | <file>$ gcc /usr/lib64/liblftp-jobs.so.0.0.0 | + | <file>$ gcc /usr/lib64/liblftp-jobs.so.0.0.0 |
/usr/lib64/gcc/x86_64-pld-linux/4.1.2/../../../../lib64/crt1.o: In function `_start': | /usr/lib64/gcc/x86_64-pld-linux/4.1.2/../../../../lib64/crt1.o: In function `_start': | ||
(.text+0x20): undefined reference to `main' | (.text+0x20): undefined reference to `main' | ||
Line 283: | Line 292: | ||
- | <file>x86_64-pld-linux-gcc -o conftest -ggdb -O2 -DORBIT2=1 -pthread -I/usr/include/libgnome-2.0 [...many -I...] -I/usr/include/libxml2 -Wl,--as-needed -pthread -lgpilotd [...many -l...] -lglib-2.0 conftest.c >&5 | + | <file>gcc -o conftest -ggdb -O2 -DORBIT2=1 -pthread -I/usr/include/libgnome-2.0 [...many -I...] -I/usr/include/libxml2 -Wl,--as-needed -pthread -lgpilotd [...many -l...] -lglib-2.0 conftest.c >&5 |
/home/users/sparky/tmp/ccgrL9ll.o: In function `main': | /home/users/sparky/tmp/ccgrL9ll.o: In function `main': |