C/C++ kalbų transliavimo stadijosŠis mažytis straipsniukas originaliai buvo post'as GameDev.lt forume. Post'ą galima rasti čia. Čia kalbama apie gcc, bet iš smės viskas tinka bet kokiam C/C++ kompiliatoriui. gcc-specific stuffą galima ignoruoti. Papildysiu pedro. Pakvietus gcc, labai daug kas yra padaroma "už akių". Paprastas call'as gcc foo.c turi keturias stadijas:
By default, bandomos vykdyti visos keturios. Jeigu kurių nors nereikia (pvz, bandai kompiliuoti asemblerio kodą: gcc foo.s), jos tiesiog praleidžiamos. Norint, galima reguliuoti kurios iš stadijų bus vykdomos, kurios ne (žr žemiau). Trumpai apie kiekvieną: PreprocessingYra stadija, kurios metu pašalinami visi komentarai, vietoj kiekvienos #include direktyvos atsiduria visas includinamas failas (rekursyviai su kitais #includais), "išresolvinami" visi makrosai (t.y. tekstas pakeičiamas makroso kodu), į vieną sujungiami iš eilės surašyti stringai. Norint pamatyti preprocessintą kodą, reikia paduoti parametrą -E: gcc -E foo.c -o foo.i. Pamatysite kaip šauniai atrodo jūsų kodas, kai maitinamas kompiliatoriui ;-). CompilingYra stadija, kurios metu C/C++ ar kitos aukšto lygio kalbos kodas sutransliuojamas į target architektūros asemblerį. Kad nutraukti GCC darbą ties šita stadija, naudojamas parametras -S: gcc -S foo.c -o foo.s. Pamatysite kaip kompiliatorius suprato jūsų kodą ir ką jis šia tema žada pasakyti procesoriui. Tai paskutinė human-readable forma, kurią galite pamatyti. AssemblingYra stadija, kurios metu asemblerio kodas paverčiamas mašininėmis komandomis. Jos rezultatas -- objektinis kodas, t.y. praktiškai tas pats, kas ir executable faile, tik dar nepabaigta. Kaip minėjo pedro, GCC darbas nutraukiamas ties šia stadija parametro -c pagalba: gcc -c foo.c -o foo.o. Patartina kiekvieną savo .c failą atskirai kompiliuoti į objektinį kodą, o tada juos visus linkuoti į executable'ą. LinkingYra stadija, kuri paima seriją objektinių failų ir bibliotekų (kurios, beje, tėra tik objektinių failų archyvai, pagaminti programos ar pagalba (štai kodėl Unixe įprasta bibliotekas vadinti foo.a: archive)) ir suriša jų tarpusavio call'us. Pvz, jeigu objektiniam faile foo.o yra standartinės funkcijos printf() kvietimas, būtent linkavimo stadijoje bus paieškota kurioje iš bibliotekų ar objektinių failų turima tokia funkcija ir foo.o esantis kodas bus pamodifikuotas, kad teisingai iškviestų funkciją. Linkavimas yra paskutinė stadija, jos rezultatų niekaip ypatingai nereikia "prašyti", jos rezultatas -- executable failas. Tai lyg ir tiek. Know your tools. Know the beast you're dealing with. -rtfb |