Makefile, Kompilieren und Verknüpfen
Ich habe eine Frage bezüglich der Zusammenstellung und Verknüpfung in der Datei Makefile (und vielleicht generell).
Ich habe einen server.c-Datei, die besteht aus dem Haupt-Programm, das eine main()
Funktion. server.c
umfasst rio.c. Ich habe ein Modul namens rio
die aus rio.c
und rio.h
. Es hat keine main()
Funktion.
Habe ich zwei Fragen, wie man eigentlich schreiben das Makefile, und der best practice für so eine Sache.
Q1: Wie schreibt man das Makefile
Habe ich Folgendes Makefile:
CC = gcc
CFLAGS = -Wall -Werror -Wmissing-prototypes
OBJS = server.o rio.o
all: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o sysstatd
server.o: server.c
$(CC) $(CFLAGS) -c server.c
rio.o: rio.c rio.h
$(CC) $(CFLAGS) -c rio.c
clean:
rm -f *~ *.o sysstatd
Ich bin mit der Verknüpfung Probleme mit diesem. Es sagt, dass ich mehrere Definitionen aller Funktionen in C. ich bin mir nicht sicher, wie das möglich ist, da server.c compiliert mit der -c
- flag, so ist eigentlich nichts verknüpft. Sie sollten wissen, dass einige Funktionen sind vorhanden, aber nicht eigentlich verknüpfen, bis die all
Regel kompiliert beiden Objekt-Dateien zusammen und erzeugt eine einzige Objekt-Datei, die alles miteinander verknüpft.
Was ist hier das Problem?
Q2: Best-practice -
Da habe ich ein Modul und dann eine weitere Datei enthält das Hauptprogramm, sollte ich kompilieren Sie das main-Programm server.c
, als ein separates Modul und kompilieren Sie dann beide zusammen in all
oder compile-server.c in allen und fügen Sie den rio.a-Modul da? Beachten Sie, dass diese noch produziert die gleiche Verknüpfung von problem, das ich schon oben also ich bin mir ziemlich sicher, ich habe mein Problem liegt woanders.
- Sind Sie mit einer externen Bibliotheken?
- Ja. Aber es ruft Fehler auf meinem eigenen Funktionen, die sagen server.c definiert Sie sich zuerst. server.c und rio.h import: stdio.h, stdlib.h, unistd.h und errno.h
- Wenn Sie sagen, "server.c enthält rio.c", meinst du, dass in der Datei
server.c
haben Sie eine Zeile wie#include "rio.c"
? Wenn ja, ist der falsche Ansatz zu nehmen und wahrscheinlich die Quelle des Fehlers; Sie sollte, einschließlichrio.h
statt. - Nicht nur das, sondern Sie haben auch explizit den link der Dateien in der Datei. Ich bin mir ziemlich sicher, dass Sie tun würde dies, nachdem
-o sysstatd <L>
wo<L>
ist die Bibliothek zu verknüpfen. Wenn Sie linklibsomelib.a
zum Beispiel, die war in Ihre$PATH
Sie ersetzen würde<L>
mit-lsomelib
. - Yep, dass war die Frage. Das macht Sinn. Meine server.o hatte schon das rio.c Funktionen, da es inklusive rio.c, wodurch die linking-Fehler. Wenn Sie fügen Sie es als eine Antwort werde ich akzeptieren.
- Die Standard-link-Regel hängt von der
LDFLAGS
undLDLIBS
Variablen genau wie die Standard-c-Zusammenstellung der Regel hängt davon abCFLAGS
. Machen Sie gute Verwendung dieser Standard-Regeln ist ein Weg, um Ihre makefile kürzer und mehr idiomatisch. Kurz gesagt, hilft es, die Dokumentation zu Lesen. - Ich lese es.. Natürlich habe ich
-c
und benutzerdefinierte Namensgebung-o
flags, daher schreiben die Zusammenstellung Linien. - Standard-GNU-build-Regel für c-source-Dateien ist
$(CC) $(CPPFLAGS) $(CFLAGS) -c
. Es wäre nicht nur gut mit der richtigen Wahl derCFLAGS
undCPPFLAGS
. Müssten Sie geben Sie die link-Regel, aber Sie sollten die üblichen Variablen, weil das ist das, was jemand Lesen Sie Ihre Quelle erwarten.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollten Sie überarbeiten die Struktur ein wenig:
Der Unterschied ist, dass die phoney Regel
all
hängtsysstatd
Aktualität, undsysstatd
ist up to date, wenn es up to date ist-w.r.t die Objekt-Dateien.Ist es nun halt eher ausführlich schreiben Sie die Zusammenstellung der Aktionen ausdrücklich. Es würde ausreichend sein, um zu verwenden:
Könnte man auch die Debatte: hat
server.c
nicht verwendenrio.h
? Wenn es das tut, wird die Abhängigkeit aufgeführt werden sollte. Wenn nicht, warumrio.h
vorhanden???make
davon aus, dassserver.o
hängtserver.c
, so dass Sie nicht haben, um anzugeben, dass (aber es wird nicht machen Annahmen über die Header). Man könnte auch ein makro verwenden, um zu verhindern, dass die Wiederholung der Programm-name:Wenn Sie benötigt weitere Bibliotheken, dann können Sie verwenden: