|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Oct 2009
Messaggi: 157
|
[Makefile] Compilazione modulare su directory diverse
Salve a tutti
Premetto che conosco bene come si usa qmake, ma vorrei capire anche i makefile poichè vorrei metterci le mani sopra. Il problema è il seguente: Devo compilare un programma su diversi moduli (in questo esempio sono main.c e util.c) i quali sorgenti sono ubicati in una cartella src. La situazione della directory è questa: Programma |__src | |_main.c | |_util.c | |_makefile2 | |__include | |_util.h | |__bin | |_makefile Il makefile è sulla prima directory, e chiama il makefile2 in src per compilare util.c e main.c. E qui viè il problema del secolo: util.o e main.o mi vengono generati nella direcotry principale (sopra l'ho chiamata programma) dove è presente il primo makefile. Anche se dovessi usare un solo makefile, come faccio a fargli capire che i file oggetto (util.o e main.o) devono andare in src e non nella directory dove parte il makefile? Infati l'errore generato è: gcc: error: src/main.o: File o directory non esistente gcc: error: src/util.o: File o directory non esistente Voi come scrivereste un makefile in una situazione del genere? (non che una normale situazione dove ogni cosa trova il suo posto) Posto i due Makefile Makefile Codice:
CC = gcc SOURCE_PATH = src/ INCLUDE_PATH = include/ INCLUDE = -I$(INCLUDE_PATH) OBJS = $(SOURCE_PATH)main.o $(SOURCE_PATH)util.o BIN_PATH = bin/ BIN_NAME = somma CC_BIN = -o $(BIN_PATH)$(BIN_NAME) DEBUG = -g CFLAGS = -Wall -c $(BIN_PATH)$(BIN_NAME): $(OBJS) $(CC) $(INCLUDE) $(DEBUG) $(OBJS) $(CC_BIN) #Genera util.o $(SOURCE_PATH)util.o: $(INCLUDE_PATH)util.h $(SOURCE_PATH)util.c $(MAKE) -f src/Makefile2 util.o #genera main.o $(SOURCE_PATH)main.o: $(SOURCE_PATH)main.c $(MAKE) -f src/Makefile2 main.o Codice:
CC = gcc INCLUDE_PATH = include INCLUDE = -I$(INCLUDE_PATH) SOURCE_PATH = src/ DEBUG = -g CFLAGS = -Wall -c #Genera util.o util.o: include/util.h src/util.c $(CC) $(INCLUDE) $(DEBUG) $(CFLAGS) $(SOURCE_PATH)util.c #genera main.o main.o: src/main.c $(CC) $(INCLUDE) $(DEBUG) $(CFLAGS) $(SOURCE_PATH)main.c |
|
|
|
|
|
#2 |
|
Member
Iscritto dal: Oct 2009
Messaggi: 157
|
up
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
vado a memoria:
il make lo esegui dalla cartella root per cui l'output finisce in quella cartella. specifica piuttosto il nome di file di output: [code] #Genera util.o src/util.o: include/util.h src/util.c $(CC) $(INCLUDE) $(DEBUG) $(CFLAGS) $(SOURCE_PATH)util.c -o src/util.o [code] Meglio ancora, sposta makefile2 in src/ e rinominalo semplicemente in Makefile, quindi chiamalo con un "make -C src" invece che make -f. La prassi in questi casi e' di non fare una regola per i singoli file nel makefile principale, ma semplicemente chiamare il make nelle sottocartelle. in altre parole nel makefile principale avresti solo una regola del tipo Codice:
src: make -C src
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
|
|
|
|
|
#4 |
|
Member
Iscritto dal: Oct 2009
Messaggi: 157
|
Ok, lo sto ricreando da capo perchè mi sono accorto di alcuni errori.
Devo ben capire quand'è che c'è bisogno di creare una macro e quand'è che se ne può fare a meno. Ad esempio stavo creando macro per ogni file sorgente .c ed ogni file oggetto .o, ma mi sono ben presto accorto dell'inutilità di ciò, e che il cmake quando crea dei makefile non usa flags per path e nomi di file. Una cosa: Il binario finale, per correttezza, andrebbe creato nel makefile di root o nel makefile in src/ ? |
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
Ci sono le cosidette regole implicite (http://www.gnu.org/software/make/man...Implicit-Rules) che funzionano in base ad un pattern, ad esempio come generare un file .o partendo da un file .cpp. Queste sono solitamente predefinite ma le puoi customizzare. Ad esempio per il file C++ esiste una regola implicita (predefinita) come la seguente: Codice:
%.o : %.cpp $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c Per customizzarla puoi procedere in due modi: ridefinisci le variabili, oppure la riscrivi. Generalmente e' piu' pratica la prima Questo vuol dire che puoi avere un makefile del tipo Codice:
CXXFLAGS=-O3 -march=native ... my-program: a.o b.o c.o d.o $(CXX) $(CXXFLAGS) $(LDFLAGS) $(CPPFLAGS) -o $@
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
dipende. Se il makefile in src/ ha tutti gli elementi per creare il binario, crealo la (diventa piu' comodo spostare/rinominare la cartella)
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
|
|
|
|
|
#7 |
|
Member
Iscritto dal: Oct 2009
Messaggi: 157
|
Le regole implicite devo ben capirle ancora.
Per quanto riguarda il mio esempio, ora so risolverlo così: root_folder/makefile: Codice:
CC = gcc DEBUG = -g OBJ_FLAG = -c WARNING = -Wall LIBS = CFLAGS = -O1 BINARY_NAME = bin/somma BINARY_BUILD = -o $(BINARY_NAME) SOURCE_PATH = src/ INCLUDE_PATH = include/ $(BINARY_NAME): $(SOURCE_PATH)util.o $(SOURCE_PATH)main.o $(CC) $(DEBUG) $(WARNING) $(CFLAGS) $(SOURCE_PATH)util.o $(SOURCE_PATH)main.o $(BINARY_BUILD) $(SOURCE_PATH)util.o: $(SOURCE_PATH)util.c $(INCLUDE_PATH)util.h make -C $(SOURCE_PATH) util.o $(SOURCE_PATH)main.o: $(SOURCE_PATH)main.c make -C $(SOURCE_PATH) main.o /root_folder/src/makefile: Codice:
include ../Makefile INCLUDE = ../include/ INCLUDE_FLAGS = -I$(INCLUDE) util.o: util.c $(INCLUDE)util.h $(CC) $(DEBUG) $(WARNING) $(CFLAGS) $(INCLUDE_FLAGS) $(OBJ_FLAG) util.c main.o: main.c $(CC) $(DEBUG) $(WARNING) $(CFLAGS) $(INCLUDE_FLAGS) $(OBJ_FLAG) main.c Le regole implicite mi sembra di aver capito che ti semplificano nel scrivere tutti i sorgenti uno ad uno. Ma se io ho un solo file .c che dipende da un file .h come "glielo spiego"?? Esempio: Codice:
%.o : %.cpp $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c Ultima modifica di Emalele1688 : 30-03-2012 alle 17:06. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 21:36.




















