Problema con il Makefile nella directory di primo livello, le fonti nelle sottodirectory

StackOverflow https://stackoverflow.com/questions/1319175

  •  19-09-2019
  •  | 
  •  

Domanda

Ho una directory chiamata project.

Contiene due sotto-directory chiamate client e server, e un makefile chiamato Makefile.

file di origine

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'uscita client/client.c suo eseguibile nella directory client/
  • Con make svr, la compilazione e l'uscita server/server.c suo eseguibile nella directory server/.
  • E con make, compile bothserver / server.candclient / 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?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top