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:

  1. Preprocessing (dirba programa cpp)
  2. Compiling (dirba programa gcc)
  3. Assembling (dirba programa as)
  4. Linking (dirba programa ld)

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ą:

Preprocessing

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

Compiling

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

Assembling

Yra 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'ą.

Linking

Yra 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

Valid HTML 4.01 Strict