2009-08-23 9 views
0

Ich habe ein Verzeichnis mit dem Namen project.Problem mit Makefile im obersten Verzeichnis, Quellen in Unterverzeichnissen

Es enthält zwei Unterverzeichnisse mit den Namen client und server und ein Makefile namens Makefile.

client und server haben Quelldateien genannt client.c bzw. server.c.

Ich habe keine separaten Makefiles in den Unterverzeichnissen für Quellen, die zu diesem Verzeichnis gehören. Alle Builds werden vom einzelnen Makefile erledigt. Der Makefile Code ist

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 

Ich lief nun make cnt und es

antwortete
cc -W -Wall -g -pthread ./client/client.c -o ./client/client.out 

Das Problem ist, alle nachfolgenden make cnt Befehle erneut kompilieren zu beenden und den obigen Text ausgibt, obwohl ich nicht bin zu ändern ./client/client.c

Ich stecke hier fest. Ich weiß nicht, was ich machen soll.

Was ich tun möchte, ist:

  • Mit make cnt, kompilieren client/client.c und Ausgang seine ausführbare Datei in dem Verzeichnis client/
  • Mit make svr, kompilieren server/server.c und Ausgang seine ausführbare Datei in server/ Verzeichnis.
  • Und mit make, compile both Server/server.c and Client/client.c` und geben ihre ausführbaren Dateien in den entsprechenden Verzeichnissen

Da ich aber keine ausführbaren Dateien svr und `cnt das Problem, das ich bin nicht über genannt Haben ist nicht gelöst.

Wenn ich das Ziel ./client/client.out statt cnt ändern und rufen Sie dann make client/client.out dann wäre es in Ordnung sein, genau das, was ich brauche, aber ich will nicht lange Befehl make client/client.out in meinem Terminal

Die Abhilfe muss ich eingeben erhalten ist wie folgt

cnt: $(CLI) 
     cc $(FLAGS) $(CLI) -o cnt 
     cp cnt ./client/client.out 

Aber nicht ganz zufrieden damit. Ich bin sicher, was ich tun möchte, ist wirklich einfach und es sollte ein bequemer Weg sein, es zu tun. Wie kann ich das tun?

Antwort

2

Lassen Sie uns formulieren, was Sie wollen. Sie möchten, dass das Ziel mit dem Namen `cnt 'nicht neu erstellt wird. Das Makefile, das Sie geschrieben haben, weiß nichts über die Datei client.out, da sie nur in Shell-Befehlen innerhalb einer Regel angezeigt wird. Make Programm liest keine Informationen aus Shell-Befehlen, es führt nur Ersetzungen durch und führt sie aus.

Wenn Makefile wählt die Ziele wird es neu erstellen (`cnt 'ist eines dieser Ziele), vergleicht es Aktualisierungszeit eines Ziels Datei mit Aktualisierungszeit seiner Voraussetzungen.Da zu dem Zeitpunkt, an dem Sie `make cnt '' ausführen, die Datei mit dem Namen cnt abwesend ist, wird das so benannte Ziel als Aktualisierung erachtet. So Befehle ausgeführt werden und keine Datei mit dem Namen CNT, so nächsten Lauf führen wird es auch für die Aktualisierung berücksichtigen.

Es gibt zwei mögliche Lösungen. Die erste besteht darin, den Zielen dieselben Namen wie der Datei zu geben, die die Regelbefehle generieren. So könnten Sie am Ende so enden:

client/client.out: $(CLI) 
    cc $(FLAGS) $(CLI) -o ./client/client.out 

Ihre Frage hat übrigens nichts mit Verzeichnissen zu tun. Sie sollten auch über die Anweisung .PHONY lesen, verwenden Sie $ (CC) anstelle von cc und lesen Sie gnu make manual, was sehr hilfreich sein könnte.

+0

Danke für die Erklärung. – nagre

0

Try this:

 
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 [email protected] 

Jetzt können Sie Make srv, Make cnt oder nur machen.
Es gibt etwas anspruchsvollere Dinge, die Sie tun können, aber das sollte für jetzt genug sein.

+0

kann ich nicht folgen. Ich habe nicht viel Erfahrung beim Erstellen von Makefiles, also schätze ich, dass ich das Handbuch irgendwann später lesen werde. Im Moment werde ich mit dem Kopieren cnt in mein Client-Verzeichnis fortfahren. Danke, – nagre

+0

Alles klar, aber Sie werden client.out jedes Mal neu erstellen, ob Sie wirklich brauchen oder nicht. – Beta