Wenn ich Verzeichnisse einbeziehen möchte, die nach Header-Dateien durchsucht werden sollen, was ist der bevorzugte Weg und warum?
-I dir vs. -isystem dir
Eine Möglichkeit, dies anzuzeigen, besteht darin, Header zu verwenden, mit denen Sie steuern -I
und diejenigen, mit denen Sie es nicht tun (System, Bibliotheken von Drittanbietern). -isystem
. Der praktische Unterschied besteht darin, dass Warnungen aktiviert werden, aus denen Warnungen stammen -isystem
Kopfzeilen werden unterdrückt.
Justin Ether
Von dem gcc-Dokumentation für -I:
Fügen Sie das Verzeichnis dir am Kopf der Liste der Verzeichnisse hinzu, die nach Header-Dateien durchsucht werden sollen. Dies kann verwendet werden, um eine Systemheaderdatei zu überschreiben und Ihre eigene Version zu ersetzen, da diese Verzeichnisse vor den Systemheaderdateiverzeichnissen durchsucht werden. Sie sollten diese Option jedoch nicht verwenden, um Verzeichnisse hinzuzufügen, die vom Hersteller bereitgestellte System-Header-Dateien enthalten (verwenden Sie dafür -isystem). Wenn Sie mehr als eine Option -I verwenden, werden die Verzeichnisse von links nach rechts gescannt; die Standardsystemverzeichnisse kommen danach.
Wenn ein standardmäßiges System-Include-Verzeichnis oder ein mit -isystem angegebenes Verzeichnis auch mit -I angegeben wird, wird die Option -I ignoriert. Das Verzeichnis wird weiterhin durchsucht, jedoch als Systemverzeichnis an seiner normalen Position in der System-Include-Kette. Dadurch soll sichergestellt werden, dass das Verfahren von GCC zum Beheben fehlerhafter Systemheader und die Reihenfolge für die include_next-Direktive nicht versehentlich geändert werden. Wenn Sie die Suchreihenfolge für Systemverzeichnisse wirklich ändern müssen, verwenden Sie die Optionen -nostdinc und/oder -isystem.
So -I
ist wahrscheinlich die bevorzugte Option, um den Speicherort Ihrer Header-Dateien anzugeben, mit Ausnahme von Sonderfällen, wie z. B. vom Anbieter bereitgestellte System-Header.
Sie sollten -I verwenden, um die Position Ihrer Header anzugeben.
Die Dateien, die Sie mit -isystem angeben, werden nach der Verarbeitung von -I durchsucht und erhalten eine Sonderbehandlung durch gcc (wie Standard-System-Header).
Hier ist also der Unterschied, den ich durch einige Experimente gefunden habe. Stellen Sie sich folgendes Setup vor:
my_std_lib/stdio.h
#ifndef _CUSTOM_STDIO_H
void test() {}
#endif
#include_next <stdio.h>
#include_next <custom.h>
my_user_lib/custom.h
#ifndef _CUSTOM_HEADER_H
void custom_func() {}
#endif
main.cpp
#include "stdio.h"
int main() {
test();
custom_func();
printf("Hello world!");
return 0;
}
Wenn Sie mit kompilieren
g++ -isystem my_std_lib -isystem my_user_lib main.cpp
alles wird gut funktionieren.
Jedoch, g++ -isystem my_std_lib -I my_user_lib main.cpp
führt zu einem Fehler
In file included from main.cpp:1:
my_std_lib/stdio.h:10:15: fatal error: 'custom.h' file not found
#include_next <custom.h>
^~~~~~~~~~
1 error generated.
Also, was ist los?
Nach meinem Verständnis, wenn ich schreibe #include "stdio.h"
beginnt GCC, die Liste der verfügbaren Header-Dateien zu durchlaufen, bis es sie findet my_std_lib/stdio.h
. Richtlinie #include_next <custom.h>
am Ende dieser Datei weist den Compiler an, nach a zu suchen custom.h
durch Durchlaufen von include-Verzeichnissen von its aktuell Stelle weiter.
Wenn ich hinzufüge my_user_lib
zur Liste der Verzeichnisse mit -I
Flagge, so scheint es Vor alle Systemverzeichnisse in der Verzeichnisliste. Daher taucht es in der Liste davor auf my_std_lib
Verzeichnis und die #include_next
scheitert.
Dasselbe würde passieren, wenn ich mit kompilieren würde g++ -isystem my_user_lib -isystem my_std_lib main.cpp
. Anscheinend werden Verzeichnisse in der gleichen Reihenfolge zur Liste hinzugefügt, in der die Flags angegeben werden, also noch einmal, my_user_lib
wird vorher kommen my_std_lib
.
Also kurz gesagt, -I
und -isystem
unterscheiden sich dadurch, dass sie ihr Ziel zur Liste der Include-Verzeichnisse hinzufügen.
Wenn Sie einen Header „Myheader.h“ mit -I einfügen, generiert der Compiler eine Suchreihenfolge: „Myheader.h“ , „system/headers“. Wenn also etwas nicht in “MyHeader.h” zu finden ist, greifen Sie auf “system/headers” zurück. Wenn Sie jedoch -isystem verwenden, sagen Sie im Grunde, dass Sie “system/headers” durch das ersetzen, was ich Ihnen gebe. Ein Rückgriff auf “System/Header” entfällt also.
Einschließen oder Ausschließen der Host-Standard-C-Bibliothek?
– Tim Post
5. April 2010 um 16:42 Uhr
Weder das eine, noch das andere. Habe gerade im GCC-Handbuch über Vorverarbeitungsoptionen gelesen und bin über diese beiden gestolpert.
– Helfermethode
6. April 2010 um 8:54 Uhr
Eine große Verwendung von -isystem gegenüber -I besteht darin, dass Warnungen in -isystem ignoriert werden. Dies ist nützlich, wenn Sie mit -Wall -Werror kompilieren möchten, aber keine Fehler in den -isystem-Verzeichnissen erhalten möchten.
– Eja
17. Januar 2021 um 16:35 Uhr