statikus fordítás C

Fórumok

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ások

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.

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).