2017-12-21 12 views
2

Ich habe ein kleines Build, in dem ich nur eine einzelne Header-Datei (und Quelldatei) aus einem anderen Verzeichnis aufnehmen möchte. Ich weiß, wie man den Parameter -I benutzt, aber nicht das gesamte Verzeichnis, sondern nur die einzelnen Dateien.Fügen Sie einen einzelnen Header aus einem anderen Verzeichnis ein

Mein Make-Datei sieht wie folgt aus:

myproj: ui.o data.o string.o 
    c99 -ggdb -o myproj ui.o data.o string.o 
    ctags * 

ui.o : ui.c data.h 
    c99 -ggdb -c ui.c 

data.o : data.c data.h 
    c99 -ggdb -c data.c 

string.o : ../../shared/src/string.c ../../shared/src/string.h 
    c99 -ggdb -c ../../shared/src/string.c ../../shared/src/string.h -o ./jcstring.o 

Wenn ich versuche, es zu machen, beklagt, dass string.h nicht gefunden wird:

c99 -ggdb -c ui.c ../../shared/src/string.h 
In file included from ui.c:7:0: 
data.h:1:22: fatal error: string.h: No such file or directory 
#include "string.h" 

Wie kann ich diese Datei enthalten, ohne das gesamte Verzeichnis inklusive?

+0

Früh in der 'make' Datei erzeugt die Liste der Quelldateien, vielleicht durch '' SRC: = $ (Wildcard * .c) 'und die Liste der Objektdateien, vielleicht durch' OBJ: = $ (SRC :. c = .o) ' – user3629249

+0

Ändern Sie den Suchpfad der Standard-Headerdatei, der ein Eintrag in der Umgebung ist, um den Verzeichnispfad zur gewünschten Datei hinzuzufügen. Beachten Sie auch, dass Ihre 'make'-Datei VIEL besser wäre, wenn sie die notwendigen Anweisungen enthält, um die' Abhängigkeits'-Datei für jede Quelldatei zu erstellen. Dann das Rezept, um die string.o zu erzeugen (am besten, den Root-Namen nicht zu ändern). würde ähnlich aussehen:% .o:% .c% d folgte in der nächsten Zeile ähnlich wie: c99 -ggdb -c $ <-o $ @ -I. gegen Ende der 'make' Datei müssen die Anweisungen hinzufügen: 'ifneq" $ (MAKECMDGOALS) "" clean " -include $ (DEP) endif' – user3629249

+0

früh in der 'make' Datei enthalten eine Aussage ähnlich wie: 'CCFLAGS: = -Wall -Wextra -WWconversion -pedantic -std = gnu99' – user3629249

Antwort

3

Ich weiß, wie Sie den Parameter -I verwenden, aber nicht das gesamte Verzeichnis, nur die einzelnen Dateien einschließen möchten.

-I nicht „enthält ein Verzeichnis“, bringt es nur das Verzeichnis auf dem Suchpfad. Es spielt keine Rolle, dass das Verzeichnis andere Dateien enthält, die Sie nicht möchten. Die einzigen Dateien, die der Compiler liest, sind diejenigen, deren Name in einer #include Direktive steht. Wenn Sie also ein ../../shared/src/string.h haben, dann können Sie die folgende Zusammenstellung Befehl verwenden:

c99 -ggdb -I ../../shared/src -c ui.c 

Im Falle von string. ist der Header im selben Verzeichnis wie die Quelldatei. Dies ist, wo der Compiler zuerst aussehen wird, so dass Sie -I überhaupt nicht benötigen.

c99 -ggdb -c ../../shared/src/string.c -o ./jcstring.o 

Das einzige Szenario, in dem das Hinzufügen -I Optionen verletzen kann, ist, wenn Dateien mit dem gleichen Namen in verschiedenen Verzeichnissen Header werden. Wenn zum Beispiel alle vier der folgenden Dateien vorhanden sind:

one/foo.h 
one/bar.h 
two/foo.h 
two/bar.h 

und Sie möchten Code kompilieren enthält

#include "foo.h" /* must refer to one/foo.h */ 
#include "bar.h" /* must refer to two/bar.h */ 

dann können Sie es nicht tun, mit nur -I Richtlinien. Entweder setzen Sie zuerst -I one und #include "bar.h" wird one/bar.h, oder Sie setzen -I two zuerst und #include "foo.h" wird two/foo.h enthalten. Die vernünftige Lösung ist, auf dieses Problem nicht zu stoßen. Header innerhalb desselben Projekts sollten eindeutige Namen haben. Wenn Sie Header aus verschiedenen Projekten einfügen, sollten Sie den Projektnamen in die Include-Anweisungen aufnehmen.

#include "one/foo.h" 
#include "two/bar.h" 

Grundsätzlich Sie eine der Header-Dateien in einem separaten Verzeichnis kopieren könnte und umfassen das, aber in dieser Situation typischen Namenskonventionen Sie wahrscheinlich in Namenskollisionen zwischen den Projekten laufen sind gegeben.

Beachten Sie auch, dass string.h ist kein guter Name für eine Überschrift, weil es der Name einer Standardbibliothek Header ist. Der Compiler wird die beiden in Ihrem Fall nicht verwechseln: #include "string.h" sucht nach der Header-Datei im aktuellen Verzeichnis, wenn es eine gibt, während #include <string.h> nur in Verzeichnissen sucht, die mit -I angegeben sind, und fällt zurück in die Standardbibliothek.Kollisionen mit systemweit installierten Headern können vorkommen, und zwar so lange, wie Sie keinen Dateinamen falsch eingeben, aber es ist für Menschen verwirrend, einen sehr bekannten Headernamen zu verwenden, der in den meisten Projekten verwendet wird.

Verwandte Themen