Praca z kompilatorem GCC

Projekt GCC (GNU Compiler Collection) to zestaw kompilatorów udostępniany w ramach projektu GNU. Jest standardowym kompilatorem na systemach uniksopodobnych, lecz dostępne są wersje na znaczną ilość systemów operacyjnych i platform sprzętowych, prawdopodobnie więcej platform niż jakikolwik inny kompilator. Przynajmniej dwa kompilatory używają podobnych opcji celem zapewnienia zgodności z GCC: Clang i kopilator Intela.

Wywołanie

Załóżmy, że nasz program składa się z plików źródłowych main.cpp, klasa1.cpp i klasa2.cpp (ewentualne pliki nagłówkowe nie są poddawane kompilacji, choć oczywiście są konieczne dla prawidłowego skompilowania plików źródłowych). Aby stworzyć plik wykonywalny, uruchamiamy po prostu:

$ g++ main.cpp klasa1.cpp klasa2.cpp

Z powodów historycznych plik wykonywalny ma domyślnie nazwę a.out. Aby nazywał się inaczej należy podać nazwę pliku:

$ g++ -o program main.cpp klasa1.cpp klasa2.cpp

Kompilacja rozłączna

Powyższe polecenia wykonują naraz kompilację i konsolidację. W wypadku dużych projektów może być to bardzo długi proces. Receptą na to jest kompilacja rozłączna. Aby skorzystać z kompilacji rozłącznej (osobne kompilowanie i osobne łączenie), najpierw kompilujemy pliki źródłowe (lub jednostki translacji) do oddzielnych tzw. plików obiektowych (zawierających kod maszynowy), a następnie otrzymane pliki obiektowe konsolidujemy w plik wykonywalny. W powyższym przykładzie należy wykonać kolejno:

$ g++ -c main.cpp
$ g++ -c klasa1.cpp
$ g++ -c klasa2.cpp
$ g++ -o program main.o klasa1.o klasa2.o

Program Make

Wywoływanie kompilatora po każdej zmianie plików w projekcie może być na dłuższą metę uciążliwe. Do budowania projektów stworzono więc program Make. Prawie każde srodowisko programistyczne buduje projekty używając narzędzia podobnego do Make (Nmake, CMake itp.), nawet jęzeli ukrywa to przed użytkownikiem za interfejsem graficznym. Poniżej omówimy podstawy używania narzędzia Make w wersji GNU.

Plik Makefile

Program Make po uruchomieniu wczytuje domyślnie plik Makefile w bieżącym katalogu i buduje pierwszy napotkany w nim cel (o celach za chwilę). Można też podać w linii poleceń cel do zbudowania, np:

$ make install

Reguły

Plik Makefile składa się z ciągu reguł, każda reguła ma następującą postać:

cel: zależność1 zależność2 ...
  polecenie1
  polecenie2
  ...

Polecenia w powyższej regule muszą być poprzedzone znakami tabulacji (a nie np. czterema spacjami). W najprostszym przypadku zarówno cel jak i zależności są nazwami plików, a polecenia w jakiś sposób tworzą cel z zależności (np. uruchamiają kompilator). Program Make po napotkaniu takiej reguły sprawdza czasy modyfikacji zależności oraz celu i jeżeli cel jest starszy od zależności (lub w ogóle go nie ma), wykonuje kolejno polecenia tworząc cel.

W bardziej zaawansowanych regułach zależności są celami innych reguł. Program Make sprawdzi wtedy, czy ktoraś z powiązanych reguł nie wymaga uruchomienia, a dopiero na końcu zbuduje regułę od której zaczął. Przykładowy plik Makefile dla projektu zawierającego pliki main.cpp, funkcja.cpp i funkcja.h (z zależnościami takimi samymi jak tutaj) wyglądałby tak:

program: main.o funkcja.o
  g++ -o program main.o funkcja.o

main.o: main.cpp funkcja.h
  g++ -o main.o -c main.cpp

funkcja.o: funkcja.cpp funkcja.h
  g++ -o funkcja.o -c funkcja.cpp

Po wpisaniu polecenia make, plik wykonywalny program zostanie przebudowany, ale niezmienione pliki nie będą niepotrzebnie kompilowane.

Najważniejsze opcje kompilatora GCC

Kompilator GCC ma w obecnej wersji ponad 2000 opcji wpływających na gerowanie kodu czy wyświetlanie ostrzeżeń przy kompilowaniu programów. Tutaj podamy tylko kilka najistotniejszych. W razie potrzeby można skonsultować się z pełną dokumentacją.