Fordítás (GNU és egyéb) - 3

 ( NevemTeve | 2012. december 3., hétfő - 18:09 )

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

Talán off-topik, de rpm-et szeretnék csinálni, linuxon és AIX-en. Erre való az 'rpm -bb specfájl'. Vagyis így volt, míg nem léptünk előre az rpmbuild-ra. Először is kell neki egy --buildroot, ami nem lehet a gyökér. Akkor legyen a /../ könyvtár, és minden jó lesz. Nem lett minden jó, mivel úgy érzi, hogy 'segítenie' kell, vagyis ellenőrzi, hogy a specfájlban felsorolt fájlok mellett vannak-e még más fájlok is, mert ha igen, akkor azokat nyilván tévedésből felejtettem ki. Akkor most erről kellene lebeszélni.

Checking for unpackaged file(s): /usr/lib/rpm/check-files /..

Szerk:
build/files.c:checkFiles az elkövető, és mintha lenne egy __check_files opció, amivel ezt el lehetne nyomni.

Szerk: a specfájlba:
%define __check_files %{nil}

következő okos ötlet az rpmbuild részéről:
/bin/rm: cannot remove directory: `/..'

Hát, bevallom, nem örültem volna, ha sikerül neki... egészen pontosan ki mondta neki, hogy bármit is töröljon?

Szerk: ez lett a megoldás (specfájl végére):

%clean
echo Done

Jujj... tenyleg no offense, de ebbe inkabb vagy ne artsd bele magad, vagy olvasd el a vonatkozo szakirodalmat. Az rpm ezeket az ellenorzeseket nem veletlenul csinalja, es szerintem jobba tesz, ha betartod a szabalyokat.

Ja, es a buildroot az pedig legyen valami ertelmes mappa, semmikeppen sem relativ utvonal! Tessek felrakni egy centos-t, vagy egy suse-t es megnezni, hogy ott mik az utvonalak!

Az rpm egy nagyon jol osszerakott cucc, te pedig ganyolni akarsz vele - meg szep hogy nem engedi.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal

De ez egyszer már működött, 'rpm -bb specfájl' módon, ehhez képest most 'meg lett jobbítva' rpmbuilddá... Értem, hogy csak segíteni akarnak, amikor kirúgják alólam széket, akarom mondani, inkompatibilis fejlesztést végeznek... csak azt kellene észben tartsák, hogy ez már nem csak az ő magánjátékszerük, hanem egyfajta ipari standard lett...
http://en.wikipedia.org/wiki/Linux_Standard_Base#Choice_of_RPM_package_format

PS: a --buildroot /../ az nem relatív útvonal, az a gyökérkönyvtár másik neve

De buildrootot nem teszunk a gyokerbe, ezt tessen man megerteni.

Egyebkent pont azert vannak ezek a cuccok benne, mert ipari standard lett. Peldaul ez a build root is azert van megcsinalva, hogy lehessen erzekelni, ha valami a build rooton kivulre akar irni, az a csomag ugyanis hibas, szar, mint ilyen minosegileg kifogasolhato, vagyis fixalni kell, a folyamat vegen nem eshet ki RPM.

Pont azert kell ezeket a szabalyokat betartani, mert az RPM immar nem kiscserkeszek fakardja, hanem olyan cucc, amivel termekeket allitanak elo. Az RPM kozvetlen azutan, hogy legordul az rpmbuild-rol, egybol repokba kerul, felindexeltetik, es a staging teszteles utan felhasznalok millioi fogjak hasznalni. Ilyen kornyezetben nem engedheto meg egy olyan app, ami meg a sajat telepiteset sem kepes a szabalyokat betartva veghezvinni.

Persze lehet, hogy en ezt azert ertem meg sokkal jobban, mert a senki altal nem hasznalt Gentoo-ban ennel sokkal-sokkal kemenyebb packaging szabalyok voltak, sokszor orakat kellett pocsolni azert, hogy egyaltalan valamilyen vegeredmenyt kapjak. De megerte, mert ezaltal egy minosegi csomagot sikerult eloallitani, amit akar be is kuldhettem volna a Gentoo-nak, ha nem lettem volna tisztaban azzal, hogy a maintaineleset nem tudnam vallalni.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal

És ennek ellenére "nagy" gyártók néha annyira szar rpm-eket adnak...kedvencem az IBM DSA, ennek az rpm-je feltesz egy .tar.gz-t, amiből aztán a post-scriptje felinstallálja a DSA-t, majd törli a .tar.gz-t...ennyire igénytelen szar munkát hogy bírtak kiadni a kezükből, nem is értem. Valami indiai okos lehetett a csomagoló, gondolom.
Ugyanilyen, "tegyük fel a .tar.gz installert" rpm-eket látni még a HP-tól is (a nagy Linux supporter, aha).

Próbáljuk egy másik szemszögből nézni: nekem az, hogy 'buildroot' egyáltalán nem mond semmit, nincs rá szükségem, nem érdekel.

Egyetlen dologra használom az rpm-et: hogy a 'make all; make install' után a 'make rpm' a már telepített program fájljait (a spec-ben a %files section alapján) csomagolja bele egy *.rpm fájlba.

Tehát nem kell ő átvegye a fordítás irányítását, nem kell megszervezze az én munkámat, egyszerűen csak azt csinálja, amit egy tar+gz vagy egy zip is meg tudna csinálni.

Azt természetesen elfogadom, hogy ez is olyan, mint minden más a számítástechnikában, vagyis hogy minél több időt és energiát fordítok arra, hogy megismerjem, annál jobban megszeretem és annál nagyszerűbb dolgokat tudnék vele elérni -- de amilyen lusta egy alak vagyok, pont az rpm-mel nem akarok nagyszerű dolgokat elérni, egyetlen egyszerű dolgot kérek tőle, és nem örülök annak, hogy amit eddig egyszerűen tudott, azt most bonyolultabban tudja.

(Ha szabad egy profán példát hoznom: a 'tail' egyik verziója büszkén közli, hogy már nincs -szám opció, csak -nszám... mert hogy szebb, meg posix, meg különben is, a változás jó dolog... Reméljük a fejlesztő édesanyja nem csuklik ilyenkor.)

De az rpm sose így működött...spec file mindig kellett hozzá. Abba meg miből áll beleírni a make, make installt (ha valóban jó a forrás, és ennyiből megúszod)?
Meg a te módszereddel hogy lehet SRPM-et előállítani? Amire utána elég ráengedni egy rpmbuild ---rebuild-et. Szóval itt sántít a hasonlat a tail-hez, mert az eleve működött -n nélkül, de a te módszered az rpm csinálásra mindig is egy ugly hack volt.

a files check kikapcsolása meg ennyiből áll:

%define _unpackaged_files_terminate_build 0

> spec file mindig kellett hozzá
persze, abból tudja, hogy mit tegyen az archívumba...

> Abba meg miből áll beleírni a make, make installt (ha valóban jó a forrás, és ennyiből megúszod)?
Mert én nem az rpm alá akarom rendelni a saját folyamatomat, hanem az rpm-et akarom a saját folyamatomba beilleszteni (mégpedig a végére, a már telepített fájlok becsomagolására).

> Meg a te módszereddel hogy lehet SRPM-et előállítani?
Még nem gondolkoztam ezen... mihelyt szükségem lesz rá, teszek érte valamit... de az is lehet, hogy .deb csomagot kell előbb csinálnom, vagy AIX-os .lpp-t vagy éppen egyiket sem -- mondom, nekem az rpm csak egy eszköznek kell, nem hobbynak/kutatási projektnek/életfilozófiának.

> a files check kikapcsolása meg ennyiből áll:
%define _unpackaged_files_terminate_build 0

Köszi, biztos ez is jó, én a %define __check_files %{nil} -t használtam erre.

> Abba meg miből áll beleírni a make, make installt (ha valóban jó a forrás, és ennyiből megúszod)?
Mert én nem az rpm alá akarom rendelni a saját folyamatomat, hanem az rpm-et akarom a saját folyamatomba beilleszteni (mégpedig a végére, a már telepített fájlok becsomagolására).

Csak ezt nem erre találták ki...worddel is írhatsz C kódot, csak nem az igazi.
Bár belátom...nagyon kreatív felhasználása és egyben megerőszakolása az eredeti rpm koncepiójának :)

Elmondhatod, hogy hogyan lenne a "hivatalos", csak félek, hogy az alábbiak valamelyike lesz benne:
1. a ./configure-nál a --prefix legyen /usr/local helyett /somepath/buildroot
2. az install után a telepített fájlokat másoljuk a /somepath/buildroot-ba
3. fakeroot-tal vagy chroot-tal varázsoljunk, hogy a /somepath/buildroot látszódjon gyökérnek

1. /usr/local-ba rpm-ből nem installálunk (illetve normális csomag nem telepít /usr/local-ba).
2. Normálisan megírt(generált) makefileoknál általában elég a 'make install DESTDIR=%RPM_BUILD_ROOT', a ./configure-hoz, buildhez nem kell nyúlni.

> illetve normális csomag nem telepít /usr/local-ba

Na máris itt a hibapont: én a /usr/local-ba akarok telepíteni, mert az adott helyzetben azt tartom jónak.
Pont ezt mondom: remek dolog, hogy az rpm-hez tartozik egy világnézet (majdhogynem vallás), de nekem arra nincs szükségem, én csak egy eszközt akarok használni.

> Normálisan megírt(generált) makefileoknál általában elég a 'make install DESTDIR=%RPM_BUILD_ROOT'

Ha meg nem, akkor megpecseljük a source-t, igaz? Én is tudom, hogy pl a debian minden source-hez készít egy-egy patch-et, részint hibajavításibul, részin hogy debian-barát legyen... Mondjuk látni vélek nem egészen tiszta pontokat, pl amikor egy libtool egy --mode=install-nál tart, akkor nem biztos, hogy szereti ha a shared libet nem oda kell telepíteni, ami az ő LIBDIR-je... tesztelni kellene...

Hat, vegul is lehet oda is tenni, tulajdonkepp a prefix nincs kobe vesve. De azert en ovatos lennek e tekintetben.

Egyebkent meg a libtool ne szeressen semmit, hanem csinalja, amit mondanak neki. Ha en nem oda akarok telepiteni, akkor azt is vegye szo nelkul tudomasul, kulonben bunko tirpaknak fogom tartani.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal

A következő szcenáriót kellene kipróbálni: A projektben van liba.so, libb.so és c.exe. c.exe használja libb.so-t, libb.so használja liba.so-t. A LIBDIR (vagyis a --rpath opció linkeléskor) értéke /usr/local/lib. A 'make all' során mindezek létre is jönnek, ideiglenes a src/.libs könyvtárban, úgy hogy
.libs/c.exe függ .libs/libb.so-tól, .libs/libb.so pedig .libs/liba.so-tól, de ott vannak mellettük jó kis textfájlok, amik elmagyarázzák, hogy az install során hogyan kell megcsinálni a relinket, hogy c.exe függjön /usr/local/libb.so-tól, /usr/local/libb.so függjön /usr/local/liba.so-tól; persze az installt is a-b-c sorrendben kell megcsinálni.
Namost ha a 'make install't eltéríted, akkor a liba.so mondjuk simán települ az eltérített helyre (nem kell relink), a libb.so relinkje viszont a /usr/local/lib/liba.so hiányán megáll. Azután pedig c.exe nem tud relinkelődni /usr/local/lib/libb.so hiánya miatt.

Szerk: olvasmány magamnak: http://www.sourceware.org/autobook/autobook/autobook_80.html

Én még nem találkoztam olyan hibával, hogy az rpath értéke rossz lesz, ha make install DESTDIR -rel installálsz (és sok ezer rpm sem), úgyhogy nem hinném, hogy itt problémába ütköznél. Bár konkrétan meg nem mondom, hogy a libtool figyeli-e a DESTDIR-t, vagy valami más módszerrel oldja meg ezt a problémát.

Miert kellene megallnia? Relinknel elvben meg tudod azt csinalni, hogy beirod az rpath-ot, de mashonnan linkelsz. Egyebkent meg tessek megnezni, hogy a GNU libtool hogy oldja meg ezt a helyzetet - mert hogy megoldja, az egeszen biztos.

Bar, szerintem a GNU libtool a legegyszerubb megoldast hasznalja: nem kodol be semmilyen rpath-et, hanem a ld.so.conf / LD_LIBRARY_PATH -ra hagyatkozik. Normalisan felepitett rendszernel ettol nem lesz baja senkinek.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal

Egyik sem. Egyaltalan hogy jut ilyen ostobasag az eszedbe?

Egy normals projekt forditasa rpm-ben ugy nez ki, hogy:

%build
./configure --prefix=%{_prefix} --sysconfdir=%{_sysconfdir} ...
make

%install
make DESTDIR=%{_buildroot} install

%files
%{_bindir}/foo
%{_libdir}/libfoo.so*

Note: most fejbol nem tudom, hogy a buildroot az %{buildroot} vagy %{_buildroot}, ezert ne vesd ram a kovet.

Es se a _prefix se a _bindir ertekeben nem szerepel a buildroot utvonala. Azt egyedul a make install -nak adjuk at.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal

Ja, a "tail -n" -be a napokban futottam bele, én is meleg szeretettel gondoltam a felmenőkre.
(Ha magyar lenne a fejlesztője, aszondanám összekeverte a változás szabadságát a választás szbadságával.)

No, nyomoztam, a GNU libtool tök jól kezeli a problémát, amiben segít neki az, hogy másképp oldja meg a dependeciákat.

Ő: dump -H c.exe

INDEX  PATH                          BASE                MEMBER
0      /home/projects/lib:/usr/lib:/lib
1                                    libb.so
2                                    liba.so
3                                    libc.a              shr.o
4                                    librtl.a            shr.o

Én: dump -H c.exe

INDEX  PATH                          BASE                MEMBER
0      /usr/lib:/lib
1      /home/projects/lib            liba.so.0
2      /home/projects/lib            libb.so.0
3      /usr/lib                      libc.a              shr.o

Tehát a verziószám (a major rész mármint) nem kerül bele a dependenciába, sem pedig az egyes elemek helye, csak egy keresési út (mindkettőből kieditáltam a gcc tekervényes útvonalát, hogy jobban látszódjon a különbség). Persze linuxon ez okés, hiszen ott a linker egyrészt a DT_SONAME alapján megcsinálja a DT_NEEDED-et, másrészt amúgy sem lehet fájlonként útvonalat tárolni.
Ezzel szemközt az AIX-on... (na most vagyunk ott, ahol az egész mese elkezdődött másfél évvel ezelőtt)

Bennem meg mindig az mocorog, hogy meg lehet ezt AIX-on is csinalni mindenfele magia nelkul, egyszeruen meg kell keresni, hogy mi az LD_LIBRARY_PATH AIX-os megfeleloje. Jobban jarnal, minthogy itt szopatod magad.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal

Persze, LIBPATH-nak hívják. Használata ellenjavalt: ez az 'indulj el, és keress valahol egy libxxxx.so' kifejezetten haxorbarát megoldás, nem csoda, hogy a WinDos is így kezeli a DLL-eket...

Azert ez a "valahol" sokkal determinisztikusabb, ha a megadott LIBPATH -on nincs ott a megfelelo .so fajl, akkor mar ugyis mindegy. Meg mondjuk akkor is, ha mar valaki bejutott addig a rendszerben, hogy a rendszerkonyvtarakba irni tud.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal

Mindenesetre egy dolog kiderült: ezt a feature-t is bele kell tegyem a saját libtool-klónomba.

Emlékeztető magamnak: most pillanatnyilag úgy tűnik nekem, hogy amikor 'convenience library'-t csinálunk, abba a position-independent (pic) modulokat kellene tenni... ellenőrizni kellene, hogy tényleg így csinálom-e. (Most ne azt nézzük, hogy az AIX-en nincs külön pic meg a non-pic, mert minden eleve pic)

Szerk: javítva, persze közben újabb hibákat fogtam, ez pl holnapra marad:

aix-libtool --mode=link gcc -o libconv.la rutin.lo
libtool: creating static lib: ar crus .libs/libconv.so.0.0.0 .libs/rutin.o
symlink .libs/libconv.la -> ../libconv.la created

Szerk2: oké, én vagyok a hülye: egy egyszerű és praktikus hack-kel akartam kikerülni +1 paraméter bevezetését. Ennyi az egyszerű és gyors hack-keről.

De pl ez már megy hibátlanul AIX-en:
ftp://ftp.astron.com/pub/file/file-5.12.tar.gz -- file-5.12

Most épp egy ilyet látok a /var/log/samba/log.nmbd-ben:

[2013/02/07 18:27:03,  0] lib/util_sock.c:667(open_socket_in)
  bind failed on port 137 socket_addr = 10.129.11.63.
  Error = The socket name is not available on this system.
[2013/02/07 18:27:03,  0] nmbd/nmbd_subnetdb.c:127(make_subnet)
  nmbd_subnetdb:make_subnet()
    Failed to open nmb bcast socket on interface 10.129.11.63 for port 137.  Error was The socket name is not available on this system.

Amikor nem fut az nmbd, akkor a 137-es porton nincs semmi, amikor fut, akkor ilyen a netstat:

udp        0      0  192.168.110.255.137    *.*
udp4       0      0  192.168.110.36.137     *.*
udp        0      0  10.129.11.255.137      *.*
udp4       0      0  10.129.11.36.137       *.*
udp4       0      0  *.137                  *.*

ez egészen jó is lehet, bár nem tudom, mi a különbség az udp és az udp4 között, meg hogy mi az első és harmadik sorban az a 'broadcast-osított' IP-cím.

Az első ötletem (igazi kispolgári, reakciós, mondhatni 'NevemTevés' ötlet) a --disable-ipv6 opció a ./configure-ban.

Később: na, ez nem ment. Sőt, egy awk-os gondot is generáltam magamnak: hogy mondják azt awk-ul, hogy ha egy minta illeszkedik, akkor több mintát már ne is próbáljon? Valamelyik verzióban (gawk, azt hiszem) erre működik a 'continue', más verziók szerint meg:

error: `continue' is not allowed outside a loop

