ΟΔΗΓΟΣ ΓΙΑ ΤΟ ΕΡΓΑΛΕΙΟ ΜΑΚΕ

...ασύγχρονα μαθήματα γλώσσας C

ΟΔΗΓΟΣ ΓΙΑ ΤΟ ΕΡΓΑΛΕΙΟ ΜΑΚΕ

Δημοσίευσηαπό linuxs » 13 Σεπ 2011, 06:34

Οδηγός για το εργαλείο
make


Έχει γίνει ένα Update στο παρακάτω



Βασικές πληροφορίες για το make...
Τί είναι το make και γιατί το χρησιμοποιούμε? Το make είναι ένα εργαλείο που, το χρησιμοποιούμε όταν έχουμε να δουλέψουμε με πολλά αρχεία! Το make ελέγχει ποια αρχεία έχουν αλλάξει και τα μεταγλωττίζει αυτόματα όταν χρειάζεται. Με την λέξη "αυτόματα" εννοώ οτι θα πρέπει να τρέξετε μια μόνο εντολή και όχι ν εντολές σε περίπτωση που δεν το χρησιμοποιούσαμε. Εντελώς θεωρητικά θα αναφέρω ένα παράδειγμα. Σε περίπτωση που είχατε 10 αρχεία και 2 βιλβιοθήκες για να βγάλετε ένα εκτελέσιμο αρχείο θα πρέπει να τρέχατε και σαν την παρακάτω εντολή:
Κώδικας: Επιλογή όλων
gcc file1.c file2.c file3.c ... file10.c -o executable_program

Τι θα είχαμε καταφέρει με αυτόν τον τρόπο? Να κάνουμε compile τα 10 αρχεία κατάληξης .c και να δημιουργήσουμε ένα εκτελέσιμο αρχείο executable_prog που τρέχοντας το εκτελούνται και τα 10 αρχεία της C! Ένα σημαντικό πρόβλημα είναι οτι εάν για παράδειγμα αλλάξουμε μια γραμμή στο 3ο αρχείο για να ανανεώσουμε το εκτελέσιμο μας θα πρέπει να κάνουμε compile ξανά τα 10 αρχεία και προφανώς αυτό δεν το θέλουμε γιατί στην πραγματικότητα μπορεί να είναι 100 αρχεία(κοστίζει σε χρόνο). Αυτό που θέλουμε να κάνουμε τώρα είναι το ίδιο αλλα χρησιμοποιώντας το make. Θα σας ήταν χρήσιμο αν εκτελέσετε το παρακάτω παράδειγμα πρώτα.

Για να μπορέσετε να δείτε την διαφορά εκτελέστε το παράδειγμα αυτό. Έχουμε 4 αρχειάκια και θέλουμε να κάνουμε ένα εκτελέσιμο! Για λόγο χρόνου σας τα έχω έτοιμα, απλά κάντε copy/paste και συνεχίστε. Προσοχή!!! Σε κάθε αρχείο δώστε το όνομα που βλέπετε στο 1ο σχόλιο!

Ονομάστε το παρακάτω αρχείο factorial.cpp
Κώδικας: Επιλογή όλων

#include "functions.h"

int factorial(int n){
if(n!=1){
return(n * factorial(n-1));
}
else return 1;
}


Ονομάστε το παρακάτω αρχείο functions.h
Κώδικας: Επιλογή όλων

void print_hello();
int factorial(int n);


Ονομάστε το παρακάτω αρχείο hello.cpp
Κώδικας: Επιλογή όλων

#include <iostream>
#include "functions.h"

using namespace std;

void print_hello(){
cout << "Hello World!";
}

Ονομάστε το παρακάτω αρχείο main.cpp
Κώδικας: Επιλογή όλων

#include <iostream>
#include "functions.h"

using namespace std;

int main(){
print_hello();
cout << endl;
cout << "The factorial of 5 is " << factorial(5) << endl;
return 0;
}


Προτείνω να τα βάλετε σε έναν φάκελο και να συνεχίσετε τρέχοντας την εντολή:
Κώδικας: Επιλογή όλων
g++ hello.cpp factorial.cpp main.cpp -o hello

θα δημιουργηθεί ένα εκτελέσιμο ονόματι hello και μπορείτε να το τρέξετε εκτελώντας το παρακάτω,
Κώδικας: Επιλογή όλων
./hello


