56.DOC

(137 KB) Pobierz









Część ósma
Programowanie dla zaawansowanych

W tej części:

u                                          Zarządzanie kodem źródłowym             

u                                          Jądro systemu              

u                                          Tworzenie sterowników urządzeń             

u                                          Projekt WINE             

u                                          HylaFAX             

u                                          Gry             

u                                          Adabas-D i inne bazy danych             

u                                          StarOffice             

u                                          Program Lone-Tar firmy Lone Star Software             

 










E:\Moje dokumenty\HELION\Linux Unleashed\Indeks\56.DOC              833


Rozdział 56.
Zarządzanie kodem źródłowym










Rozdzia³ 56. ¨ Zarządzanie kodem źródłowym              833

Peter MacKinnon i Tim Parker

W tym rozdziale:

u                                          Program make

u                                          RCS

u                                          Uzyskiwanie informacji o wersji z pliku RCS             

u                                          Dostęp do pliku RCS             

u                                          Porównywanie i łączenie poprawek             

u                                          Praca z programem make i systemem RCS             

Duże projekty programistyczne, w których skład wchodzi wiele plików źródłowych tworzonych przez różnych programistów, mogą sprawiać mnóstwo kłopotów, szczególnie jeśli to właśnie Ty jesteś odpowiedzialny za zarządzanie całością projektu. Oto najczęściej występujące problemy:

u                                          skąd można mieć pewność, że plik zawierający np. biblioteki wejścia / wyjścia napisane przez innego programistę zawiera najnowszą wersję procedur?

u                                          jak poradzić sobie w sytuacji, gdy trzeba przekompilować aplikację, ale nie bardzo wiadomo, które z 50 plików wchodzących w skład kodu źródłowego zostały zmodyfikowane?

Okazuje się, że śledzenie najnowszych wersji plików i szukanie w razie potrzeby wersji sprzed godziny czy też sprzed kilku dni może zająć więcej czasu niż samo programowanie.

Nawet niewielkie aplikacje zwykle tworzone są na podstawie więcej niż jednego pliku zawierającego kod źródłowy. Podczas kompilowania programów w języku C musisz posługiwać się nie tylko plikami z kodem źródłowym, ale również plikami nagłówkowymi i plikami bibliotek. Na szczęście, dla systemu Linux dostępne jest środowisko programistyczne znakomicie upraszczające większość zadań związanych z zarządzaniem kodem źródłowym.

Program make

Program make, będący prawdopodobnie najważniejszym programem użytkowym wykorzystywanym podczas tworzenia oprogramowania, pozwala określać zależności pomiędzy plikami i uaktualniać tylko te pliki, które tego wymagają. Uaktualnianie zwykle sprowadza się do kompilacji odpowiednich plików źródłowych czy też konsolidacji plików pośrednich, ale w skład tego procesu może wchodzić również usuwanie plików tymczasowych. Proces uaktualniania może być powtarzany dziesiątki razy w trakcie tworzenia aplikacji. Zamiast zajmowania się związanymi z nim zadaniami ręcznie, można zlecić je programowi make, zyskując więcej czasu na ważniejsze czynności, takie jak tworzenie samego kodu źródłowego czy oglądanie telewizji.

Program make generuje odpowiednie polecenia na podstawie pliku opisu nazywanego najczęściej makefile. Wygenerowane polecenia są następnie przetwarzane przez interpreter poleceń powłoki. Zawartość pliku makefile to w zasadzie zestaw zadań (zwanych regułami), które należy wykonać przy uaktualnianiu projektu. Definiowanie reguł sprowadza się do określenia zależności pomiędzy plikami. W przypadku tworzenia pliku wykonywalnego z kodu w języku C w systemie Linux zwykle oznacza to kompilację plików źródłowych do postaci pośredniej, a następnie konsolidację plików pośrednich (być może wraz z dodatkowymi bibliotekami) do postaci wykonywalnej. Program make potrafi również sam określić, które z plików zostały zmodyfikowane i wymagają uaktualnienia (na podstawie czasu ostatniej modyfikacji pliku).

 

