User Tools

Site Tools


developingpld:advanceddeveloping:fixingasneeded

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
developingpld:advanceddeveloping:fixingasneeded [2006-08-07 02:53]
SamChi
developingpld:advanceddeveloping:fixingasneeded [2006-08-08 15:42]
SamChi - typo
Line 7: Line 7:
 Put in spec file this line:  Put in spec file this line: 
  
-<​file>​%devine ​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. 
Line 16: Line 16:
  
 ===== How --as-needed works ===== ===== How --as-needed works =====
-With ''​--as-needed''​ enabled only libraries ​which contain ​symbols required by __object files__ are linked. ​+With ''​--as-needed''​ enabledonly libraries ​containing ​symbols required by __object files__ are linked. ​
  
  
  
 == About positions == == About positions ==
-Linker options are positional, and position is very important. ​Because 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. 
  
-Correct ​ones are: +Correct ​positions ​are: 
  
 <​file>​$ gcc $(LDFLAGS) -o $@ $(OBJECTS) $(LIBS) <​file>​$ gcc $(LDFLAGS) -o $@ $(OBJECTS) $(LIBS)
Line 41: Line 41:
 <​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'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&​amp;​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&​amp;​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 61: Line 61:
 <​file>​$ gcc -Wl,​--as-needed -o executable <​objects.o>​ -l2 -l1 <​file>​$ gcc -Wl,​--as-needed -o executable <​objects.o>​ -l2 -l1
 </​file>​ </​file>​
-it's usual when object files require only library 2, and -l1 is required by -l2. As I said linker only checks for symbols from objects, so -l1 is not linked. Normally it is easy to fix it, simply make sure while linking -l2 it is linked to -l1 (take a look at the second real example). ​+It's usual situation ​when object files require only library 2, and //-l1// is required by //-l2//. As I said linker only checks for symbols from objects, so //-l1// is not linked. Normally it is easy to fix it, simply make sure while linking ​//-l2// it is linked to //-l1// (take a look at the second real example). ​
  
  
Line 75: Line 75:
  
  
-<​file>​x86_64-pld-linux-g++ -DNOMMGR -Wall -DGAMEDATADIR=\"/​usr/​share/​xmoto\" ​ -ggdb -O2 -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 100: Line 100:
 Binary file /​usr/​lib64/​libSDL.so matches Binary file /​usr/​lib64/​libSDL.so matches
 </​file>​ </​file>​
-they are in ''​-lSDL'',​ but binary does not link with ''​-lSDL''​; edit Makefile by hand and add ''​-lSDL''​ at the same place ''​-lSDL_mixer''​ is: ''​LIBS = -lcurl -lode -llualib50 -llua50 -lSDL_mixer -lSDL -lbz2 -lz -lpng -ljpeg'' ​+They are in ''​-lSDL'',​ but binary does not link with ''​-lSDL''​. Edit Makefile by hand and add ''​-lSDL''​ at the same place ''​-lSDL_mixer''​ is: ''​LIBS = -lcurl -lode -llualib50 -llua50 -lSDL_mixer -lSDL -lbz2 -lz -lpng -ljpeg'' ​
  
 What we get after running make in build tree:  What we get after running make in build tree: 
Line 106: Line 106:
  
  
-<​file>​x86_64-pld-linux-g++ -DNOMMGR -Wall -DGAMEDATADIR=\"/​usr/​share/​xmoto\"​ -ggdb -O2 -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 139:
  
  
-<​file>​x86_64-pld-linux-g++ -DNOMMGR -Wall -DGAMEDATADIR=\"/​usr/​share/​xmoto\" ​ -ggdb -O2 -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'​
 </​file>​ </​file>​
-//It worked !// +**It worked !** 
  
  
Line 180: Line 180:
  
  
-<​file>/​bin/​sh ../libtool --tag=CC --mode=link ​x86_64-pld-linux-gcc -ggdb -O2 -Wall  ​-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 -ggdb -O2 -Wall -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 212: Line 212:
 ''​GNOME_KEYRING_LIBS = -lgnome-keyring -lglib-2.0'' ​ ''​GNOME_KEYRING_LIBS = -lgnome-keyring -lglib-2.0'' ​
  
-So add this one and glade to that library deps: +So add this one and ''​-lglade-2.0'' ​to that library deps: 
  
  
Line 235: Line 235:
  
 == Why was it working without --as-needed ? == == Why was it working without --as-needed ? ==
-test-source-selector binary was linked with all libraries needed by libedataserverui-1.2.so,​ and the binary was the one who provided missing symbols to libedataserverui-1.2.so ​+''​test-source-selector'' ​binary was linked with all libraries needed by libedataserverui-1.2.so,​ and the binary was the one who provided missing symbols to libedataserverui-1.2.so ​ 
 + 
 + 
 + 
 +=== What if broken library comes from other package ? === 
 +You can check manually does library has all required symbols, simply running ' gcc //library// ', like this:  
 + 
 +This is an example of correctly linked library:  
 + 
 +<​file>​$ gcc /​usr/​lib64/​liblftp-tasks.so.0.0.0 
 +/​usr/​lib64/​gcc/​x86_64-pld-linux/​4.1.2/​../​../​../​../​lib64/​crt1.o:​ In function `_start':​ 
 +(.text+0x20):​ undefined reference to `main'​ 
 +collect2: ld returned 1 exit status 
 +</​file>​ 
 +And incorrectly linked one:  
 + 
 +<​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':​ 
 +(.text+0x20):​ undefined reference to `main'​ 
 +/​usr/​lib64/​liblftp-jobs.so.0.0.0:​ undefined reference to `StringSet::​Remove(int)'​ 
 +/​usr/​lib64/​liblftp-jobs.so.0.0.0:​ undefined reference to `Buffer::​Format(char const*, ...)'​ 
 +[...] 
 +/​usr/​lib64/​liblftp-jobs.so.0.0.0:​ undefined reference to `SMTask::​SuspendSlave()'​ 
 +collect2: ld returned 1 exit status 
 +</​file>​ 
 +**Warning:​** some libraries may require to have unresolved symbols. ​
  
  
Line 258: Line 283:
  
  
-<​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':​
Line 265: Line 290:
 collect2: ld returned 1 exit status collect2: ld returned 1 exit status
 </​file>​ </​file>​
-function '''​convert_ToPilotChar''',​ may be found in passed library, but take a look at section about positions, arguments order is incorrect: libraries go before objects (conftest.c) ​it's very common when someone puts ''​-l<>''​ in ''​LDFLAGS''​ instead of ''​LIBS'',​ that was the case too +function '''​convert_ToPilotChar''',​ may be found in passed library, but take a look at section about positions, arguments order is incorrect: libraries go before objects (conftest.c). It's very common when someone puts ''​-l<>''​ in ''​LDFLAGS''​ instead of ''​LIBS'',​ that was the case too
  
-just take a look at my fix: +Just take a look at my fix: 
  
  
Line 279: Line 304:
 +       ​LIBS="​$LIBS_save"​ +       ​LIBS="​$LIBS_save"​
 </​file>​ </​file>​
-with this simple change everything works perfectly. ​+With this simple change everything works perfectly. ​
  
  
developingpld/advanceddeveloping/fixingasneeded.txt · Last modified: 2007-05-27 20:51 by arekm