Τι είναι τα Makefiles...
Αν τρέξετε την εντολή
Κώδικας: Επιλογή όλων
make
δεν νομίζω να κάνει κάτι! :lol: :lol: :lol: Φυσικά ψάχνει να βρεί το makefile το οποίο το παραλείψαμε ως όρισμα! Απλά θα το αναφέρω αυτό και κρατήστε το στο background! Για να τρέξετε ένα makefile δικό σας θα πρέπει να εκτελέσετε κάτι σαν;
Κώδικας: Επιλογή όλων
make -f my_make_file

έγραψε:Το όρισμα -f μας επιτρέπει να τρέξουμε το δικό μας makefile. Μπορείτε να κάνετε πολλά περισσότερα με το make! Δείτε man make. ;)



Κανόνες...
Για να γράψετε ένα makefile θα πρέπει να χρησιμοποιήσετε κάποια συγκεκριμενη δομή και κάποιους κανόνες. Για να καταλάβετε τι εννοώ θα τρέξετε πολύ απλά και πρόχειρα το πρώτο σας makefile! ;) Ο τρόπος σύνταξης των κανόνων στο makefile(απαραίτητο για να συνεχίσετε) είναι:
Κώδικας: Επιλογή όλων
<target> : <dependencies>
<action1>
<action2>...

o κανονας οριζει τρια πραγματα.
  • το ονομα του αρχειου που πρεπει να ανανεωθει (στοχος - target),
  • ποτε πρεπει να ανανεωθει (εξαρτησεις - dependencies) και
  • πως θα ανανεωθει (ενεργειες - actions).

Οι εξαρτήσεις (dependencies) ειναι ονόματα αρχείων απο τα οποία εξαρτάται ο στόχος (target) και μπορεί να είναι και ονόματα στόχων απο άλλους κανόνες. Το make θα εκτελέσει τις ενέργειες (actions) με τη σειρά που ορίζονται όταν κάποιο απο τα αρχεία που αναφέρονται στις εξαρτήσεις εχει νεότερη ημερομηνία από το στόχο. Οι ενέργειες (actions) μπορεί να είναι ότι εντολές θέλετε και πρέπει υποχρεωτικά να ξεκινούν με ΤΑΒ. Η παράλειψη του αρχικού TAB σε κάθε γραμμή ενέργειας είναι και το συνηθέστερο λάθος στην κατασκευή του Makefile. Στην πραγματικότητα η βασική λειτουργία του make είναι ΠΟΛΥ απλή αρκεί να καταλάβετε τι γίνεται όταν το τρέχεις γι' αυτό θα δούμε παρακάτω ένα παράδειγμα εκτέλεσης.
Όταν θα τρέξουμε το makefile αυτό που θα γίνει είναι να πάει να βρεί το target(εξού και το όνομα :lol: ), μετά τι πρέπει να γίνει? Για να "εκτελεστεί" το target θα πρέπει να εκτελεστούν τα dependencies(εξού και το όνομα :lol: :lol: ). Επίσης προσθέστε ότι όταν υπάρχει ένα τουλάχιστον dependencie θα υπάρχει και μια actiion για αυτό(συνήθως κάποια εντολή που θα εκτελεί το πρόγραμμα πχ. gcc file1.c).

Θυμάστε τον φάκελο που είχαμε φτιάξει στην αρχή? ;) Αποθηκεύστε εκεί με όνομα my_make_file ακόμη ένα αρχείο που σας το έχω έτοιμο και είναι το πρώτο σας makefile
Κώδικας: Επιλογή όλων

all:
g++ main.cpp hello.cpp factorial.cpp -o hello


Τρέχοντας το make αυτό που θα γίνει είναι να "τρέξει" το all και αυτό που εκτελείται στον στόχο all είναι g++ main.cpp hello.cpp factorial.cpp -o hello.
Οπότε τρέξτε το δικό σας makefile εκτελώντας την εντολή;
Κώδικας: Επιλογή όλων
make -f my_make_file

τώρα τρέξτε το αρχείο hello κλασικά με
Κώδικας: Επιλογή όλων
./hello