Nazwa makefile czy Makefile jest faktycznie nazwą pliku, który program make spodziewa się znaleźć w katalogu bieżącym. Można zażądać przetwarzania pliku o innej nazwie, ale zgodnie z tradycją (a kto chciałby się spierać z ponad trzydziestoletnią tradycją?) programiści używają pliku o nazwie makefile.

Program make jest zdecydowanie najlepiej przystosowany do programowania w języku C, ale można również wykorzystywać go przy pracy z innymi językami programowania dla Linuxa, na przykład z asemblerem czy językiem FORTRAN.

Przykładowy plik makefile

Przyjrzyjmy się prostemu przykładowi zastosowania programu make.

Polecenie

 

$make cosnowego

powoduje, że zostanie utworzona nowa wersja programu cosnowego. W naszym przypadku będzie to plik wykonywalny, w związku z czym proces ten będzie składał się z kompilacji i konsolidacji odpowiednich plików. Plik cosnowego określa się jako plik docelowy (ang. target) programu make. Pliki pośrednie konsolidowane do jednego pliku wykonywalnego nazywane są plikami pierwotnymi (ang. dependents) pliku cosnowego. Pliki zawierające kod źródłowy są kompilowane do postaci pośredniej, są więc również (choć nie wprost) plikami pierwotnymi pliku cosnowego.

Oto lista plików, które będą potrzebne do utworzenia programu cosnowego (ich zawartość jest dla naszego przykładu nieistotna):

u                                          dwa pliki zawierające kod źródłowy w języku C, main.c i zrobto.c;

u                                          trzy pliki nagłówkowe, tak.h, nie.h i moze.h;

u                                          jeden plik zawierający bibliotekę funkcji, /usr/nowe/lib/swiezy.a;

u                                          plik zawierający kod źródłowy w asemblerze, szybciej.s.

Jak widać, nasz projekt nie jest duży, więc nie byłoby szczególnie trudno ręcznie kompilować i konsolidować odpowiednie pliki. Zamiast tego jednak spróbujmy utworzyć odpowiedni plik makefile, pozwalający zautomatyzować te niezbyt fascynujące czynności.

Używając swojego ulubionego edytora tekstów, utwórz plik makefile o następującej treści:

 

cosnowego: main.o zrobto.o szybciej.o /usr/nowe/lib/swiezy.a
    cc –o cosnowego main.o zrobto.o szybciej.o /usr/nowe/lib/swiezy.a
main.o: main.c
    cc –c main.c
zrobto.o: zrobto.c
    cc –c zrobto.c
szybciej.o: szybciej.s
    as –o szybciej.o szybciej.s
sprzataj:
    rm *.o
moze.h: tak.h nie.h
    cp tak.h nie.h /usr/reksio/

Format pliku makefile

Załóżmy, że wszystkie wspomniane pliki znajdują się w tym samym katalogu, co plik makefile; co zyskaliśmy, tworząc go? Każdy plik makefile (więc również ten, który przed chwilą utworzyłeś) składa się z pewnej liczby wpisów. Przykładowy plik składa się z sześciu wpisów. Pierwszy wiersz każdego wpisu definiuje zależności pomiędzy plikami. Pozwala on określić (po dwukropku), jakie pliki są niezbędne do utworzenia pliku (obiektu) docelowego o nazwie zapisanej przed dwukropkiem. Następne wiersze określają zestaw poleceń, które zostaną wykonane przez program make, gdy zajdzie potrzeba uaktualnienia danego pliku docelowego. Pojedynczy wpis ma więc postać:

 

plik docelowy: pliki potrzebne do jego utworzenia
(TAB) lista poleceń

Wiersze określające polecenia, które mają zostać wykonane, muszą rozpoczynać się od znaku tabulacji – jest to jedna z reguł składniowych pliku makefile. Wierszy określających polecenia może być więcej, ale każdy z nich jest wykonywany oddzielnie, w swoim własnym środowisku. Wynika stąd, że następujące polecenia:

 

cd gdzies
mv *.c gdzieindziej

