Narz«dzia do programowania w j«zyku C Cz«æ I Opracowa : dr iný. Zbigniew Jaworski 1. Kompilator j«zyka C J«zyk C jest j«zykiem og lnego stosowania. Jest on jednak æciæle zwiˆzany z systemem Unix, dlaêpotrzeb kt rego zosta opracowany. System operacyjny, kompilator C i niemal wszystkie programy us ugowe systemu Unix zosta y napisane w C (lub C++). W starszych wersjach system w (np. w systemie SunOS 4.x) kompilator j«zyka C by dostarczany przez producenta i standardowo nosi nazw«cc. Powodem tego by a konstrukcja systemu, kt ra w przypadku zmiany konfiguracji jˆdra wymaga a jego rekomplilacji. Obecnie wi«kszoæ system w nie wymaga takich operacji i kompilator C nie jest elementem systemu. Opr cz kompilator w Òwbudowanych do systemuó istniejˆ r wnieý inne ich wersje, zar wno komercyjne jak i dost«pne jako freeware (np.: kompilator gcc stworzony iêrozpowszechniany przez Free Software Foundation). W dalszej cz«æci tej instrukcji zajmowa si«b«dziemy kompilatorem gcc. 1.1. Od tekstu r d owego programu do kodu wykonywalnego Proces tworzenia binarnego kodu wykonywalnego, zwany zwyczajowo kompilacjˆ, sk ada si«zêkilku odr«bnych etap w.êsˆ to: Êprekompilacja (ang. preprocessing) - polega na stworzeniu ostatecznego tekstu r d owego programu poprzez w ˆczenie plik w wskazanych dyrektywˆ preprocesora #include, wykonanie podstawieä makrodefinicji #define i opcjonalne usuni«cie komentarzy. Êkompilacja do kodu asemblera (ang. compilation) - polega na tym, ýe kompilator przeglˆdajˆc kod r d owy programu otrzymany po etapie prekompilacji wyszukuje tokeny (s owa kluczowe, operatory) i przekszta ca je na wewn«trznˆ reprezentacj«. Reprezentacja wewn«trzna jest nast«pnie przekszta cana na kod asemblera. Jeæli nie jest to moýliwe to kompilator sygnalizuje b «dy. Êoptymalizacja kodu asemblera (ang. optymalization) - polega na zmianie kodu asemblera w celu zwi«kszenia jego efektywnoæci. Kod poddawany jest modyfikacjom takim jak zmiana sposobu obliczania adres w wzgl«dnych, eliminacja nieuýywanych fragment w kodu, optymalizacja przydzia u rejestr w oraz zmiana lokalnych odwo aä w taki spos b, by uýywany by wska nik stosu. Ten etap kompilacji jest opcjonalny. Êasemblacja (ang. assembly) - polega na przetworzeniu kodu asemblera w relokowalny kod w j«zyku maszynowym. Instrukcje w tym kodzie nie odnoszˆ si«jeszcze do konkretnych adres w w pami«ci. Kod umieszczany jest w pliku obiektowym (ang. object file). Etap ten wykonywany jest przez program as (systemowy) lub gas (z pakietu GNU). - 1 -
Êkonsolidacja (ang. link editing) - konsolidator, lub ýargonowo linker (ang. link editor), dokonuje szeregu operacji w celu stworzenia pliku binarnego z kodem wykonywalnym : 1)Êprzeszukanie standardowego zestaw bibliotek oraz bibliotek wskazanych w linii wywo ania w celu w ˆczenia do programu kodu funkcji niezdefiniowanych w modu ach stworzonych przez uýytkownika (np.: printf(), sin()). W przypadku braku kodu danej funkcji we wszystkich przeszukanych bibliotekach konsolidator sygnalizuje b «dy i koäczy prac«. 2)Êprzypisanie kodu maszynowego do ustalonych adres w, np. zmienne globalne otrzymujˆ konkretne adresy tak, aby moýna si«odwo ywa do ich wartoæci. 3)Êutworzenie wykonywalnego pliku binarnego w formacie ELF (ang. Executable and Linking Format) Konsolidacja wykonywana jest przez program ld. 1.2. Parametry wywo ania kompilatora Polecenie wywo ania kompilatora ma nast«pujˆcˆ posta : gccêê[opcje]êêplik1 É plikn Zawartoæ argumentu pliki okreælana jest na podstawie dwuznakowego rozszerzenia (koäc wki nazwy), zgodnie z nast«pujˆcˆ konwencjˆ : Rozszerzenie Zawartoæ Przyk ad.c tekst r d owy w j«zyku C main.c.s kod w j«zyku asemblera main.s.o kod relokowalny (wynik asemblacji) main.o.a biblioteka libc.a Do najcz«æciej uýywanych opcji naleýˆ: -oênazwaêpowoduje zmian«nazwy programu wynikowego na podanˆ przez uýytkownika; np.: gcc -o prog main.c, powoduje nadanie nazwy prog zamiast standardowej a.out, -E powoduje zatrzymanie po etapie prekompilacji, wyniki sˆ wypisywane na ekran, -S powoduje zatrzymanie po etapie generowania kodu asemblera, wyniki sˆ umieszczane w pliku z rozszerzeniem.s, -c powoduje zatrzymanie po etapie asemblacji, wyniki sˆ umieszczane w pliku zêrozszerzeniem.o, -Dmakro uýycie opcji jest r wnoznaczne z umieszczeniem liniiê#define makro naêpoczˆtku pliku zawierajˆcego tekst r d owy, -Umakro uýycie opcji jest r wnoznaczne z umieszczeniem liniiê#undefêmakro naêpoczˆtku pliku zawierajˆcego tekst r d owy, -O powoduje wykonanie optymalizacji, - 2 -
-Opoziom powoduje wykonanie bardziej z oýonej optymalizacji. Parametr poziom moýe przyjmowa wartoæci 1, 2 i 3. Uýycie tej opcji powoduje wzrost czasu kompilacji i zapotrzebowania na pami«w por wnaniu do opcji -O. -g powoduje w ˆczanie do pliku wynikowego informacji (numery linii, typ i rozmiar identyfikator w, tablica symboli) umoýliwiajˆcych æledzenie wykonywania programu wynikowego (ang. debugging); UWAGA! Opcje -O i -g zwykle nie mogˆ by stosowane jednoczeænie. Jednak kompilator gcc dopuszcza takˆ moýliwoæ pozwalajˆc na ograniczone æledzenie zoptymalizowanego kodu programu. -Idir powoduje w ˆczenie katalogu dir do zestawu katalog w, w kt rych naleýy poszukiwa plik w nag wkowych, -Ldir powoduje w ˆczenie katalogu dir do æcieýki poszukiwaä bibliotek; w linii wywo ania opcja ta musi poprzedza opcj«-l (wyjaænienie poniýej), -lident polecenie dla konsolidatora (programu ld), kt re powoduje, ýe bibliotekaêlibident.aêjest przeszukiwana w celu znalezienia kodu funkcji zewn«trznych. -pipe powoduje, ýe kompilator gcc zamiast tworzy pliki poærednie do komunikacji pomi«dzy programami wykonujˆcymi kolejne etapy kompilacji wykorzystuje do tego celu ˆcza (ang. pipe). Opcja nie dzia a na systemach gdzie asembler nie moýe czyta danych ze strumienia wejæciowego. Dzia a prawid owo przy korzystaniu z asemblera gas. -ansi tekst r d owy musi by w 100% by zgodny z normˆ ANSI j«zyka C. -traditional toleruje starsze konstrukcje j«zyka C, z tzw. wersji j«zyka K&R opisanˆ w ksiˆýce autor w j«zyka B.W.Kernighan i D.M.Ritchie Najprostszym sposobem uýycia kompilatora jest wydanie polecenia : gcc main.c Kompilator potraktuje wtedy zawartoæ pliku main.c jako tekst r d owy w C (zgodnie z obowiˆzujˆcˆ konwencjˆ) i wykona wszystkie etapy kompilacji, aý do uzyskania kodu wykonywalnego, kt ry zostanie umieszczony w pliku o standardowej nazwie a.out. Na etapie konsolidacji pod uwag«b«dzie wzi«ta tylko biblioteka libc.a, zawierajˆca kod standardowych funkcji j«zyka C takich jak printf(), fopen(), i.t.d. Wszystkie pliki poærednie zostanˆ usuni«te. W bardziej skomplikowanym przypadku, gdy tekst r d owy znajduje si«nie w jednym lecz w kilku plikach, np.: main.c, data.c, input.c i output.c i dodatkowo programista uýy funkcji matematycznych, polecenie kompilacji powinno wyglˆda nast«pujˆco : gccêinput.cêoutput.cêdata.cêmain.cê-lm Kompilator dla kaýdego z plik w wykona wszystkie etapy kompilacji, aý do uzyskania plik w obiektowych main.o, data.o, input.o i output.o, a nast«pnie dokona ich konsolidacji biorˆc tym razem pod uwag«opr cz biblioteki libc.a takýe bibliotek«libm.a zawierajˆcˆ kod funkcji takich jak sin(), cos(), i.t.d. Program wykonywalny znajdzie si«w pliku a.out. Podobnie jak wêpoprzednim przyk adzie wszystkie pliki poærednie opr cz plik w obiektowych zostanˆ usuni«te. - 3 -
Argumentami wywo ania kompilatora gcc mogˆ by r ýne typy plik w i moýliwa jest sytuacja, wêkt rej kaýdy z argument w jest innego typu (uzyskany zosta przez zatrzymanie kompilacji po innym etapie), np.: gccêmain.oêdata.sêinput.iêoutput.cê-lm Pliki, kt re w czasie prekompilacji majˆ by w ˆczone do tekstu programu (przy pomocy dyrektywy #include) muszˆ znajdowa si«w bieýˆcym katalogu (dotyczy to plik w nag wkowych stworzonych przez uýytkownika) lub w standardowym katalogu instalacyjnym kompilatora (standardowe pliki nag wkowe kompilatora. np. stdio.h). Jeæli programista chce umieæci w asne pliki nag wkowe w innym katalogu niý pliki z tekstem r d owym, to by uczyni je dost«pnymi dla kompilatora, musi w linii wywo ania uýy opcji -Idir, gdzie dir jest nazwˆ tego katalogu (wzgl«dnˆ lub bezwgl«dnˆ). Przyk adowo, jeæli pliki nag wkowe zosta y umieszczone w katalogu../headers to wywo anie kompilatora ma posta : gccê-i../headersêêinput.cêoutput.cêdata.cêmain.c Podobnie jest w przypadku bibliotek. Konsolidator oczekuje, ýe biblioteki znajdujˆ si«w standardowym katalogu instalacyjnym. Jeæli uýytkownik korzysta z innych bibliotek (np.êstworzonych samodzielnie) to musi poinformowa konsolidator przy pomocy opcji -Ldir, gdzie one si«znajdujˆ. Informacja ta musi poprzedzi opcj«-l. Przyk adowo, jeæli dodatkowa biblioteka nosi nazw«libusux.a i znajduje si«w katalogu../libs, to wywo anie kompilatora powinno mie posta : gccêmain.cêdata.cêinput.cêoutput.cê-l../libê-lusux Naleýy zwr ci uwag«na regu «nadawania bibliotekom nazw. Nakazuje ona, by nazwa bibioteki mia a posta libident.a, gdzie pole ident moýe mie d ugoæ od 1 do 7 znak w. W linii wywo ania kompilatora, po opcji -l, podawana jest tylko cz«æ ident zamiast ca ej nazwy biblioteki, np.: -lm dla biblioteki libm.a. 2. Biblioteki Bibliotekˆ (ang. library archive) jest archiwum plik w obiektowych zawierajˆce nag wek, w kt rym znajdujˆ si«informacje m.in. o nazwach i po oýeniu wewnˆtrz archiwum poszczeg lnych obiekt w oraz tablic«symboli bibliteki. Taka organizacja biblioteki zwi«ksza efektywnoæ jej przeszukiwania podczas konsolidacji. Wraz z systemem dostarczane sˆ jego standardowe biblioteki takie jak libc.a czy libm.a. Opr cz nich istniejˆ biblioteki zawierajˆce zestaw funkcji przeznaczonych do specjalnych zastosowaä jak np. libcurses.a umoýliwiajˆca programiæcie programowˆ obs ug«terminali. Niezaleýnie od bibliotek dost«pnych w danym systemie kaýdy uýytkownik moýe tworzy w asne biblioteki, kt re mogˆ by nast«pnie uýywane w taki sam spos b jak systemowe. Do tego celu uýywany jest program ar. Zasady pos ugiwania si«tym programem sˆ bardzo podobne do sposobu korzystania z programu tar. Wywo anie ar ma nast«pujˆcˆ sk adni«: arêê[opcje]êêarchiwumêêplik1... plikn Argument archiwum jest nazwˆ biblioteki, a plik1 É plikn sˆ plikami obiektowymi, zêkt rych naleýy stworzy bibliotek«, lub kt re naleýy wyekstrahowa lub usunˆ z biblioteki. Najcz«æciej uýywane opcje to: - 4 -
-d usuwanie z archiwum wskazanego pliku, -q dodaje plik na koniec archiwum (UWAGA! nie sprawdza czy dany plik jest juý w archiwum), -r zamiana (lub dodanie) wskazanego pliku w archiwum; jeæli pliku nie ma w archiwum to nast«puje jego dodanie, a w przypadku gdy nie istnieje archiwum - jego utworzenie, -u uýywana razem z -r powoduje, ýe zamiana nast«puje tylko wtedy, gdy data modyfikacji pliku w archiwum jest wczeæniejsza niý data modyfikacji pliku podanego jako argumentu, -s ponowne utworzenie tablicy symboli biblioteki; umoýliwia odtworzenie tablicy symboli po jej usuni«ciu programem strip, -t wypisanie zawartoæci archiwum; zwykle uýywana razem z opcjˆ -v, -x ekstrakcja wskazanego lub wszystkich plik w z archiwum (nie niszczy archiwum), -v wyæwietlanie bardziej szczeg owych informacji podczas dzia ania. Przyk adowo, jeæli programista chce utworzy bibliotek«libusux.a z nast«pujˆcych plik w: funkcja1.o,êfunkcja2.oêiêfunkcja3.o,êto polecenie moýe mie posta : arêê-rvêêlibusux.aêêfunkcja1.oêfunkcja1.oêfunkcja1.o lub arêê-ruvêêlibusux.aêêfunkcja1.oêfunkcja1.oêfunkcja1.o Jeæli biblioteka libusux.a nie istnia a wczeæniej, to w obu przypadkach zostanie utworzona. Opcja Ðr stanowi zabezpieczenie przed sytuacjˆ, w kt rej do istniejˆcej juý biblioteki dopisywane by y by za kaýdym razem nowe wersje plik w funkcja1.o, funkcja2.o i funkcja3.o. Sprawdzenie zawartoæci biblioteki moýliwe poprzez wydanie nast«pujˆce polenia: arêê-tvêêlibusux.a 3. Pomocnicze programy narz«dziowe W procesie tworzenia programu uýytkownik moýe wykorzystywa nast«pujˆce programy pomocnicze, dost«pne standardowo w systemie Unix: gdb nm strip program uruchomieniowy (ang. debugger) wypisuje informacje zawarte w tablicy symboli pliku wykonywalnego, pliku obiektowego lub biblioteki, usuwa z pliku wykonywalnego, pliku obiektowego lub biblioteki tablic«symboli oraz dodatkowe informacje do ˆczone do pliku w wyniki kompilacji z uýyciem opcji -g, - 5 -
4. Program uruchomieniowy W pakiecie GNU dost«pny jest program uruchomieniowy gdb. Jego wywo anie jest nast«pujˆce: gdb [opcje]êêprogram [core] lub gdb [opcje]êêprogram [process_id] Program umoýliwia krokowe wykonywanie programu, ustawianie pu apek, æledzenie wartoæci zmiennych i wyraýeä i inne typowe dla program w uruchomieniowych operacje. Oczywiæcie uruchamiany program (a dok adnie kaýdy plik zawierajˆcy tekst rod owy) musi by skompliwany z uýyciem opcji -g. Po wywo aniu program gdb komunikuje si«z uýytkiem za pomocˆ prostej pow oki takich jak bash czy zsh. Jednˆ z komend jest help, kt re pozwala uzyska informacje o dost«pnych poleceniach i ich sk adni w aktualnej wersji programu. - 6 -