Przydatne opcje kompilatora

From MorphOS Library

Grzegorz Kraszewski


Ten artykuł w innych językach: angielski


Kompilator GCC ma setki opcji. Znaczna część z nich nie jest istotna z punktu widzenia typowego użycia pod MorphOS-em. Część z nich nie jest istotna z punktu widzenia architektury PowerPC. W artykule opisany jest zestaw najważniejszych opcji potrzebnych w kompilowaniu programów dla MorphOS-a. Szczegółowy opis wszystkich parametrów znajduje się w instrukcji obsługi GCC.

Kompilacja i linkowanie

Dla każdego projektu składającego się z więcej niż jednego pliku z kodem, proces budowania gotowego programu jest podzielony na dwa etapy: kompilację i linkowanie. Kompilacja zamienia każdy plik z kodem źródłowym na plik zawierający odpowiadający mu kod wykonywalny procesora (ang. object file). Linkowanie łączy pliki wygenerowane przez kompilator w gotowy plik wykonywalny programu. Dla prostych projektów mieszczących się w jednym pliku źródłowym, te dwa etapy połączone są w jeden proces.

Oba etapy budowania programu mają swoje parametry. Część opcji jest brana pod uwage tylko przy kompilacji, część tylko przy linkowaniu, niektóre są ważne dla obu. Na szczęście nazwy parametrów dla obu etapów nigdy się nie pokrywają, dlatego bezpiecznym rozwiązaniem jest podanie wszystkich żądanych opcji w obu etapach. Nadmiarowe parametry zostaną po prostu zignorowane.


Kolejność parametrów

Generalnie rzecz biorąc, kolejność parametrów podawanych w GCC nie jest istotna. Są jednak od tej ogólnej zasady ważne wyjątki. Najważniejszym z nich jest podawanie linkerowi nazw bibliotek statycznych, z jakimi ma zostać zlinkowany program. Przypuśćmy, że linkujemy z dwiema bibliotekami libfoo.a i libbar.a. Wymaga to podania linkerowi dwóch parametrów: −lfoo −lbar. Jeżeli jednak bibkioteka libbar używa funkcji z libfoo, parametr −lfoo musi być podany po parametrze −lbar. W przeciwnym wypadku linker nie będzie w stanie rozwinąć wszystkich symboli z libbar.


Opcje ostrzeżeń kompilatora

Opcje te kontrolują przed jakimi potencjalnie niebezpiecznymi konstrukcjami programistycznymi kompilator będzie nas ostrzegał. Niektórzy programiści narzekają na kompilator (zwłaszcza na wersję GCC 4), że "czepia się nieistotnych szczegółów". Mimo to warto włączyć większość ostrzeżeń, może to zaoszczędzić wielu godzin spędzonych na wyszukiwaniu błędów w programie...

−Wall, włącza ostrzeżenia dla najczęściej spotykanych potencjalnie niebezpiecznych konstrukcji języka. Są to na przykład przypadki użycia wartości przypisania jako warunku logicznego, czy arytmetyka na wskaźnikach typu void*. Jakkolwiek są to konstrukcje poprawne syntaktycznie, mogą być często efektem pomyłki w pisaniu kodu, a jeśli nawet użyte celowo – są często źródłem trudnych do zdebugowania błędów. Włączenie tej opcji powinno być czymś oczywistym dla każdego rozsądnego programisty.

−Wextra, włącza jeszcze więcej ostrzeżeń (w GCC 2.95.3 ta opcja ma postać −W). Nie ma poważnego powodu, żeby i jej nie włączyć.

Uwaga: GCC4 ma jedną irytującą właściwość. Stałe znakowe z założenia są typu char i nie można tego zmienić. Prawie całe systemowe API MorphOS-a używa do tekstów typu STRPTR, który jest zdefiniowany dyrektywą typedef jako unsigned char*. Używanie stałych znakowych jako argumentów funkcji z API wywołuje mnóstwo ostrzeżeń kompilatora. Najpoprawniejszym (choć żmudnym) sposobem ich uniknięcia jest jawne rzutowanie typu każdej stałej znakowej na STRPTR. Alternatywnym rozwiązaniem jest wyłączenie ostrzeżeń opcją −Wno-pointer-sign. Wadą tego sposobu jest to, że opcja ta wyłącza ostrzeżenia o znaku nie tylko do wskaźników na char ale także wszystkie inne typy całkowitoliczbowe. Trzecim sposobem, dobrym do zastosowania w nowo pisanym kodzie jest zmiana definicji typu STRPTR (i pokrewnych). Można to zrobić umieszczając następujący fragment kodu przed zainkludowaniem pliku nagłówkowego <exec/types.h>:

typedef char* STRPTR;
typedef const char* CONST_STRPTR;
#define STRPTR_TYPEDEF

Używając tego sposobu musimy mieć całkowitą pewność, że nie wykonujemy na tekstach wskazywanych przez STRPTR arytmetyki zakładającej znak (a jeżeli to robimy, wszędzie muszą być jawne rzutowania typu). Dlatego bardzo ryzykowne jest stosowanie tego sposobu do starego kodu.


Opcje linkera

−noixemul, powoduje, zlinkowanie programu z biblioteką statyczną libnix, która dostarcza bibliotekę standardową C/C++ i kod startowy programu. Bez tego parametru używana jest biblioteka współdzielona ixemul.library i odpowiadający jej kod startowy. Więcej.

−s, po zlinkowaniu usuwa z pliku wykonywalnego informacje debugera i tablice symboli. Te informacje nie są potrzebne w programie w wersji do dystrybucji. Usunięcie ich znacząco zmniejsza rozmiar pliku wykonywalnego.


Opcje optymalizatora

−On, gdzie n jest z przedziału od 0 do 3. Parametr kontroluje ogólną "siłę" optymalizacji. −O2 wydaje się być najlepszym wyborem do codziennego użycia. −O3 włącza wiele optymalizacji, które mogą silnie wpłynąć na zwiększenie się rozmiaru pliku wykonywalnego. Dobrzy programiści przede wszystkim optymalizują swoje algorytmy, kompilator nie jest w stanie poprawić błędów projektowych...

−Os, włącza optymalizację pod kątem zmniejszenia rozmiaru kodu kosztem szybkości wykonania. Raczej nieprzydatna dla typowych programów opcja.