Az újabb gcc (4.6.3, ubuntu precise) linker megadott --start-group --end-group opciók ellenére egymenetesként működik. Így linkelek (script részlet a make rendszer mélyéről):
echo -Wl,--start-group >>$RSPLNK
for i in $BUILD_LIB; do echo $i >>$RSPLNK; done
echo -Wl,--end-group >>$RSPLNK
Az RSPLNK a válaszfálj neve. A --start-group --end-group opciók között felsorolódnak a linkelni kívánt könyvtárak. A válaszfájlt végül így használom:
c++ `cat $RSPLNK`
Namost ez 10 (vagy 20) évig jó volt így. Idén tavasszal, viszont azt vettem észre, hogy a linker mégis egymenetesen működik. Áthidaló megoldásként a scriptben megdupláztam a --start-group --end-group kiírását, így kétmenetes lesz. Működik, de a dolog felettébb bosszantó.
Másik eset:
A B.so hivatkozik egy A.so-ban definiált függvényre. B.so linkelésekor nincs magadva (eddig nem kellett) az A.so. A végrehajtható X program hivatkozik mind A.so-ra mind a B.so-ra. X linkelésekor megadom A.so-t is, B.so-t is. Eddig szépen működött.
Egy ideje azonban X linkelésekor az a hibaüzenet, hogy a B.so-ban feloldatlan hivatkozás marad egy A.so-beli függvényre. Ezért kénytelen vagyok már B.so-ba is belelinkelni az A.so-t.
Úgy látom, hogy itt indokolatlan funkcióvesztés van. Nem lehet számítani a dolgokra. Vélemények?
Hozzászólások
--no-as-needed ?
Köszönöm, ez volt a megoldás.
Nem az ld változott, hanem az ubuntu. Azt hiszem ubuntuban változtatták meg ennek az opciónak a defaultját. A debian wheezy-ben ugyanolyan változatú (2.22) ld van, mint a precise-ban, mégis a régi módon működik. Amúgy az --as-needed opció nyilvánvalóan rosszul működik, úgyhogy az egész csak szivatásra jó.
--
ulysses.co.hu
Amikor elkezdett bejönni a golden linker, akkor volt egy tonna hasonló jellegű bug(?), ami felszínre került (bocs, ha triviális).
A 4.6-os gcc már alapból preferálja a golden linkert (http://gcc.gnu.org/gcc-4.6/changes.html).
Flameeyes bloggolt elég sokat erről. Külön tag van a blog-ján a gold-hoz:
https://blog.flameeyes.eu/tag/gold
Habár azt a post-ot most hirtelen nem találom, ahol pont arról beszél, hogy mi van akkor ha A nem linkelte B-t, pedig a golden szerint kellett volna, de C linkeli A-t és B-t is. De volt valami ilyen is. Minden esetre a mostani binutils elég értelmesen kiírja, hogy mi ilyenkor a baja. Persze te nem binutils-ról, hanem gcc-ről beszélsz, tudom...
Szóval az a gyanúm, hogy nem bug, hanem feature.
Egyébként a golden az asszem nem egy GNU ragály. Felütötte a fejétt clang/llvm szinten is...
http://stackoverflow.com/questions/14954975/how-to-use-gold-for-link-ti…
Ebben nincs személyes tapasztalatom.
Az egymeneteshez nem tudok hozzászólni.
Üdv:
Dw.
"Jegyezze fel a vádhoz - utasította Metcalf őrnagy a tizedest, aki tudott gyorsírni. - Tiszteletlenül beszélt a feljebbvalójával, amikor nem pofázott közbe."
Köszönöm az infót. Fogalmam sem volt arról, hogy egyáltalán létezik a gold. Nálam mindenesetre nem az fut, hanem a GNU ld 2.22. Van ugyan egy binutils-gold csomag az ubuntu repóban, de nálam nincs installálva. Amúgy, az optimalizálásnál sokkal jobban érdekel a stabilitás és hordozhatóság. Rengeteg programot fordítok ugyanazzal a make rendszerrel Linuxon, BSD-n, Windowson, és rosszul érint, ha ilyen változások miatt megbicsaklik a hordozhatóság.
Nekem az a gyanúm, hogy a két eset összefügg. Azonkívül: Ha a 2. eset feature volna, akkor le kellene mondanunk olyan so-k készítéséről, amik keresztbe hivatkoznak egymásra, márpedig ez korábban lehetséges volt. Sőt, most is lehetséges, kipróbáltam egy mini projektben, amiben semmi más nincs csak egy ilyen kereszthivatkozás.
--
ulysses.co.hu
Ha most úgy linkeled, ahogy az a gold-nak ízlik, akkor az csökkenti a hordozhatóságot?
"Jegyezze fel a vádhoz - utasította Metcalf őrnagy a tizedest, aki tudott gyorsírni. - Tiszteletlenül beszélt a feljebbvalójával, amikor nem pofázott közbe."
Az időbeli hordozhatóság máris csökkent, mert az ld nem úgy működik, mint korábban (hanem hibásan). Ha a golddal linkelnék akkor a platformok közötti hordozhatóság is csökkenne, és egy csomó programot több platformon újra kellene tesztelni.
--
ulysses.co.hu
Tenyleg csak egy velemeny... vagyis inkabb ke'rde's:
Ezért kénytelen vagyok már B.so-ba is belelinkelni az A.so-t.
Ez pontosan miert is baj? Ha tudom, hogy B-nek szuksege lesz A-ra, akkor B-hez hozzalinkelem, en legalabbis eddig mindig igy csinaltam... Es ha majd a main()-t (X-et) forditjuk, akkor ott ma'r csak B-t kell hozzalinkelni, es akkor az `ldd` ma'r mindent jol mutat, mennek a dolgok. Szvsz ez a logikusabb sorrend.
Ugy remlik, kavarodas csak akkor volt mikor B-t dlopen()-nel huzzuk be, azaz X linkido"ben nincs semmi info errol...
Egyáltalán nem logikus. Egyszerűen a linker bizonyos esetekben nem teljesíti a feladatát (legalábbis az én mostani ubuntumon).
--
ulysses.co.hu
Nem akarlak megbántani, de a linker helyesen jar el ebben az esetben, korábban szimplán engedékenyebb volt.
// Happy debugging, suckers
#define true (rand() > 10)
Jo kerdesek. Az esetedet olyasmihez tudna'm hasonlitani, hogy mintha csak futtata'si ido"ben akarnank eldonteni, hogy egy adott funkciot/eljarast konkretan melyik lib is implemental. Pelda: me'g anno a gtk1.2/gtk2.0 atmenet tajekan byte-rol byte-ra ugyanazt a C kodot le lehetett forditatni -lgtk opcioval ill -lgtk2.0-val is (ill ugyanennek a pkg-config --libs megfelelojevel). Ahogy igy most atjon, olyasmi lenne a szerinted "nem logikus"-nak megfelelo opcio, hogy csak futtata'skor dontenem el hogy a gtk_random_funct() az most a gtk1-bol vagy gtk2-bol jon. Szoval en nem akarom megadni az X (main) linkele'sekor hogy mi kell, hanem "majd". Hogy (X) -> gtk szinten adom ezt elo" vagy (X -> B) -> A szinten, az kabe mindegy is...
Viszont, ha futtatasi idoben akarunk vmit eldonteni, akkor arra ott a dlopen(), dlsym() et al., szoval jo kerdes, hogy akkor most mi is a logikus. Igy roviden:
Akkor még egyszer. Nem arról van szó, hogy nem tudom összelinkelni a programomat. Az első posztban írtam, hogy már tavasszal észrevettem az eltérést, csak eddig együtt éltem vele. Most viszont van időm vizsgálódni, hogy mi a helyzet.
Az ld időnként egymenetesen működik. Feloldatlan hivatkozások maradnak. Ha csak annyit változtatok, hogy a könyvtárak felsorolását megduplázom (két menet), akkor megjavul.
Időnként nem old fel olyan hivatkozásokat, amikhez pedig meg van adva a könyvtár. Ha máshol (a linkelt so-k linkelésekor, elvileg feleslegesen) is megadom ugyanazt a könyvtárat, akkor megjavul.
Nem érdekelnek az olyan válaszok, amik azt magyarázzák, hogy valójában miért is éppen a hibás működés a jó.
Ezeken a rendszereken nem jelentkezik a hiba:
FreeBSD 8.2 64bit, ld 2.14 (2004.05.23)
intrepid 32bit, ld 2.18.93 (2008.10.09)
lucid 32bit, ld 2.20.1 (2010.03.03)
Ezen meg jelentkezik:
precise 64bit, ld 2.22 (nem írja ki a dátumot)
Arra tippelek hogy ez okozza az eltérést (ld changelist):
--
ulysses.co.hu
A tényállás pontosabb rögzítése.
A termek.exe program mindenféle so-kat linkel, többek között ezeket:
xmldom.so
util.so (hivatkozik xmldom.so-ra, de nem linkeli)
tds.so (hivatkozik xmldom.so-ra, és be is linkeli)
Ha a fenti séma szerint linkelek, akkor az ld 2.22 azt mondja,
hogy util.so-ban feloldatlan hivatkozás marad xmlparserNew-ra,
ami az xmldom.so-ban van, tehát elvileg fel kéne tudni oldania.
A következő 3 változtatás bármelyike megoldja a problémát:
1) Ha az util.so linkeléséhez hozzáadom xmldom.so-t, akkor megjavul.
2) Ha a tds.so linkeléséből kiveszem xmldom.so-t, akkor megjavul.
3) Valójában a termek.exe programnak nincs szüksége a tds.so-ra.
Ha a termek.exe linkeléséből kiveszem tds.so-t, akkor is megjavul.
A --copy-dt-needed-entries opció visszaállítása nem okoz semmilyen látható eltérést. Az egymenetesség sem változik.
--
ulysses.co.hu