<target> : <dependencies> <action1> <action2>...Ο κανονας οριζει τρια πραγματα. Το ονομα του αρχειου που πρεπει να ανανεωθει (στοχος - target), ποτε πρεπει να ανανεωθει (εξαρτησεις - dependencies) και πως θα ανανεωθει (ενεργειες - actions). Οι εξαρτησεις (dependencies) ειναι ονοματα αρχειων απο τα οποια εξαρταται ο στοχος (target) και μπορει να ειναι και ονοματα στοχων απο αλλους κανονες. Το make θα εκτελεσει τις ενεργειες (actions) με τη σειρα που οριζονται οταν καποιο απο τα αρχεια που αναφερονται στις εξαρτησεις εχει νεοτερη ημερομηνια απο το στοχο. Οι ενεργειες (actions) μπορει να ειναι οποιεσδηποτε εντολες και πρεπει υποχρεωτικα να ξεκινουν με ΤΑΒ. Η παραλειψη του αρχικου TAB σε καθε γραμμη ενεργειας ειναι και το συνηθεστερο λαθος στην κατασκευη του Makefile.
Εστω για παραδειγμα οτι σε μια εργασια του μαθηματος εχουμε τα αρχεια list.C
και list.h . Ενας κανονας για να δημιουργουμε το list.o ειναι:
list.o : list.C list.h g++ -c list.CΑν το εκτελεσιμο της εργασιας ονομαζεται test_data_structures και περιεχει ενα επιπλεον αρχειο main.C, τοτε για να το δημιουργησουμε αρκει να προσθεσουμε στην αρχη του αρχειου Makefile τους κανονες:
test_data_structures : list.o main.o g++ -o test_data_structures list.o main.o main.o : main.C g++ -c main.CΕτσι οταν δινουμε την εντολη make, θα μεταγλωττιζεται μονο οποιο αρχειο ειναι νεοτερο απο το εκτελεσιμο.
Σχολια
Τα σχολια στο Makefile εισαγονται με τη χρηση του
χαρακτηρα #: ο χαρακτηρας # και ολοι οι χαρακτηρες μεχρι το
τελος της γραμμης αγνοουνται. Τα σχολια μπορουν να εμφανιζονται οπουδηποτε στο
Makefile. Παραδειγμα:
LEDA_LIBS = -lL -lm # Link with the LEDA library of basic data types
clean : rm -f *.o test_data_structures coreΤετοιους κανονες τους καλουμε δινοντας το ονομα του στοχου σαν ορισμα στη γραμμη εντολων αμεσως μετα το make, π.χ. :
make cleanΤο make δεχεται διαφορα ορισματα στη γραμμη εντολων. Το πιο συνηθισμενο ειναι να δοθει σαν ορισμα το ονομα ενος στοχου (οπως το make clean που εχουμε δει παραπανω). Αν δεν υπαρχει ονομα στοχου στη γραμμη εντολων το make επεξεργαζεται τον πρωτο στοχο του Makefile. Αλλο ενα συνηθες ορισμα ειναι το -f <Makefile> που λεει στο make να χρησιμοποιησει καποιο αλλο αρχειο σαν Makefile. Παραδειγμα:
make -f Makefile2
<ονομα_μεταβλητης> = <κειμενο>Αν υπαρχουν κενα στην αρχη του κειμενου αγνοουνται. Οι μεταβλητες μπορουν να χρησιμοποιηθουν οπουδηποτε (ακομη και για τον ορισμο αλλων μεταβλητων). Στην τιμη μιας μεταβλητης αναφερομαστε με τη συνταξη:
$(<ονομα>) η ${<ονομα>}
Εστω για παραδειγμα οτι εχουμε την εργασια που περιγραψαμε παραπανω και
εστω οτι θελουμε να καλεσουμε τον μεταγλωττιστη με την επιλογη
-g (για
debugging). Μπορουμε στην αρχη του Makefile να ορισουμε : CXXFLAGS = -gκαι να τροποποιησουμε τους κανονες ως εξης:
test_data_structures : list.o main.o
g++ -o $(CXXFLAGS) test_data_structures list.o main.o
list.o : list.C list.h
g++ -c ${CXXFLAGS} list.C
main.o : main.C
g++ -c $(CXXFLAGS) main.C
Ετσι αν θελουμε να αλλαξουμε τα ορισματα του compiler π.χ. απο
-g
σε -O (για βελτιστοποιηση), αρκει να αλλαξουμε μονο τον ορισμο της
CXXFLAGS σε : CXXFLAGS = -OΗ ιδια τακτικη μπορει να χρησιμοποιηθει και για αλλα ορισματα, π.χ. βιβλιοθηκες. Για παραδειγμα αν για την παραπανω εργασια πρεπει να χρησιμοποιησουμε και τη βιβλιοθηκη βασικων τυπων της LEDA θα προσθεσουμε στο Makefile :
LEDA_LIBS = -lL -lmκαι θα τροποποιησουμε τον κανονα για το test_data_structures ως εξης:
test_data_structures : list.o main.o g++ -o $(CFLAGS) test_data_structures list.o main.o $(LEDA_LIBS)
$(CC) -c $(CPPFLAGS) $(CFLAGS)οπου η μεταβλητη CC εχει προεπιλεγμενη τιμη gcc, ενω οι μεταβλητες CPPFLAGS και CXXFLAGS θεωρουνται οτι εχουν κενη προεπιλεγμενη τιμη.
Απο την αλλη πλευρα, θα μπορουσε το ιδιο αρχειο foo.o να παραγεται απο ενα αρχειο foo.C η foo.cc (C++ αρχειο) μεσω του μεταγλωττιστη g++ (για κωδικα C++) με τη χρηση του κανονα:
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS)οπου η μεταβλητη CXX εχει προεπιλεγμενη τιμη g++, ενω οι μεταβλητες CPPFLAGS και CXXFLAGS θεωρουνται οτι εχουν κενη προεπιλεγμενη τιμη. (Υπαρχουν τετοιοι κανονες για τους περισσοτερους τυπους αρχειων).
Για να χρησιμοποιησουμε εναν τετοιο κανονα πρεπει ειτε να ορισουμε εναν κανονα χωρις ενεργειες (actions) η να μην ορισουμε κανενα κανονα για καποιο αρχειο. Για παραδειγμα για την εργασια που εχουμε προαναφερει ο κανονας που δημιουργει το main.o μπορει να παραλειφθει. Οταν το make χρειαστει το main.o θα ελεγξει αν υπαρχει το main.C και αν ναι, θα χρησιμοποιησει τον αντιστοιχο ενσωματωμενο κανονα για C++. Οταν θελουμε να ορισουμε επιπλεον εξαρτησεις (dependecies), τοτε οριζουμε ενα σχετικο κανονα αλλα δεν οριζουμε ενεργειες (actions). Στην παραπανω εργασια ο κανονας για το list.o μπορει να τροποποιηθει ως εξης:
list.o : list.hΗ συμπεριφορα των ενσωματωμενων κανονων μπορει να τροποποιηθει με το να δωσουμε διαφορετικες τιμες στις μεταβλητες που χρησιμοποιουν. Ετσι αν θελουμε, μπορουμε να προσθεσουμε στo Makefile :
CXXFLAGS = -gγια να τροποποιησουμε τη συμπεριφορα του ενσωματωμενου κανονα. (Φυσικα δεν ειναι αναγκαιο να χρησιμοποιησουμε τους ενσωματωμενους κανονες). Στο τελος του κειμενου υπαρχει ενα ολοκληρωμενο παραδειγμα.
my_lib : list.o stack.o ar crv my_lib.a list.o stack.o ranlib my_lib.a(Τα ορισματα της ar σημαινουν τα εξης : c : να δημιουργησει - create - το αρχειο my_lib.a, να προσθεσει - add with replacement - τα αρχεια list.o και stack.o και να αναφερει αναλυτικα - verbose - τις ενεργειες καθως εκτελειται). Για το stack.o δε χρειαζεται να ορισουμε τιποτα αφου θα δημιουργηθει απο το stack.C με τη χρηση ενσωματωμενου κανονα. Για να δημιουργησουμε τη βιβλιοθηκη πρεπει να δωσουμε στη γραμμη εντολων το ονομα του σχετικου στοχου σαν ορισμα, δηλαδη :
make my_libΑκολουθει ενα ολοκληρωμενο παραδειγμα.
CXX = /usr/local/gcc2.95/bin/g++ # use of g++-2.95 compiler OBJS = main.o list.o stack.o # project files LIB_OBJS = list.o stack.o # my_lib files LEDA_PATH = /usr/local/leda # directory where LEDA libraries are stored LEDA_LIBS = -lL -lm # Link with the LEDA library of basic data types CXXFLAGS = -g # for debugging; can be changed or omitted later CPPFLAGS = -I$(LEDA_PATH) all : test_data_structures my_lib # rule to create everything test_data_structures : $(OBJS) # rule to create executable $(CXX) -o test_data_structures $(OBJS) -L$(LEDA_PATH) $(LEDA_LIBS) my_lib : $(LIB_OBJS) # rule to create my_lib.a from list.o and stack.o ar crv my_lib.a list.o stack.o ranlib my_lib.a # we write this rule only to state the dependency of list.o from list.h list.o : list.h #rules for main.o and stack.o are not necessary clean : # rule to delete unnecessary files rm -f *.o test_data_structures core
Επιστροφη στη σελιδα του εργαστηριου.