Borland C++ Compiler/MAKE: Różnice pomiędzy wersjami
Usunięta treść Dodana treść
Nie podano opisu zmian |
Nie podano opisu zmian |
||
Linia 1:
=
==
MAKE pozwala zautomatyzować proces budowania projektu programistycznego poprzez stawianie odpowiednich zasad dla plików źródłowych i wywoływaniu komend systemowych. Poza tym program ten znacznie przyspiesza proces budowy programu, ponieważ wykonuje opercje tylko na plikach, które zostały zmodyfikowane od czasu ostatniej kompilacji (uruchomienia MAKE).
==
Najważniejszy plik dla MAKE. W nim znajdują się wszelkie zasady operacji na źródłach, wywołania programów, makra i instrukcje odpowiedzialne za zarządzanie budową projektu. Utworzyć go można w najprostszym edytorze tekstowym (np. w systemowym Notatniku). Należy pamiętać jednak, aby plik zapisać jako makefile.mak lub makefile (bez rozszerzenia). To, którą opcje wybierzesz jest już obojętne.
==
Wywołanie MAKE jest nieco inne niż pozostałych narzędzi Borland-a. W tym przypadku kluczową rolę odgrywa lokalizacja na dysku, z której wywołujesz program. W lokalizacji tej musi się znajdować plik makefile wraz ze skopiowanym (z katalogu \bin naszych FCLT) make.exe. To ważne! Inaczej programy wywoływane z makefile'a nie będą działały poprawnie. Będziesz wywoływać właśnie tę kopię make'a, więc najpierw trzeba wejść w jej lokalizację:
CD <lokalizacja>
MAKE [<opcje>] [<wynik>]
; <tt><opcje></tt> : MAKE ma mało opcji, a ponadto w większości z nich można zastąpić odpowiednimi komendami w makefile'u, zanim jednak oswoisz się z dyrektywami warto na nie spojrzeć; w następnym podrozdziale będzie o nich więcej
; <tt><wynik></tt> : czyli, plik(i) wynikowy/e Twojego projektu, pamiętaj że nie musisz ich tutaj wymieniać
w praktyce wywołanie MAKE może wyglądać tak:
Linia 18:
MAKE -a -s
==
Jak zwykle skupię się tylko na tych najważniejszych:
{|
Linia 39:
Zazwyczaj opcje te można zastąpić odpowiednimi dyrektywami w samym makefile'u
==
Składnia makefile to już swego rodzaju język programowania do budowy projektów programistycznych. Możemy rozróżnić jej kilka podstawowych elementów:
Linia 46:
komendy systemowe "siłą" MAKE jest możliwość wywoływania nie tylko narzędzi Borland-a, ale także komend DOS'owych i innych programów takich jak np. kompilator assemblera.
; zmienne : tak jak w każdym języku programowania "kontenery" do których możemy przypisać łańcuchy znaków.
; dyrektywy : chociaż będę je opisywał na końcu nie powinny być lekceważone, to jedne z najważniejszych elementów w każdym języku programowania, tak samo jest i tutaj.
A tak wygląda przykładowy makefile, z którego korzystasz na co dzień prawdopodobnie nawet o tym nie wiedząc, czyli <tt>builtins.mak</tt> z BIN'a:
#
Linia 86:
!endif
Czarna magia? W następnych podrozdziałach
Aby to co pisze nie było tylko czystą teorią wymyśliłem projekt ''HelloProject'', którego makefile będziemy rozwijać w miare postępów w nauce. Jak zorganizować sobie miejsce pracy nad tym projektem? Należy utworzyć nowy katalog z nazwą projektu: <tt>C:\Hello\</tt> Następnie trzeba tam skopiować wszystkie jego pliki źródłowe:
* <tt>Hello.cpp</tt>
* <tt>klasa.cpp</tt>
* <tt>klasa.h</tt>
* <tt>zasoby.rc</tt>
* <tt>DEF.def</tt>
* <tt>makefile.mak
Wynikiem tego projektu będzie windowsowy EXE'k: Hello.exe. Nieważne, co będzie robił ten program, to tylko ćwiczenie, resztę pozostawiam Tobie, Twojej wyobraźni i inwencji. MAKE będziemy wywoływać tam, gdzie jest makefile, czyli z katalogu <tT>c:\Hello\</tt>. Tam też powinna znaleźć się kopia programu MAKE.
== Komentarze ==
W makefile'u tak jak w C++, również możesz używać komentarzy jednoliniowych. Wszystko to co znajdzie się w jednej linii po symbolu hash'a: '''<tt>#</tt>''' MAKE ignoruje.
# to jest komentarz
== 4.7 Zasady ogólne i szczegółowe ==
Zasady regulują wywoływanie narzędzi w makefile'u. Ogólnie rzecz biorąc zasady określają jakie pliki ma przetwarzać MAKE, ewentualnie gdzie one się znajdują, gdzie ma się znaleźć wynik operacji. Ważną kwestią w zrozumieniu zasad jest fakt, że zasada to tylko prawo, za wypełnienie którego odpowiedzialny jesteś Ty. Pamiętaj też że zasada przekazuje tylko informacje dla MAKE, natomiast komendy, które za jej pomocą wywołujesz rządzą się już swoimi prawami. Zarówno przy komendach, jak i przy samych zasadach można używać symbolu
<txt>\
<dok. txt'u>
Ogólny szablon zasady wygląda tak:
<zasada>
<komenda>
[<komenda>]
[...]
Pamiętaj tylko o przynajmniej jednej spacji przed komendą, aby nie znajdowała się ona tuż przy początku linii - to błąd! Błędem jest też nie zapisanie samej zasady przy początku linii. Jednym słowem musi to wyglądać tak, jak na powyższym szablonie. Zasada zacznie "wchodzić w życie" (wywoływać swoje komendy), jeśli jej pliki zależne (źródłowe) będą różniły się datą i czasem ostatniej modyfikacji z datą plików wynikowych lub jeśli pliki wynikowe w ogóle nie będą istnieć. Np. jeśli chcemy skompilować plik <tt>Hello.cpp</tt> za pomocą zasad to kompilator zostanie wywołany kiedy <tT>Hello.cpp</tT> i <tt>Hello.obj</tt> będą miały inne daty modyfikacji lub jeśli plik <tt>Hello.obj</tt> nie będzie istniał. Jak widać w tytule tego rozdziału zasady możemy podzielić na dwa typy: ogólne i szczegółowe (''implicit & explicit rules'').
===
Zasady te tyczą się wszystkich plików z określonym rozszerzeniem (ewentualnie możesz określić folder, w którym MAKE ma zezwalać na operacje na nich). Zasady te zakładają tylko zmianę rozszerzenia, a nazwy plików pozostawiają. ''Implicit rule'' wygląda tak:
[{<lokalizacja1>}].<roz1>[{<loklalizacja2>}].<roz2>:
<komenda/y>
gdzie:
; <tT><lokalizacja1></tt> : lokalizacja/e plików zależnych (źródłowych) (w przypadku gdy jest ich więcej jako seperatora używamy średnika:';')
; <tt><roz1></tt> : rozszerzenie plików źródłowych
; <tt><lokalizacja2></tt> : lokalizacja/e na dysku plików plików docelowych (wynikowych) operacji (gdzie mają się one znaleźć) oddzielone jedna od drugiej średnikiem:';'
; <tt><roz2></tt> : rozszerzenie plików wynikowych
Na przykład:
Linia 134 ⟶ 135:
copy hello.obj c:\obj
Przejdźmy teraz do analizy tych trzech linijek kodu. Pozwoli Ci to lepiej zrozumieć działanie zasad make'a. W tym przypadku zasada zezwala na operacje na plikach *.cpp tylko z katalogu <tT>c:\src</tt>, a ich wynik w magiczny sposób musi znaleźć się w <tt>c:\obj</tt>, oczywiście nie da się tego dokonać bez pomocy systemowego słowa kluczowego COPY albo użycia w parametrach wywołania kompilatora opcji -n. Jeśli nie określisz w zasadzie tych lokalizacji, to dozwolone będą operacje na wszystkich plikach na całym Twoim twardzielu. Określając w zasadzie lokalizacje plików źródłowych nie łudź się że zostanie to przekazane komendom które wywołujesz, dlatego podczas kompilacji zapisałem plik <tT>hello.cpp</tt> wraz jego z lokalizacją, oczywiście nie musiałbym tego robić, gdybyśmy odpalili MAKE z lokalizacji <tT>c:\src</tt>.
===
Zasady szczegółowe określają z jakich plików źródłowych powstaje plik wynikowy. W tym przypadku musimy podać dokładne nazwy plików a nie jak to było w przypadku zasad ogólnych samego rozszerzenia plików. Spójrzmy na składnię:
<wynik(i)>:[:] [{<lokalizacja>}]<src>
<komenda/y>
; <tt><wynik(i)></tt> : nazwa pliku/ów wynikowego/ych, który ma być wygenerowany
; <tt><lokalizacja></tt> : lokalizacja/e plików źródłowych odzielone od siebie średnikami:';'
; <tt><src></tt> : plik(i) źródłowy/e
Przykład powinien rozwiać wszelkie wątpliwości:
Linia 151 ⟶ 152:
Hello.exe,,cw32.lib import32.lib,,
Zasada zakłada że <tt>Hello.obj</tt> i <tt>klasa.obj</tt> znajdują się tylko i wyłącznie w katalogu <tt>c:\obj</tt>. Tak jak w zasadach ogólnych tak i tutaj ta lokalizacja nie ma nic wspólnego z komendami - i w tym przypadku musisz podać lokalizacje każdego ze swoich plików źródłowych (oczywiście jeśli znajdują się one tam gdzie makefile nie musisz tego robić). Zmieni się to dopiero po wprowadzeniu do kodu [[Borland C++ Compiler:MAKE#Specjalne zmienne|inteligentnych
Wszystkie pliki docelowe (wynikowe) z zasad ogólnych powinny być automatycznie plikami źródłowymi w zasadzie szczegółowej. Inaczej MAKE danej zasady ogólnej nie weźmie pod uwagę. Pokaże to na przykładzie:
Linia 165 ⟶ 166:
cw32.lib import32.lib,,zasoby.res
W tym przypadku konsolidator zgłosi błąd, że nie może znaleźć pliku zasoby.res, nic dziwnego -
MAKE zakłada, iż zawsze dysponujemy tylko jednym plikiem wynikowym, ale i temu można zaradzić tworząc symboliczne pliki wynikowe o tak:
ALL: <PlikWynikowy1> <PlikWynikowy2> [<Plikwynikowy3> [...]]
Teraz nic nie stoi na przeszkodzie, aby wcześniejszy niefortunny kod zamienić na poniższy:
Linia 192 ⟶ 193:
implib mylib +lib3.obj +lib4.obj
Najpierw do biblioteki statycznej mylib.lib dodawane są <tt>obj1.obj</tt> i <tt>obj2.obj</tt>, następnie w drugiej zasadzie do tej samej biblioteki odajemy: <tt>obj3.obj</tt> oraz <tt>obj4.obj</tt>.
===
Jest jeszcze jedna zasada, którą odkryłem analizując makefile generowany przez program vide, co ciekawe help FCLT nic o niej nie pisze, zachowuje się jakby w ogóle nie istniała... no comment. Właściwie to nie wiem, czy można by nazywać to zasadą, bo nie określa żadnych praw dostępu do plików. Jej składnia jest miej więcej taka:
<nazwa>:
<komenda/y>
Przydaje się ona do wywołania narzędzi typu debugger lub TOUCH które nie czynią żadnych zmian w rozszerzeniu pliku zatem nie można ich normalnie wywołać z jakichkolwiek wcześniejszych zasad. Poza tym zasada ta zawsze "wejdzie w życie", gdyż nie mamy tu żadnych plików zależnych ani wynikowych. Pewnym jej ograniczeniem jest to że po zakończeniu jej działań MAKE także kończy. Cóż, nie można mieć wszystkiego. Dla przykładu podaje wywołanie programu TOUCH:
Linia 205 ⟶ 206:
touch *.cpp *.rc
==
Na co nam zasady skoro i tak nigdy nie zostaną poparte działaniami? - na nic. Dlatego, aby coś zaczęło działać trzeba to...wywołać :). Jak już pisałem oprócz zwykłych wywołań narzędzi z FCLT można tu też umieszczać komendy systemowe, czy włączać inne program takie jak np. kompilator assemblera, czy swój własny program już po skompilowaniu. Pamiętaj jednak, że komendy nie mogą występować w makefile'u od tak sobie, muszą one zawierać się w jakiejś zasadzie tylko w ten sposób można wywoływać narzędzia przez MAKE, inaczej program zgłosi błąd. Poza tym przy wywołaniu 'czegoś' można użyć następujących przedrostków:
{|
Linia 237 ⟶ 238:
zasoby.res
Ten makefile jest dość prymitywny, jednak automatyzuje on już całą budowę projektu ''HelloProject''. Spróbuj go odpalić samemu.
==
W makefile'u możemy deklarować
<nazwa> = [<łańcuch_znaków>]
Zwroć uwagę, że przypisywany łańcuch nie jest ujęty w "" tak jak to jest w C/C++, wszystko to co znajdzie się za znakiem równości:
SRC = Hello.cpp klasa.cpp
Wykorzystanie
.cpp.obj:
bcc32 -c $(SRC)
I tak
C_FLAGS = -tW -c -v -w-par -w-rvl
Linia 261 ⟶ 262:
bcc32 $(C_FLAGS) $(SRC)
===
Każdemu zadeklarowanemu przez nas makru można zmienić wartość. Robimy to korzystając z następującego szablonu:
$(<nazwa_zm>:<stary_txt>=<nowy_txt>)
Na przykład można to wykorzystać do zmiany rozszerzenia plików z jakich korzystamy:
Linia 271 ⟶ 272:
$(SRC:.cpp=.obj)
Teraz nie musisz pisać już
===
Istnieją jeszcze
{|
|zmienna
| przekazywane dane w zasadach ogólnych
| przekazywane dane w zasadach szczegółowych
|-
| $*
| plik źródłowy (bez rozszerzenia) z lokalizacją
| plik wynikowy (bez rozszerzenia) z lokalizacją
|-
| $<
| plik źródłowy+rozszerzenie z lokazlizacją
| plik wynikowy+rozszerzenie z lokazlizacją
|-
| $:
| lokalizacja
| lokalizacja
|-
| $.
|
| plik wynikowy+rozszerzenie
|-
| $&
| plik źródłowy
| plik wynikowy
|-
| $@
| plik wynikowy+rozszerzenie z lokalizacją
| to samo co $<
|-
| $**
| to samo co $<
| wszystkie
|-
| $?
| to samo co $<
| stare
|}
Linia 317 ⟶ 318:
bcc32 -q -c $<
ten kod spowoduje kompilacje wszystkich plików *.cpp w katalogu <tt>c:\cpp</tt>, a pliki *.obj, które wygeneruje umieści w lokalizacji w której znajduje makefile.
To nie wszystko -
$(
Oto typy znaczników do standardowych makr MAKE'a:
{|
|znacznik
| przekazywane dane o pliku
| przykład użycia
| przykładowy rezultat
|-
| D
Linia 354 ⟶ 355:
bcc32 -q -c -n$(@D) $<
ten fragment skryptu spowodowałby kompilację plików *.cpp z katalogu <tt>c:\cpp</tt> i zapisywałby pliki *.obj do katalogu <tt>c:\obj</tt>.
Twoje
$(BIN): $(SRC:.cpp=.obj)
ILINK32 $(L_FLAGS) c0w32.obj $**,$.,,cw32.lib import32.lib $(LIB),$(DEF),$(RES)
Używając makr <tt>$**</tt> lub <tt>$?</tt> w zasadzie szczegółowej (''explicit rule'') można do komendy dodać przedrostek '''&''', który będzie oznaczał, że komenda odnosi się tylko do jednego pliku z pola src (normalnie makra <tt>$**</tt> i <tt>$?</tt> w zasadach szczegółowych oznaczają wszystkie pliki źródłowe, co uniemożliwi pracę niektórych komend) np.:
hello.exe: hello.obj klasa.obj
copy $** c:\obj
Po takiej operacji komenda systemowa COPY zgłosi błąd, ponieważ <tt>$**</tt> wskazuje na pliki <tt>hello.obj</tt> i <tt>klasa.obj</tt>, a COPY może obsługiwać tylko jeden plik. Ten błąd da się naprawić:
hello.exe: hello.obj klasa.obj
Linia 376 ⟶ 377:
copy klasa.obj c:\obj
..aha przed przystąpieniem do kolejnego rozdziału rozwiniemy nasz ''HelloProject'' o
{|
| <tt>.\src\
| <-- Hello.cpp klasa.cpp
|-
|<tt>.\src\hdr\</tt>
| <-- klasa.h
|-
|<tt>.\src\res\</tt>
| <-- zasoby.res
|-
|<tt>.\obj\</tt>
| <-- makefile.mak DEF.def make.exe *.obj *.li?
|-
|<tt>.\bin\</tt>
|}
Chyba nie muszę wyjaśniać przeznaczenia tychże katalogów? Ich nazwy mówią same za siebie. Teraz proszę zerknąć na ten kod:
Linia 416 ⟶ 427:
DEL $.
Jak widać makefile bardzo zyskał na funkcjonalności i co najważniejsze na uniwersalności: dzięki
Teraz małe sprostowanie tak dziwnego zapisu kompilacji zasobów: <tt>brcc32</tt> nie zachowuje się jak większość programów z FCLT ponieważ zostawia plik wynikowy w lokalizacji ze źródłami.<br>
Jest pewien mankament tego makefile'a: jeśli nie masz plików zależnych zasady szczegółowej MAKE się o nie upomni, choć mają one dopiero powstać w trakcie trwania makefile'a. Jest na to rada: przed pierwszym (później nie ma już takiej potrzeby) uruchomieniem makefile'a "dotknij" programem TOUCH wszystkie pliki źródłowe. Np. w tym projekcie będzie to wyglądać tak:
Linia 429 ⟶ 440:
Można rozwiązać to w ten sposób... ale jest znacznie bardziej funkcjonalna dyrektywa...
==Dyrektywy==
Dyrektyw/słów kluczowych w borlandowskim makefile'u jest mniej niż np. w C++ ale wystarczająco dużo, aby efektywnie zarządzać projektem. W tym przypadku spisałem niemal wszystkie wyrażenia (chyba że sam któregoś nie rozumiałem). Nie musisz się ich uczyć na pamięć, wystarczy, że będziesz miał te 5 tabelek zawsze pod ręką. Warto jednak na początek je przeczytać, żeby przekonać się jakie są możliwości słów kluczowych w MAKE.
Ważną zasadą przy wykorzystywaniu dyrektyw jest to aby MAKE nie pomylił danej dyrektywy z wywołaniem programu. Jeśli więc chcemy dyrektywa umieścić w polu komend jakiejś zasady to trzeba ją postawić na początku wiersza w innym przypadku zostanie ona potraktowana jako komenda systemowa, a to może oznaczać tylko kłopoty...
===Pliki Projektu i konfiguracja MAKE===
Linia 437 ⟶ 448:
| opis
|-
|<pre>.autodepend</pre>
| -a
| sprawdzaj pliki nagłówkowe przed kompilacją i jeśli zostaną zmodyfikowane kompiluj jeszcze raz pliki które z nich korzystają
|-
|<pre>.noautodepend</pre>
| -a-
| nie sprawdzaj plików nagłówkowych
|-
|<pre>.cacheautodepend</pre>
| -c
| przechowuj w pamięci podręcznej pliki wchodzące w skład projektu i jeśli nie zostaną w poczynione żadne zmiany nie wykonuj na nich operacji ponownie
|-
|<pre>.nocacheautodepend</pre>
| -c-
| nie przechowuj w pamięci podręcznej plików wchodzących w skład projektu
|-
|<pre>.keep</pre>
| -K
| zachowuj pliki tymczasowe tworzone podczas działania programu MAKE
|-
|<pre>.nokeep</pre>
| -K-
| nie przechowuj plików tymczasowych które są tworzone podczas działania MAKE'a
|-
|<pre>.ignore</pre>
| -i
| ignoruj wartość jaką zwróci komenda
|-
|<pre>.noIgnore</pre>
| -i-
| nie ignoruj wartości jaką zwróci komenda
|-
|<pre>.silent</pre>
| -s
| nie pokazuj na ekranie wywołania narzedzia
|-
|<pre>.nosilent</pre>
| -s-
| pokazuj na ekranie wywołanie narzędzia lub komendę jaką wykonuje system
|-
|<pre>.swap</pre>
| -S
| wyczyść swoją pamięć zanim zaczniesz wywoływać narzędzia (ta instrukcja jest dobra podczas operacji na dużych plikach)
|-
|<pre>.noswap</pre>
| -S-
| nie czyść pamięci przed wywoływaniem narzędzi
|}
{|
|szablon
|opis |-
|<pre>.precious: <PlikWynikowy></pre>
| zapisz <tt><PlikWynikowy></tt> (jeśli któryś z programów "padnie" MAKE często wyrzuca swój plik wynikowy)
|-
|<pre>.suffixes: .<roz1> [.<roz2> [.<roz3>]..]</pre>
| twórz pliki najpierw z rozszerzeniem: <tt><roz1></tt> później z <tt><roz2></tt>, a na końcu z <tt><roz3></tt> (itd.); ta dyrektywa jest analizowana przez zasady ogólne i określa ona porządek tworzenia <tt>PlikówDocelowych</tt>
|-
|<pre>.path.<roz> = <lokalizacja></pre>
|szukaj pliku z rozszerzeniem <tt><roz></tt> w podanej <tt><lokalizacji></tt> (ta dyrektywa niweluje problem z wcześniejszym makefile'em)
|-
|<pre>!include [<lokalizacja>]<Nazwapliku></pre>
| dodaj tekst do obecnego makefile'a z pliku <tT><NazwaPliku></tt> (działa jak makro-instrukcja <tt>#include</tt> w C/C++)
|-
|<pre>!undef <nazwa_zmiennej></pre>
| "wyrzuć" zmienną <tt>nazwa_zmiennej</tt>
|}
===Instrukcje warunkowe===
{|
|szablon
| opis
|-
|<pre>!ifdef <nazwa_zmiennej> <operacje></pre>
| jeśli zmienna <tt><nazwa_zmiennej></tt> jest zadeklarowana wykonaj <tt><operacje></tt>
|-
|<pre>!ifndef <nazwa_zmiennej> <operacje></pre>
| jeśli zmienna <tt><nazwa_zmiennej></tt> <u>nie</u> jest zadeklarowane wykonaj <tt><operacje></tt>
|-
|<pre>!if <warunek> <operacje></pre>
| jeśli <tt><warunek></tt> zostanie spełniony wykonaj <tt><operacje></tt>
|-
|<pre>!else <operacje></pre>
| w przeciwnym wypadku wykonaj <tt><operacje></tt> (musi występować z <tt>!if</tt> lub <tt>!ifdef</tt> lub <tt>!ifndef</tt>)
|-
| <pre>!elif <warunek> <operacje></pre>
| w przeciwnym wypadku, jeśli <tt><warunek></tt> jest spełniony wykonaj <tt><operacje></tt> (musi występować z <tt>!if</tt> lub !ifdef</tt>, <tt>!ifndef</tt>, <tt>!else</tt>)
|-
|<pre>!endif</pre>
|kończy instrukcję warunkową
|}
Instrukcję warunkową warto bardziej wnikliwie zanalizować, ponieważ jak sądzę będziesz ją często używał(a).
# Każda instrukcja warunkowa musi się kończyć dyrektywą !endif
# Przy określaniu warunków instrukcji warunkowej możemy użyć między innymi następujących operatorów:
{|
| operator
| opis
| operator
| opis
|-
| -
| negacja
| ||
| logiczne "lub"
|-
| +
| dodawanie
| !
| logiczne "nie"
|-
| -
| odejmowanie
| &&
| logiczne "i"
|-
| *
| mnożenie
| >=
| większe lub równe
|-
| /
| dzielenie
| <=
| mniejsze lub równe
|-
| ==
| równe
| >
| większe
|-
| !=
| nierówne
| <
| mniejsze
|}
# Aby sprawdzić czy zmienna jest zadeklarowana (tj. czy je wcześniej stworzyliśmy) można użyć specjalnego '''znacznika d'''. Zastosowanie go jest równoważne z użyciem dyrektywy !ifdef:
* <tt>!ifdef <zmienna></tt> to, to samo co <tt>!if $d(<zmienna>)</tt>
* <tt>!ifndef <zmienna></tt> to, to samo co <tt>!if !$d(<zmienna>)</tt>
===Ekran===
Linia 523 ⟶ 595:
| rezultat
|-
| <pre>!error <komunikat></pre>
| polecenie, po natrafieniu na które MAKE kończy działanie i wyświetla na ekranie rezultat...
| <tt>Fatal makefile
|-
| <pre>!message <komunikat></pre>
| jeśli MAKE natrafi na to polecenie, wyświetla na ekranie rezultat...
| <tt><komunikat></tt>
|}
==MAKE w praktyce==
Teraz pora na wzbogacenie naszego makefile'a o dyrektywy i tym samym doprowadzenie skryptu do ostatecznej wersji. Przeanalizuj ten kod, a na pewno rozjaśni Ci się w głowie, o czym
.\asm <-- ewentualne wstawki asmowe (*.asm)
Linia 539 ⟶ 611:
Teraz możesz przejść do analizy.
'''c:\Hello\HelloProject.txt:'''
#----------------------------
Linia 565 ⟶ 637:
'''c:\Hello\obj\makefile.mak:'''
DIR = c:\Hello #nie wstawiaj na końcu '\'
Linia 626 ⟶ 698:
# implementacja (<tt>makefile.mak</tt>) - część, w której zawarte są same komendy budowy projektu, ten segment jest tworzony tylko raz podczas pisania makefile'a i od tego czasu raczej nie powinieneś go ruszać;
Tak naprawdę skrypt ten jest na tyle uniwersalny, że możesz używać go w wielu projektach (byle była zachowana odpowiednia struktura katalogów). Do makefile'a dodałem zasadę kompilującą w wstawki assemblerowe. Program TASM32, który jest kompilatorem assemblera niestety nie należy
|