web-dev-qa-db-fra.com

Comment dire au compilateur g ++ où rechercher les fichiers d'inclusion?

Dans un "répertoire de travail", j'ai beaucoup de fichiers * .cpp et * .h qui #include les uns des autres et des fichiers des sous-répertoires.

Par exemple:

#include "first.h"
#include "second.h"
#include "dir1/third.h"
#include "dir2/fourth.h"

Dans mon propre répertoire (qui est différent du répertoire "de travail"), je voudrais créer un nouveau fichier * .cpp et * .h qui inclut l'un des fichiers du répertoire "de travail". Par exemple:

#include "/root/workingdirectory/first.h"

Cependant, cela ne fonctionne pas. Parce que "first.h" peut inclure "second.h" et "second.h" ne se trouve pas dans mon répertoire. Existe-t-il un moyen de dire au compilateur qu'il doit rechercher les fichiers inclus non pas dans le répertoire courant mais dans le répertoire de travail: /root/workingdirectory/?

Pour le rendre encore plus complexe, dir1 et dir2 ne se trouvent pas dans mon répertoire de travail. Ils sont situés dans /root/workingdirectory2/. Donc, ma deuxième question est de savoir s'il est possible de résoudre ce problème en laissant le compilateur savoir que les sous-répertoires sont situés ailleurs?

Je dois également ajouter que je n'utilise aucun environnement pour le développement et que je compile à partir de la ligne de commande (en utilisant g++).

19
Roman

Lire le manuel fin

Il est là pour que tout le monde puisse le lire. Vous avez même le choix de quoi utiliser (j'irais avec le premier):

-Idir

Ajoutez le répertoire dir en tête de la liste des répertoires à rechercher pour les fichiers d'en-tête. Cela peut être utilisé pour remplacer un fichier d'en-tête système, en remplaçant votre propre version, car ces répertoires sont recherchés avant les répertoires du fichier d'en-tête système. Cependant, vous ne devez pas utiliser cette option pour ajouter des répertoires contenant des fichiers d'en-tête système fournis par le fournisseur (utilisez -isystem Pour cela). Si vous utilisez plusieurs options -I, Les répertoires sont analysés de gauche à droite; viennent ensuite les répertoires système standard.

Si un répertoire système standard inclut, ou un répertoire spécifié avec -isystem, Est également spécifié avec -I, L'option -I Est ignorée. Le répertoire est toujours recherché mais en tant que répertoire système à sa position normale dans le système, incluez la chaîne. Cela permet de garantir que la procédure de GCC pour corriger les en-têtes du système buggy et l'ordre de la directive include_next Ne sont pas modifiés par inadvertance. Si vous devez vraiment modifier l'ordre de recherche des répertoires système, utilisez les options -nostdinc Et/ou -isystem.

-iquotedir

Ajoutez le répertoire dir en tête de la liste des répertoires à rechercher pour les fichiers d'en-tête uniquement pour le cas de #include "file"; ils ne sont pas recherchés #include <file>, sinon tout comme -I.

12
rubenvb

Comme on vous l'a déjà dit, il est utile de lire le manuel - spécifiquement ce chapitre - et encore plus spécifiquement ici .

Plus précisément, vous voulez

g++ -I/root/workingdirectory -I/root/workingdirectory2

Notez également la documentation sur #include syntaxe de la directive, décrite ici comme:

2.1 Inclure la syntaxe

Les fichiers d'en-tête utilisateur et système sont inclus à l'aide de la directive de prétraitement #include. Il a deux variantes:

#include <file>

Cette variante est utilisée pour les fichiers d'en-tête système. Il recherche un fichier nommé fichier dans une liste standard de répertoires système. Vous pouvez ajouter des répertoires à cette liste avec l'option -I (voir Invocation).

#include "file"

Cette variante est utilisée pour les fichiers d'en-tête de votre propre programme. Il recherche un fichier nommé fichier d'abord dans le répertoire contenant le fichier actuel, puis dans les répertoires de devis et ensuite les mêmes répertoires utilisés pour <file>. Vous pouvez ajouter des répertoires à la liste des répertoires de devis avec l'option -iquote. L'argument de #include, qu'il soit délimité par des guillemets ou des crochets, se comporte comme une constante de chaîne dans la mesure où les commentaires ne sont pas reconnus et les noms de macro ne sont pas développés. Donc,#include <x/*y> spécifie l'inclusion d'un fichier d'en-tête système nommé x/* y.

Cependant, si des barres obliques inverses se produisent dans le fichier, elles sont considérées comme des caractères de texte ordinaires et non comme des caractères d'échappement. Aucune des séquences d'échappement de caractères appropriées aux constantes de chaîne en C n'est traitée. Donc, #include "x\n\\y" spécifie un nom de fichier contenant trois barres obliques inverses. (Certains systèmes interprètent \ comme séparateur de chemin. Tous ces éléments interprètent également / de la même façon. Il est plus portable à utiliser uniquement /.)

C'est une erreur s'il y a quelque chose (autre que des commentaires) sur la ligne après le nom du fichier.

Donc par exemple

#include "first.h"

commencera à chercher dans le même répertoire que le fichier .cpp contenant cette directive (ou prendra un chemin relatif par rapport à ce répertoire).

Si vous souhaitez utiliser le chemin d'inclusion (spécifié par -I) Tu devrais utiliser

#include <dir1/third.h>

La pratique habituelle consiste à utiliser le #include "local.h" formulaire pour les en-têtes à l'intérieur d'une bibliothèque/package/module (mais vous avez choisi d'organiser cela), et le #include <external.h> formulaire pour les en-têtes des bibliothèques externes/tierces ou système.

10
Useless

Pour gcc, c'est le -I option pour l'en-tête comprend . Pour les fichiers .cpp, vous avez juste besoin que ceux-ci apparaissent comme argument de la commande gcc.

4
Andrew White