Ολοκληρωμένοι targets με dependencies...
Αυτό που κάναμε πριν ήταν το πιο απλό παράδειγμα για το make και συνήθως δεν λειτουργεί έτσι. Γιατί δεν έχετε χρησιμοποιήσει ακόμη τα dependencies! Και τι είναι αυτά? Γιατί να τα χρησιμοποιήσετε? Γιατί, χωρίς αυτά ΠΑΛΙ κάνετε compile 3 αρχεία στην συγκεκριμένη περίπτωση και ν αρχεία γενικά. Εδώ μπαίνουν τα dependencies και ουσιαστικά βοηθούν ώστε να μην κάνουμε compile πολλά αρχεία συγχρόνως! Σε όποιο έγινε αλλαγή σε αυτό θα γίνει compile και θα δείτε πως. Πάλι στον ιδιο φάκελο που είμαστε σβήστε τα περιττά αρχεία που δημιουργήθηκαν απο το προηγούμενο make (λογικά τα εκτελέσιμα μόνο) και κρατήστε τα 3 αρχεία κατάληξης .c και την βιβλιοθήκη .h. Το νέο αρχείο make είναι έτοιμο και είναι το:
Κώδικας: Επιλογή όλων

all: hello clean

hello: main.o factorial.o hello.o
g++ main.o factorial.o hello.o -o hello

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

factorial.o: factorial.cpp
g++ -c factorial.cpp

hello.o: hello.cpp
g++ -c hello.cpp

clean:
rm -rf *.o

ρίξτε μια ματιά και θα δείτε οτι είναι εύκολο στην κατανόηση! Ο αρχικός στόχος είναι ο all, για να γίνει αυτός θα πρέπει αν γίνουν οι στόχοι hello και clean. Για να γίνει ο hello χρειάζονται άλλοι 3 στόχοι σε καθένα απο τους οποίους χρειάζεται να γίνει ένα αρχείο compile(έτσι θα γίνεται compile ένα αρχείο κάθε φορά και κάθε φορά που γίνεται το make δεν θα κάνουμε και τα 3 αρχεία compile). Για να γίνει ο clean στόχος δεν χρειάζεται κάτι οπότε απλα εκτελείται η εντολή που διαγράφει όλα τα .o(3) αρχεία που μας είναι περιττά στο τέλος. Δεν είναι απαραίτητο αυτό απλά για ομορφιά! ;)

Χρησιμοποιώντας μεταβλητές...
Στην αρχη καθε Makefile μπορουμε να ορισουμε μεταβλητες για να αποφευγουμε περιττες επαναληψεις και να το κανουμε πιο ευαναγνωστο. Οι ορισμοι των μεταβλητων ειναι της μορφης:
Κώδικας: Επιλογή όλων
<ονομα_μεταβλητης> = <κειμενο>

Αν υπαρχουν κενα στην αρχη του κειμενου αγνοουνται. Οι μεταβλητες μπορουν να χρησιμοποιηθουν οπουδηποτε (ακομη και για τον ορισμο αλλων μεταβλητων). Στην τιμη μιας μεταβλητης αναφερομαστε με τη συνταξη:
Κώδικας: Επιλογή όλων
$(<ονομα>) η ${<ονομα>}

Εστω για παραδειγμα οτι εχουμε την εργασια που περιγραψαμε παραπανω και εστω οτι θελουμε να καλεσουμε τον μεταγλωττιστη με την επιλογη -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)


Σύμφωνα με τα δυο παρακάτω link,

Έτοιμο παράδειγμα για χρήση...
Σε linux συστήματα χρησιμοποιείστε το παρακάτω κώδικα(δουλειά του migf1) και απλά αλλάξτε τα ονόματα των αρχείων με τα δικά σας,
Κώδικας: Επιλογή όλων
CC = gcc
CFLAGS = -Wall
OBJECTS = main.o ship.o ui.o ai.o

main: $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o main.exe

%.o : %.c
$(CC) $(CFLAGS) -c $<

clean:
rm -f main.exe main.o ship.o ui.o ai.o


Περισσότερες πληροφορίες για το make: http://www.gnu.org/software/make/manual/html_node/index.html
Τελευταία επεξεργασία από linuxs και 22 Φεβ 2012, 07:24, έχει επεξεργασθεί 3 φορά/ες συνολικά
Αιτία: Update post
Αν το πρόβλημά μας επιλυθεί. Επιλέγουμε το θέμα που βοήθησε στην επίλυση και πατάμε το κουμπάκι Εικόνα.
Γνώσεις ⇛ Linux: Μέτριο┃Προγραμματισμός: C┃Αγγλικά: Καλά
Λειτουργικό ⇛ Linux Ubuntu 10.4 LTS
Προδιαγραφές ⇛ Intel Pentium @T4500 2.3GHz│ 512GB VRAM│ 500 HDD│ ATI RADEON HD545v 512 MB │ Screen: 15.6''
Άβαταρ μέλους
linuxs
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 1060
Εγγραφή: 02 Ιούλ 2010, 13:19
Τοποθεσία: GR
IRC: linuxs
Εκτύπωση

