Miként készülnek a felhőkarcolók? Hogyan is hívják életre a nagy dolgokat manapság az emberek? Hatalmas erőforráskoncentrációval. Emberi, pénzügyi, szellemi és nem utolsó sorban fizikai erőforrások.
Ugyan egy hatalmas projekt megvalósítása sok idő, de a legnagyobb része mégis láthatatlan, akár mennyire is ambiciózus vállalkozásról van szó. Hiszen akár éveken át tevezőasztalon mozog csak a teremtmény.
Még érdekesebb a dolog, ha szoftverről van szó. Ott talán csak a leglegvégén lehet egy lapos kis korongot odanyomni bárki orra alá, hogy "na, kész!".
Kicsit régebben a Mozillás levelezőlistákról siránkoztam, hogy mennyire feszülta hangulat, de betudom valami átmeneti mentális viharnak, mert mostanság épp az ellenkezője igaz rájuk. És ez jó, mert vonzza a fejlesztőket, a tenniakarókat. Maga a Mozilla egy hatalmas emberi célkitűzés, vállalkozás, összefogás. Mindenki beleönti egy nagy-nagy betonkeverőbe a tudása legjavát.
Viszont abból, hogy összehordunk egy kupacra rengeteg téglát, cementet, vasbetont és egyéb dolgokat nem nagyon kapunk egy házat, egy épületet. Még mesterséges hegynek is nehézkesen illik be, mert nem lesz túl ellenálló az elemekkel szemben.
Hasonlóan a szoftvereknél, és gyakorlatilag az élet minden teremtésénél, egy folyamatról van szó, amihez oda kell vinni és használni kell bizonyos különleges eszközöket. Lásd daru, lásd fordítóprogram. Lásd még markoló, betonpumpa, heggesztőállvány, úthenger illetve linker, asszembler, szkriptek, verziókövetés.
Miért érdekes ez? Igazából nem az. Viszont én úgy veszem észre, hogy legtöbbször a nagy szoftverprojekteknél manapság már nem a konkrét programozói virtuozitáson áll vagy bukik a mutatvány, hanem a szervezettségen, a hatékonyságon, ezeken a kis eszközökön. Nézzünk megy egy kikötőt, ha lusták, lassúak és esetlenek azok a kis vontatóhajók, akkor a nagy tankerek/teherhajók csak kínkeservvel érnek célt és indulhatnak útjukra.
Nem tudom, hogy hányan tudják, de a Windows NT 4 fejlesztésének ütemét elsősorban az lassította, hogy miután valaki írt egy rakás kódot, jól átnézte. Majd átnézette mással. Mentették a szerveren a változásokat, majd vártak, a következő körre, amiko is egy izmosabb erőmű, a "build gép" fogta a több tízezer forrásfájlt és összekombinálta azzá a sok-sok fájllá, amiből egy operációs rendszer áll.
És minnél nagyobb gödröt ásunk, annál több kamion kell, hogy elvigyük a földet. És minnél mélyebben vagyunk, annál több erőfeszítés még mélyebbre menni. Ööö.. nem szándékosan választottam a gödör analógiát, lehetne éppen a Burj Dubai is.
És ez mind a mai napig hellyel-közzel így is van. Ugyan egy nagyobb rendszer esetében lehetőség van a modulokra, komponensekre bontásra, de bizonyos mélységű változtatásokhoz ott is mindent fel kell forgatni.
Szóval azon kívül, hogy a forrásfájlokból össze kell varázsolni, szerkeszteni a dinamikusan betölthető programkönyvtárakat (.dll, .so, a két legismertebb kiterjesztés), magát a futtatható gépi kódot tartalmazó bináris fájlt, a nyelvi fájlokat, a mindenféle adatfájlt, és hatezer egyéb dolgot, még valahogy ezt rendszerezni is kell. Persze, elvileg semmi nem akadályozza, hogy egy könyvtárban legyen ~10.000 állományunk, és aztán csak kiadjuk a fordítónak, hogy
g++ main.cpp. És ha a main.cpp-nkben szépen hivatkozunk a többi fájlra, akkor minden oké. Csak ez mégsem egészen így van, ha így lenne, akkor a végén kapnánk (ha egyátalán kapnánk!) egy ~20 megás exe fájlt, és jónapot.
Hogyan is működnek ezek a rendszerek? Igazából meglepően egyszerű elemek vannak összeláncolva gecivékony damillal. Magyarul, vacak szkriptfájlok, különböző "make" programok, "konfiguráló" szkriptek és egyéb kacatok alkotják ezt a nagyon fontos vázat, amire majd kikristályosodik a valami, amit építünk.
Például,
Mozilla,
KDE4, Qt4.. és gyakorlatilag minden szoftver, ami kicsit is túlmutat a Hello Wörd kategórián. Ez önmagában nem baj, csak nehéz és bonyolult. Nehéz belejönni, nehéz kézzel vacakolni ezekkel, nehéz összeegyeztetni a különféle
make programok formátumait, nehéz megbékeltetni a nyócféle
configure szkirptet.
Ennek ellenére, a legtöbbször fájdalommentes a dolog. Letöltünk egy vaskos zip-et (például a Qt esetében), kicsomagoljuk, bepötyögjük a terminálba, hogy
./configure, ez szépen megvizsgálja a rendszerünket, mi van feltelepítve, milyen hardverünk van, milyen architektúrája van a processzorunknak, milyen videókártyánk van (ha épp fontos), miféle operációs rendszerünk van, milyen fejlesztőeszközök vannak a gépen, van-e elég hely, ilyesmi. Ha valami nincs, meghal és utolsó lehelletével próbálja tudatni a kedves emberrel, hogy mit kell még behordani a kupacba. Windózon példának okáért a legtöbb nyílt forráskódú programot nem triviális fordítani, mert alapvetően egy unix-szerű rendszeren fogantak, és egy olyasmi környezethez illeszkedik a legtöbb eszköz.
És a ./configure legyártja nekünk azt, amire igazán büszkék lehetnek az emberek, hogy kitalálták. És megúszták egy kurvanagy meteor azonnali becsapódása nékül. Ez pedig nem más, mint a
Makefile. Ami tartalmazza a pontos utasításokat, amiket végre kell hajtani az aktuális
make programnak. Ezek többnyire abból állnak, hogy meghívják a fordítót valahogy. Megfelelő paraméterekkel. Átadják, hogy hol vannak a grafikus könyvtárfájlok, hol vannak az alap operációs rendszer fájlok, hol vannak a hálózati modul fájlai, és hogy szeretnénk fordítani, milyen optimalizációt kívánk a kedves vevő, és így tovább..
Majd a make, mint egy ügyeletes rabszolgahajcsár noszogatja a fordítót. Az első körben az ember által nagyságrendekkel nehezebben olvasható assembly kódot fordítja le a program forrásából. Ez a kód már teljes mértékben az adott gépre, processzorra van kitalálva, specializálva, optimalizálva. Ez a fordítás az, ami általában a legtöbb időt emésti fel. Ki kel számolni rengeteg memóriacímet, végrehajtani egy csomó optimalizációs tranfszormációt, ami előtt nyilván analizálni kell a program szerkezetét, ami előtt fel kell építeni valamilyen adatstruktúrát a memóriában, amit majd egyátalán tudunk vizslattatni. Ehhez kezdetben meg kell bizonyosodni a forrás helyességéről, nincs-e benne elgépelés, nincsenek-e benne triviális logikai hibák. Itt jönnek a képbe ilyen varázsigék, mint
parser,
lexer. Szóval ez egy külön tudományág. Ide-s-tova 60 éve foglalkoznak vele nagyon komolyan. Az elvet még Neumann haverunk fektette le. Nem kis zsenialitással, akkoriban. A fordítás után jön az összeszerelés, mármint szó szerint így hívják.
Assembler, összeszerelő. Fogja és lefordítja az assembly kódot gépi kódra. Ez az, ami már nem embereknek szól. Aki tudja olvasni, nagyrészt nem ember :P Itt már olyan dolgok is lényegesek, mint hogy hogyan is tároljuk a számokat. Balról jobbra írva, vagy fordítva? (Little endian, illetve big endian, amúgy már a configure is megnézni, már a compilernek tudnia kell, de psszt!) Majd ezeket a kész gépi kódú csomagokat fogja és szigszallagozza össze a
linker. Ezek nem kifejezetten hihetetleül komplex programok, de azért ezt se lehet csak úgy fejbe' lejátszani :) És a linker az, ami a végén kiköp nekünk egy .exe-t (vagy valamilyen futtatható binárist, amit az adott operációs rendszer főprogramja, el tud kezdeni betölteni a memóriába, majd a processzorba és végül át tudja adni a vezérlést neki.)
Hm. És kb. ennyi :o És kézzel nem igazán szerkesztünk makefile-t, és kézzel nem szerkesztünk configure szkriptet. És létezik auto-configure és létezik auto-make .. és létezik még ezer eszköz, ami az eszközök használatát hivatott megkönnyíteni. Viszont midegyiknek vannak hülye rigolyái, válogatósak és buzik. Általában. Ha nem, akkor sokkal rosszab :D
Make okosítás. Meg
még egy.
zomg44!, kicsit félremente a vonat, és nem úgy van pár dolog, mint ahogy. A
./configure nem hoz létre
Makefile-t, ellenben létrehozhat egy
config.h. Ezáltal az adott rendszerspecifikus jellemzőket át tudjuk adni a programnak. Az
autoconf program egy meglévő
configure.in-ből csinál
configure. Az
automake pedig egy meglévő
Makefile.am-ből. Ha látunk ilyen
Makefile.m4 fájlokat, azt az automake csinálta, nem kell vele törődni.Az M4 (macro feldolgozó, semmi extra :o) egy kis segédprogram, amit az automake használ a perl mellett (mivelhogy az automake-t perlben írják manapság).
A Makefile-t szépen meg kell írni, ahogy adogatjuk hozzá a projektünkhöz az új fájlokat. Pl. a KDevelop ezt kezeli nekünk.
Na, mostmár mehet tovább a kódvonat!