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ßlich rio.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 link libsomelib.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 und LDLIBS Variablen genau wie die Standard-c-Zusammenstellung der Regel hängt davon ab CFLAGS. 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 der CFLAGS und CPPFLAGS. 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.

InformationsquelleAutor darksky | 2012-12-01
Schreibe einen Kommentar