statikus fordítás C

 ( kaltsi | 2009. július 30., csütörtök - 13:25 )

Lenne egy C progi amit úgy szeretnék fordítani, hogy az egy másik környezetben (másik kernel, libc verzió) alatt is lefusson.

Ebben kérnék segítséget, mert sajnos ezt a hibát kapom.

gcc -static -Wall progi.c -o progi

progi.c:(.text+0x7441): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Hat pedig elegge beszedes a figyelmezteto uzenet, mit is kell megoldanod mas rendszerek alatt, peldaul ifdef kapcsolokkal...

http://djszapi.homelinux.net

Hiaba ifdef, a buildhost parametereit veszi figyelembe. A leforditott kod lehet, hogy pl. bsd-n el sem fog indulni, hiaba ifdefezed meg, mert az forditaskor ertekelodik ki.
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

http://people.redhat.com/drepper/no_static_linking.html

En egy regi SuSE 8.1-esen szoktam forditani, azon 2.2.5-os glibc van. Minden ujabb verzioval fut.

hozzairod (marmint a parancsssorhoz) esetleg a /usr/lib/libc.a-t?

A.

Azért kapod ezt a hibaüzenetet, mert a gethostbyname() a Name Service Switch-et használja. Röviden és borzasztó pontatlanul ez annyit jelent, hogy amikor bármi ilyesmi name->entity lookup-ot csinálsz, legyen az user, group, host stb., akkor a glibc futásidőben benyalja az /etc/nsswitch.conf-ot, annak alapján pedig dlopen()-nel betölti a megfelelő NSS modult. Ezek a modulok mind egy public API-t szolgáltatnak, tehát a glibc a rendszeren bekonfigolt modul betöltése után, a konkrét modultól független módon szólítja fel a modult, hog csinálja meg a lookup-ot.

A fenti public API a glibc-vel együtt változik. Amikor te statikusan linkeled a programodat, akkor a glibc-nek a modult paraméterező/meghívó része rögzül, vagyis a programod csak egy adott API verzió szerint lesz képes az NSS modulokkal beszélni. Ha a futtató rendszeren eltérő API verziójú modulok vannak, akkor jobb esetben nem fog menni a name lookup, rosszabb esetben SIGSEGV.

Lásd info libc, majd Name Service Switch menüpont. Én csak ideböffentettem, ami eszembe jutott, bocs. A gépeden éppen fent lévő modulokat megnézheted így: ls -l /lib/libnss_*.so.

(A fentiben API/ABI különbségtétellel nem vacakoltam.)

Tehát a gondot alapvetően az okozza, hogy az NSS modul(oka)t nem tudod statikusan a programodhoz ragasztani, a glibc mindenképpen dinamikusan akarja betölteni. Az egésznek az az értelme, hogy így egy programban pl. egy felhasználói jelszó ellenőrzését nem kell mindig átírni ill. külön kezelni, ha helyi /etc/shadow-ról a rendszer áttér LDAP-ra: ilyenkor elég az /etc/nsswitch.conf-ot átírnia a rendszergazdának.

Azt ne kérdezd, hogy ez hogyan függ össze a PAM-mal, mert fogalmam sincs. Jó eséllyel versengő megoldások.

Mit tehetsz: a programodban a glibc-s gethostbyname() helyett használj egy külső resolver library-t, amelynek a licenszfeltételei megengedik, hogy statikusan linkelve terjeszd. Ötletekhez lásd pl. apt-cache search resolver library. A külső library nyújthat teljesen egyedien elnevezett függvényt, de az is lehet, hogy lesz benne egy gethostbyname(). Utóbbi esetben a programodat ezzel a libbel linkelve a glibc kódja helyett a library kódja fog beépülni (mivel a libc.so ill. libc.a mindig a linker parancssor végére kerül, és csak az addig feloldatlan referenciákat fedi le).

hu, ez nagyon szép leírás, köszönöm, így már teljesen világos minden