nie zadziałają zgodnie z oczekiwaniami. Aby zapobiec tego rodzaju sytuacjom, należy polecenia, które mają zostać wykonane wspólnie, zapisywać w jednym wierszu, rozdzielając je średnikami. Można to zrobić na dwa sposoby:

 

plik docelowy: pliki potrzebne do jego utworzenia
     polecenie1; polecenie2; polecenie3;...

albo:

 

plik docelowy: pliki potrzebne do jego utworzenia
     polecenie1; \
     polecenie2; \
     polecenie3;

i tak dalej. Jeśli używasz drugiego sposobu, ukośnik musi być ostatnim znakiem wiersza, dzięki czemu zapobiegnie on interpretacji znaku końca wiersza.

 

Można również określić kilka rodzajów zależności pomiędzy plikami, definiując kilka wpisów dla tej samej nazwy pliku docelowego. Program make ma o wiele większe możliwości, niż opisane w tym rozdziale, ale prawdopodobnie nie będą Ci one potrzebne, dopóki nie będziesz pracował z naprawdę dużymi projektami, uwikłanymi w mnóstwo wzajemnych zależności.

Pierwszy wpis naszego pliku makefile jest kluczowy dla utworzenia pliku wykonywalnego cosnowego. Stwierdza on, że plik cosnowego może zostać uaktualniony w przypadku, gdy wszystkie pliki pośrednie i pliki biblioteki, od których jest on zależny, istnieją i którykolwiek z nich jest nowszy niż ostatnia wersja pliku cosnowego. Oczywiście, jeśli plik cosnowego nie istnieje, również zostaną podjęte wszystkie działania prowadzące do jego utworzenia. Najpierw program make sprawdzi, czy któryś z plików pierwotnych wymaganych do utworzenia pliku cosnowego wymaga uaktualnienia i, w razie potrzeby, podejmie odpowiednie działania. Proces ten powtarzany jest rekurencyjnie – program make sprawdza zależności dla plików docelowych na kolejnych poziomach, zgodnie z danymi zapisanymi w pliku makefile.

Ostatni wpis jest dość nietypowy – powoduje on skopiowanie plików tak.h i nie.h (zależnych w jakiś sposób od pliku moze.h) do katalogu domowego użytkownika reksio pod warunkiem, że zostały one zmodyfikowane. Takie rozwiązanie może być przydatne na przykład w przypadku, gdy reksio pracuje nad jakimś programem związanym z naszym projektem i powinien zawsze mieć dostęp do najnowszej wersji plików nagłówkowych. Jak widać, program make może być wykorzystany do celów innych niż tylko kompilowanie i konsolidacja programów – potrafi on wykonywać różne polecenia w oparciu o zadeklarowane zależności.

W naszym pliku makefile zdefiniowany jest również plik docelowy o nazwie sprzataj, którego uaktualnienie nie powoduje kompilowania żadnych plików. Plik ten nie wymaga istnienia żadnych plików pierwotnych – dla programu make nie stanowi to żadnego problemu. Jeśli w katalogu bieżącym nie ma pliku o nazwie sprzataj, program make wykona wszystkie polecenia powiązane z tym identyfikatorem – a więc usunie pliki pośrednie (z rozszerzeniem .o). Plik sprzataj, choć dość nietypowy (ponieważ z założenia nie jest nigdy tworzony), jest traktowany na równi z wszystkimi pozostałymi obiektami docelowymi.

Jeśli wydasz polecenie

 

$ make cosnowego

program make wygeneruje serię poleceń, które spowodują uaktualnienie wszystkich plików pierwotnych pliku docelowego cosnowego, a następnie uaktualni sam ten plik. Wszystkie przetwarzane polecenia są wyświetlane na ekranie. Taki sam efekt da wpisanie polecenia

 

$ make

ponieważ program make wywołany bez argumentów uaktualnia pierwszy plik docelowy napotkany w pliku makefile. Przetwarzane polecenia są wyświetlane na ekranie, a po wystąpieniu ewentualnego błędu działanie programu make jest wstrzymywane.

Jeśli wszystkie pliki pierwotne i plik cosnowego...

Zgłoś jeśli naruszono regulamin