Re: Οδηγός για το εργαλείο make

Δημοσίευσηαπό migf1 » 07 Οκτ 2011, 07:22

Για C, μπορείτε να σώσετε αυτό εδώ το makefile...

Κώδικας: Επιλογή όλων

CC = gcc
CFLAGS = -Wall
OBJECTS = main.o ship.o ui.o ai.o

main: $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o main.exe

%.o : %.c
$(CC) $(CFLAGS) -c $<

clean:
rm -f main.exe main.o ship.o ui.o ai.o


για να το έχετε σαν σκελετό και απλά να αντικαθιστάτε το ονόματα των δικών σας αρχείων.
Τελευταία επεξεργασία από linuxs και 22 Φεβ 2012, 06:44, έχει επεξεργασθεί 1 φορά/ες συνολικά
Αιτία: Διόρθωση(σβήσιμο του .exe για linux συστήματα)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Οδηγός για το εργαλείο make

Δημοσίευσηαπό Star_Light » 08 Οκτ 2011, 16:42

ΜΠΡΑΒΟ συνάδελφε λίνουξς , ωραιος και αρκετα χρησιμος ο οδηγος σου.

migf1 στο παραπανω σκριπτ γιατι μπαινει η καταληξη .exe μιας και στο Unix
δεν χρειαζεται και δεν εχει ενα εκτελεσιμο την κατάληξη που έχει στα Windows για παραδειγμα.
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Οδηγός για το εργαλείο make

Δημοσίευσηαπό linuxs » 08 Οκτ 2011, 16:49

thx! αυτή την απορία της είχα και εγώ... :/
Αν το πρόβλημά μας επιλυθεί. Επιλέγουμε το θέμα που βοήθησε στην επίλυση και πατάμε το κουμπάκι Εικόνα.
Γνώσεις ⇛ Linux: Μέτριο┃Προγραμματισμός: C┃Αγγλικά: Καλά
Λειτουργικό ⇛ Linux Ubuntu 10.4 LTS
Προδιαγραφές ⇛ Intel Pentium @T4500 2.3GHz│ 512GB VRAM│ 500 HDD│ ATI RADEON HD545v 512 MB │ Screen: 15.6''
Άβαταρ μέλους
linuxs
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 1060
Εγγραφή: 02 Ιούλ 2010, 13:19
Τοποθεσία: GR
IRC: linuxs
Εκτύπωση

Re: Οδηγός για το εργαλείο make

Δημοσίευσηαπό migf1 » 10 Οκτ 2011, 13:20

Star_Light έγραψε:
...
migf1 στο παραπανω σκριπτ γιατι μπαινει η καταληξη .exe μιας και στο Unix
δεν χρειαζεται και δεν εχει ενα εκτελεσιμο την κατάληξη που έχει στα Windows για παραδειγμα.

Γιατί σας το έκανα copy & paste από το παιχνίδι της Ναυμαχίας που το αναπτύσσω σε Windows :lol: (με βολεύει πολύ καλύτερα στα Windows η ανάπτυξη των προγραμμάτων σε C).

Οπότε δεν τη χρειάζεστε την κατάληξη .exe, απλά σβήστε την ;)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Οδηγός για το εργαλείο make

Δημοσίευσηαπό linuxs » 10 Οκτ 2011, 13:52

Ε ρε μανία με αυτή τη Ναυμαχία!!! Όπου και να πάω όλοι το παίζουν. Πρέπει αν βγάλω κάποια στρατιγική :P :lol: :lol: :lol:
Αν το πρόβλημά μας επιλυθεί. Επιλέγουμε το θέμα που βοήθησε στην επίλυση και πατάμε το κουμπάκι Εικόνα.
Γνώσεις ⇛ Linux: Μέτριο┃Προγραμματισμός: C┃Αγγλικά: Καλά
Λειτουργικό ⇛ Linux Ubuntu 10.4 LTS
Προδιαγραφές ⇛ Intel Pentium @T4500 2.3GHz│ 512GB VRAM│ 500 HDD│ ATI RADEON HD545v 512 MB │ Screen: 15.6''
Άβαταρ μέλους
linuxs
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 1060
Εγγραφή: 02 Ιούλ 2010, 13:19
Τοποθεσία: GR
IRC: linuxs
Εκτύπωση


Επιστροφή στο Μαθήματα C