Difference between revisions of "Przydatne opcje kompilatora"

From MorphOS Library

(Translation in progress.)
(Translation finished.)
 
(2 intermediate revisions by the same user not shown)
Line 8: Line 8:
 
==Kompilacja i linkowanie==
 
==Kompilacja i linkowanie==
  
For every project consisting of more than one source file, the process of building the executable program is divided into two stages: compiling and linking. Compilation turns every source code file into an object file. Linking merges all object files (and static libraries) into the final executable. For simple single file projects, these two stages merge into one.
+
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.
  
Both the stages have different options. Some options are relevant only for compiling, some only for linking, and some are important for both. Fortunately option names never overlap. Then the safe solution is to pass '''all''' the desired options for both stages. Irrelevant ones will be simply ignored.
+
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.
  
  
==Options order==
+
==Kolejność parametrów==
  
The order of passing options to GCC is not important in general. There are some critical exceptions however. The most common one is order of passing static libraries to the linker. Let's assume linking with two static libraries ''libfoo.a'' and ''libbar.a''. This requires passing ''−lfoo −lbar'' parameters to the linker. However, in the case where ''libbar'' uses functions from ''libfoo'', the ''−lfoo'' option must be passed '''after''' the ''−lbar'' option. The linker will be left with unresolved symbols in ''libbar'' otherwise.
+
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''.
  
  
==Warning options==
+
==Opcje ostrzeżeń kompilatora==
  
These options control warnings issued by the compiler on some potentially dangerous language constructs. While some programmers complain about the compiler being too picky, it is recommended to turn most of these options on. It can save hours of time wasted on debugging...
+
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''', turns on warnings for typical potentially dangerous language constructs. Example ones are using a value of assignment as a logical condition, or using arithmetic on ''void*'' pointers. While syntactically legal, such constructs may be a result of mistyping, and even when used intentionally, may produce errors that can be very hard to debug. This option is a must for any reasonable programmer.
+
'''−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''', turns on even more warnings (this option is '''−W''' in GCC 2.95.3). There is no serious reason to not use this option together with '''−Wall'''.
+
'''−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ć.
  
 +
<small>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ą '''&minus;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>'':
  
<small>Note: GCC4 has an irritating feature. String literals are assumed to be arrays of fixed ''char'' type. Almost all the MorphOS API functions expect strings to be of type ''STRPTR'' which is a typedef of ''unsigned char*''. Passing literals to these functions produces tons of warnings. The clean way to avoid it, is to explicitly cast every literal passed to the MorphOS API as ''STRPTR''. An alternative is to suppress these warnings with '''&minus;Wno-pointer-sign'''. The disadvantage of this second solution is that it also suppresses pointer signedness warnings for all other integer types, not only for ''char''.</small>
+
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.</small>
  
==Linker options==
 
  
'''&minus;noixemul''', instructs the linker to use the static ''libnix'' library for standard C/C++ functions and startup code. Without this parameter, the shared library ''ixemul.library'' is used. [[Installation_of_Software_Development_Kit_and_its_basic_usage#Standard_C_and_C++_Libraries|Read more]].
+
==Opcje linkera==
  
'''&minus;s''', instructs the linker to strip debug information and symbol tables. This information is not needed in a release executable. Stripping them lowers the executable size significantly.
+
'''&minus;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. [[Instalacja SDK (Software Development Kit) i podstawy jego używania#Standardowe biblioteki C i C++|Więcej]].
  
 +
'''&minus;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.
  
==Optimization options==
 
  
'''&minus;On''', where ''n'' ranges from 0 to 3. The parameter is a global control of execution speed optimizer. Higher numbers make the optimizer more aggressive. '''&minus;O2''' seems to be the best for everyday use. '''&minus;O3''' turns on many optimizations which can significantly increase the executable size. Good programmers optimize their algorithms in the first place, compiler optimizations can't fix design errors...
+
==Opcje optymalizatora==
  
'''&minus;Os''', turns on executable size optimization, at the cost of execution speed. Not very useful for typical applications.
+
'''&minus;On''', gdzie ''n'' jest z przedziału od 0 do 3. Parametr kontroluje ogólną "siłę" optymalizacji. '''&minus;O2''' wydaje się być najlepszym wyborem do codziennego użycia. '''&minus;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...
 +
 
 +
'''&minus;Os''', włącza optymalizację pod kątem zmniejszenia rozmiaru kodu kosztem szybkości wykonania. Raczej nieprzydatna dla typowych programów opcja.

Latest revision as of 13:31, 6 April 2011

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.