Dyrektywy preprocesora Jeżeli plik źródłowy posiada rozszerzenie.F lub.FOR, może on zawierać dyrektywy dla preprocesora. Na podstawie tych dyrektyw preprocesor tworzy właściwy plik źródłowy do kompilacji. W większości implementacji dyrektywy procesora są wspólne dla języków FORTRAN, C i C++, natomiast inne dla PL/1, COBOLu oraz PASCALa. Uwaga! W przypadku niektórych implementacji FORTRANu, niezależnie lub zamiast dyrektyw preprocesora występują dyrektywy dla kompilatora. Postać dyrektywy preprocesora: #dyrektywa # musi być w pierwszej kolumnie Przy przetwarzaniu pliku źródłowego zawierającego dyrektywy preprocesora najpierw jest uruchamiany program cpp.
DyrektywaArgumentyZnaczenie #defineŁańcuch tekstowy Definiowanie symbolu a w C i C++ również stałych. #undefŁańcuch tekstowyAnulowanie #define #includeNazwa pliku Włącznie pliku do tekstu źródłowego. #ifWyrażenie logiczne Kompilacja warunkowa. Operandami wyrażeń logicznych mają postać defined(tekst) #elif Łańcuch tekstowy, wyrażenie logiczne #ifdef Łańcuch tekstowy #ifndef #endif Dyrektywy preprocesora użyteczne przy tworzeniu programów w FORTRANie
Dyrektywy #define, #undef i #include #define tekst Powoduje ustawienie przełącznika tekst; stosuje się do kompilacji warunkowej, np. #define DEBUG powoduje ustawienie przełącznika DEBUG Na ogół definicję wstawia się do linii polecenia kompilacji przy pomocy opcji -Dteskt f77 -DDEBUG –o progr prog.F Będzie miało taki sam efekt jak wstawienie #define DEBUG w pierwszej linii pliku program.F #include nazwa_pliku #include Działa podobnie jak fortranowska dyrektywa INCLUDE
Proste dyrektywy kompilacji warunkowej #ifdef tekst kod fortranowski przy zdefiniowaniu tekst #endif #ifndef tekst kod fortranowski przy braku zdefiniowania tekst #endif Trochę bardziej złożona dyrektywa kompilacji warunkowej #ifdef tekst kod fortranowski przy zdefiniowaniu tekst #else kod fortranowski przy braku zdefiniowania tekst #endif Dyrektywy kompilacji warunkowej
Pełna kaskada #ifdef tekst1 kod fortranowski przy zdefiniowaniu tekst1 #elif tekst2 kod fortranowski przy zdefiniowaniu tekst2. #else kod fortranowski przy braku zdefiniowania tekst1, tekst2, … #endif
program przyklad #ifdef PIERWSZY print *,"PIERWSZY" #elif DRUGI print *,"DRUGI" #else print *,NIC #endif end Przykład etoh:~> f77 -DPIERWSZY -o przyklad przyklad.F etoh:~>./przyklad PIERWSZY etoh:~> f77 -DDRUGI -o przyklad przyklad.F etoh:~>./przyklad DRUGI etoh:~> f77 -o przyklad przyklad.F etoh:~>./przyklad NIC
etoh:~> f77 -P -E -DPIERWSZY przyklad.F program przyklad print *,"PIERWSZY" stop end etoh:~> cpp -P -DPIERWSZY przyklad.F program przyklad print *,"PIERWSZY" stop end Kończenie przetwarzania na etapie preprocessingu Wynik przekierować do pliku z rozszerzeniem *.f. Brak opcji –P dla cpp lub –P –E dla f77 powoduje dołączenie nagłówka informującego o preprocessingu którego linie zaczynają się od #. To uniemożliwia kompilację otrzymanego kodu kompilatorem FORTRANu natomiast kompilacja kodu C lub C++ z takim nagłówkiem nie stanowi problemu.
Wykorzystanie słowa kluczowego defined Zamiast łańcucha tekst można po #if oraz #elif umieścić wyrażenie logiczne zawierające operacje logiczne w których defined(tekst1), defined(tekst2),…, są operandami i każdy z nich ma wartość logiczną 0 jeżeli odpowiedni tekst nie został zdefiniowany lub 1 jeżeli został zdefiniowany. Operatory są następujące: && - koniunkcja (operacja binarna) || - alternatywa (operacja binarna) !- negacja (operacja unarna) Przykład: #if defined(AIX) || defined (LINUX) open(plik,status=append) #elif defined(IRIX) open(plik,position=append #endif Przykład źródła FORTRANOwskiego zawierającego różne dyrektywy preprocesoraPrzykład źródła FORTRANOwskiego zawierającego różne dyrektywy preprocesora.
Program make i jego pliki opisowe Program make służy do automatycznego wykonywania sekwencji zaspecyfikowanych zadań, a ogół zrobienia czegoś ze składników. Wygląda to jak duplikowanie skryptów csh, sh, itp., ale są dwie istotne różnice: 1.Zadanie z sekwencji jest realizowane jeżeli przynajmniej jeden z jego składników jest nowszy, niż plik będący wynikiem jego realizacji. 2.Automatycznie sprawdzane są i wykonywane w razie potrzeby wszystkie zadania, których pliki wynikowe są składnikami danego zadania. Składnia polecenia: make [-f plik_opisowy] [opcje] [definicje] [zadanie] Standardowymi plikami opisowymi są Makefile lub makefile; jeden z nich musi być w aktualnym katalogu, jeżeli nie podajemy explicite pliku opisowego opcją –f.
Struktura pliku opisowego # Komentarze jak w skryptach unixowych; może być w dowolnym miejscu. # # Najpierw definiujemy zmienne, jeżeli ich potrzebujemy. Do zdefiniowanych # zmiennych odwołujemy się jak w unixie przez ${zmienna} lub $(zmienna) # zmienna1=wartość1 … zmiennaN=wartośćN # Teraz definiujemy zadania do wykonania. Uwaga! (TAB) oznacza znak tabulacji. # zadanie1:lista_składników_zadania (dependencies) (TAB)instrukcja1 … (TAB)instrukcjaN1 … zadanieM:lista_składników_zadania (TAB)sposób wykonania … (TAB)instrukcjaNM # Każda linia może być kontynuowana w następnej; w takim przypadku musi się ona # kończyć znakiem \ a linia kontynuacji musi się rozpoczynać znakiem tabulacji.
Przykład użycia make do tworzenia programu titr obliczającego krzywą miareczkowania mocnego kwasu mocną zasadą Źródła FORTRANowskie titr.ftitr.f czyt_dane.f oblicz_krzywa.f oblicz_ph.f pisz_wyniki.fczyt_dane.foblicz_krzywa.foblicz_ph.f pisz_wyniki.f Dane krzywa_dane Wyniki krzywa_wyniki Plik Makefile w wersji najprostszej Makefile
Działanie programu make Stan przed uruchomieniem make lrwxrwxrwx 1 adam users 25 Dec 14 11:55 Makefile ->Makefiles/Makefile_simple drwxr-xr-x 2 adam users 4096 Dec 14 11:55 Makefiles -rw-r--r-- 1 adam users 472 Jan czyt_dane.f -rw-r--r-- 1 adam users 176 Dec 14 11:57 krzywa.dane -rw-r--r-- 1 adam users 114 Jan krzywa.wyniki -rw-r--r-- 1 adam users 471 Jan oblicz_krzywa.f -rw-r--r-- 1 adam users 499 Jan oblicz_ph.f -rw-r--r-- 1 adam users 440 Jan pisz_wyniki.f -rw-r--r-- 1 adam users 551 Jan titr.f
etoh:~/FORTRAN/MAKE> make f77 -c titr.f f77 -c czyt_dane.f f77 -c oblicz_krzywa.f f77 -c oblicz_ph.f f77 -c pisz_wyniki.f f77 -o titr titr.o czyt_dane.o \ oblicz_krzywa.o oblicz_ph.o \ pisz_wyniki.o lrwxrwxrwx 1 adam users 25 Dec 14 11:55 Makefile -> Makefiles/Makefile_simple drwxr-xr-x 2 adam users 4096 Dec 14 11:55 Makefiles -rw-r--r-- 1 adam users 472 Jan czyt_dane.f -rw-r--r-- 1 adam users 1764 Dec 14 12:08 czyt_dane.o -rw-r--r-- 1 adam users 176 Dec 14 11:57 krzywa.dane -rw-r--r-- 1 adam users 114 Jan krzywa.wyniki -rw-r--r-- 1 adam users 471 Jan oblicz_krzywa.f -rw-r--r-- 1 adam users 912 Dec 14 12:08 oblicz_krzywa.o -rw-r--r-- 1 adam users 499 Jan oblicz_ph.f -rw-r--r-- 1 adam users 1056 Dec 14 12:08 oblicz_ph.o -rw-r--r-- 1 adam users 440 Jan pisz_wyniki.f -rw-r--r-- 1 adam users 1872 Dec 14 12:08 pisz_wyniki.o -rwxr-xr-x 1 adam users Dec 14 12:08 titr -rw-r--r-- 1 adam users 551 Jan titr.f -rw-r--r-- 1 adam users 1132 Dec 14 12:08 titr.o
Jeżeli zmienimy tylko niektóre pliki źródłowe lub skasujemy niektóre pliki *.o to make spowoduje kompilacje tylko plików zmienionych. W poniższym przykładzie modyfikujemy plik poleceniem touch (zmienia tylko czas I datę utworzenia plku). etoh:~/FORTRAN/MAKE> touch titr.f etoh:~/FORTRAN/MAKE> make f77 -c titr.f f77 -o titr titr.o czyt_dane.o \ oblicz_krzywa.o oblicz_ph.o \ pisz_wyniki.o Przykłady bardziej złożonych plików Makefile do tworzenia programu titr MakefileMakefile zawierający definicję kompilatora oraz objectów poprzez zmienne MakefileMakefile zawierający ogólne polecenia kompilacji dla plików o określonym rozszerzeniu poprzez reguły przyrostkowe (suffix rules).