Következő ötlet:

sed_repl 's|^#define HAVE_IPV6 1|/* no IPV6 */|' include/config.h

awk: nem a next parancsra gondoltál?
(amúgy ha annyira nem szereti a continue-t - ami szerintem amúgy nem erre van, hanem valóban ciklus törzsének átlépésére -, akkor még mindig lehet trükközni:

{ /* minta nélküli akció */
while ( 1 ) {
if ( $0 ~ /itt-a-mintád/ ) {
continue
}
}
}

de ez szerintem nem azt eredményezi amit te szeretnél.

Ha nem continue, akkor next. Szerintem.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal

Azaz, next a helyes megfejtés, köszi mindkettőtöknek!

Szivesen :-) Egyszer elvertem erre az egy szora masfel ora guglizast, szoval azota elegge bevesodott...
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal

Csak a kesobbiek kedveert mondom, hogy szerintem pl. awk manualbol a mawk-fele kifejezetten korrekt darab. Kelloen tomor, de altalaban abban mindent megtalalok (ha nem, akkor jon az O'Reilly-fele Sed and AWK 2nd Edition papiralapon). Szerintem hasznalhatosagban veri mind a One-True-AWK manualjat (nawk), mind a GNU-AWK-et (gawk).

Kosz, meg fogom nezni.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal

Legalább az kiderült, hogy az IPv6-hoz semmi köze. Inkább olyasminek látszik lenni, hogy egy az nmbd megnyit egy UDP-s socketet, amit bind-elni akar egy olyan IP-re (port=137), ami nem a lokális gép IP-je... vajon milyen megfontolásból?

Note to self: kedves én! az install -D opcióját is meg kellene csinálni!

Ja, és a rinetd is meghalta magát...

Mire alaposabban nekiálltam volna a debuggolásnak, azt látom hogy mégis elindult, és a második (vagyis felesleges) indulásnál volt a core-dump... azért az sem olyan jó dolog...

Szerk: javítva. A hiba csak akkor jön ki, ha egy vagy több portra nem tud bind-elni. Ilyenkor a 'SOCKET *seFds' nevű pointere által mutatott memóriaterületen pont annyi inicializálatlan érték van, ahány bind sikertelen volt. Egy ilyen sort tettem bele a malloc mögé:

memset (seFds, '\xff', sizeof(SOCKET) * seTotal);

Nem nullara ('\x0') kellene venni? Arra szoknak felkeszulni a proggerek...
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal

Esetünkben nem, ugyanis ez a vektor SOCKET-eket tárol (Windows-os név a file-handle-ra;), a nulla legális érték, a -1 az INVALID_SOCKET.

Normálisan ilyenkor a rinetd fejlesztőivel kellene kapcsolatba lépni, bár eléggé 'abandoned'-nek látszik (2003-as 0.62-es verzió itt: http://www.boutell.com/rinetd/)

K: Ha a (random rendszerhívás) hibát jelez, de az errno nulla (vagy valami megtévesztő érték), akkor mi van?
V: Valószínűleg multithread főprogram hívott meg egy alprogramot, ami _THREAD_SAFE opció nélkül volt fordítva, és így nem jutott érvényre a
#define errno *_Errno()
vagyis rosszt errno-t olvastál ki.

K: Ja, hát ezt magamtól is rögtön kitalálhattam volna.

Note to self: Egyben váltani kellene strerror-ról strerror_r irányba is. Ez mondjuk nem annyira sürgős, de legalább az új/módosított progikban kellene haladni ebbe az irányba.

Szerk: külön öröm, hogy két ilyen nevű függvény van, egymással oldalról kompatibilisek:

int strerror_r(int errnum, char *buf, size_t buflen); /* XSI-compliant */
char *strerror_r(int errnum, char *buf, size_t buflen); /* GNU-specific */

Ezek alapján talán így mehetne:

int ern= errno;
char errmsg [256];

*errmsg= '\0';
strerror_r (ern, errmsg, sizeof (errmsg));
fprintf (stderr, "Baj van ... errno=%d: %s", ..., ern, errmsg);

a /usr/local/etc/mc.ext-be talán érdemes egy ilyet is tenni:

# jar,war,ear
regex/\.(jar|war|ear)$
        Open=%cd %p#uzip
        View=%view{ascii} unzip -v %f

ugyanis, hogy a *.jar-ból mit ismer fel a 'file', az nem egészen triviális (a file-tól és a file(1)-től függően lehet):

Zip archive data, at least v2.0 to extract
Java Jar file data (zip)
PKZIP (.zip) compressed archive

Ugyanez ubuntun:

# jar,war,ear
regex/\.(jar|war|ear)$
    Open=%cd %p/uzip://
    View=%view{ascii} /usr/lib/mc/ext.d/archive.sh view zip

Szerk: erdekes, valamiert inkonzisztens extfs archivum hibakat dobal, ketszer kell ralepni a fajlra, hogy egyszer megnyissa. De sima zippel is ezt csinalja, szoval nem a fenti kiegeszites bugja.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.