Problema con il Makefile nella directory di primo livello, le fonti nelle sottodirectory
-
19-09-2019 - |
Domanda
Ho una directory chiamata project
.
Contiene due sotto-directory chiamate client
e server
, e un makefile chiamato Makefile
.
client
e server
hanno ottenuto chiamati rispettivamente client.c
e server.c
,.
Non ho alcun makefile separati in sottodirectory di fonti appartenenti a tale directory. Tutti generazioni sono fatto dal singolo makefile. Il codice è Makefile
FLAGS = -W -Wall -g -pthread
SERV =./server/server.c #My server code
CLI =./client/client.c #My client code
build:svr cnt
svr: $(SERV)
cc $(FLAGS) $(SERV) -o ./server/server.out
cnt: $(CLI)
cc $(FLAGS) $(CLI) -o ./client/client.out
Ora mi corse make cnt
e rispose
cc -W -Wall -g -pthread ./client/client.c -o ./client/client.out
Il problema è che tutte le successive comandi make cnt
finiscono per compilarlo di nuovo e in uscita il testo di cui sopra, anche se io non sto cambiando ./client/client.c
Sono bloccato qui. Non so cosa fare.
Quello che voglio fare è:
- Con
make cnt
, la compilazione e l'uscitaclient/client.c
suo eseguibile nella directoryclient/
- Con
make svr
, la compilazione e l'uscitaserver/server.c
suo eseguibile nella directoryserver/
. - E con
make, compile both
server / server.cand
client / client.c` ed uscita i loro eseguibili nelle rispettive directory
Ma dal momento che non ho alcun eseguibili denominati svr
e `cnt il problema che sto avendo non è risolto.
Se cambio l'obiettivo di ./client/client.out
invece di cnt
e quindi chiamare make client/client.out
allora sarebbe bene, esattamente quello che mi serve, ma non voglio per entrare lungo comando make client/client.out
nel mio terminale
La soluzione che ho ottenuto è la seguente
cnt: $(CLI)
cc $(FLAGS) $(CLI) -o cnt
cp cnt ./client/client.out
Ma non del tutto soddisfatto. Sono sicuro di quello che voglio fare è molto semplice e ci dovrebbe essere un modo conveniente intorno a farlo. Allora, come posso farlo?
Soluzione
Diamo a formulare ciò che si desidera. Si vuole bersaglio chiamato `CNT' di non essere ricostruito. Il makefile che hai scritto non sa nulla di file client.out, perché appare solo in comandi di shell all'interno di una regola. Fare programma non legge le informazioni dai comandi di shell, lo fa solo sostituzioni lì e li esegue.
Quando makefile sceglie gli obiettivi che si ricostruirà ( `CNT' è uno di questi obiettivi), si confronta il tempo di aggiornamento di un obiettivo file con il tempo di aggiornamento dei suoi prerequsites. Dal momento che al momento che si esegue `` make CNT '' il file denominato cnt è assente , il bersaglio chiamato così è considerato come richiede aggiornamento. Così comandi vengono eseguiti e producono nessun file chiamato cnt , così la prossima make run lo considererà per l'aggiornamento pure.
Ci sono due possibili soluzioni. Il primo è quello di dare obiettivi stessi nomi del file, che i comandi regola genereranno. Quindi, si potrebbe finire in questo modo:
client/client.out: $(CLI)
cc $(FLAGS) $(CLI) -o ./client/client.out
Il tuo questioin non ha nulla a che fare con le directory, tra l'altro. Si dovrebbe anche leggere su direttiva .PHONY, uso $ (CC) al posto di cc e leggere GNU make manuale, che potrebbe essere molto utile.
Altri suggerimenti
Prova questo:
SERVO =./server/server.out CLIO =./client/client.out .PHONY: srv cnt build build: svr cnt svr: $(SERVO) cnt: $(CLIO) $(SERVO) $(CLIO): %.out : %.c cc $(FLAGS) $^ -o $@
Ora è possibile rendere SRV , fare cnt , o semplicemente make .
Ci sono un po 'più sofisticati cose che potete fare, ma questo dovrebbe essere sufficiente per ora.