Où gcc cherche-t-il les fichiers inclus ?

Anne C gcc

Algorithme de recherche

Pour rechercher les fichiers inclus, gcc construit une liste de répertoires composée de deux parties : la liste commence par le répertoire du fichier source, puis les répertoires où chercher les fichiers inclus avec des guillemets (#include "..."), et enfin les répertoires où chercher les fichiers systèmes, inclus avec des crochets (#include <...>).

Il cherche ensuite les fichiers inclus avec des guillemets dans toutes la liste, et les fichiers systèmes dans la seconde partie seulement.

Voir les chemins utilisés

L’option -Wp, permet de passer directement des options au préprocesseur. Par exemple -Wp,-v permet de voir la liste des chemins de recherche utilisés. Par ailleurs, -fsyntax-only permet de ne faire que ça.

Par exemple :

$ gcc -fsyntax-only -Wp,-v test.c

donne sur ma machine :

ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

On voit que par défaut, la première partie de la liste est vide (pas tout à fait puisqu’il y a le répertoire du fichier courant, mais qui n’est pas indiqué ici).

Modifier la liste

On peut :

  • ajouter des chemins dans la première partie de la liste avec l’option -iquote ;
  • ajouter des chemins dans la seconde partie de la liste, avant les répertoires par défaut, avec l’option -isystem (ou -I mais ce n’est équivalent : voir l’exemple ci-dessous) ;
  • ôter les répertoires par défaut avec l’option -nostdinc.

Les options sont traitées dans l’ordre (le premier répertoire est donc le premier dans la recherche, c’est-à-dire qu’il est mis en tête de liste) mais les doublons sont éliminés.

Par exemple :

$ gcc -fsyntax-only -Wp,-v test.c -nostdinc -iquote src -isystem src/include

donne :

#include "..." search starts here:
 src
#include <...> search starts here:
 src/include

Mais les répertoires indiqués par -I sont prioritaires par rapport à ceux indiqués par -isystem. Par exemple :

$ gcc -fsyntax-only -Wp,-v test.c -nostdinc -isystem include1 -isystem include2

donne :

#include "..." search starts here:
#include <...> search starts here:
include1
include2

Alors que :

$ gcc -fsyntax-only -Wp,-v test.c -nostdinc -isystem include1 -I include2

donne :

#include "..." search starts here:
#include <...> search starts here:
include2
include1

Pour ne pas chercher dans le répertoire du fichier source

Le problème avec l’algorithme précédent c’est qu’il commence toujours par chercher les fichiers inclus entre guillemets dans le répertoire du fichier source… et il arrive qu’on ne veuille pas faire ça.

La solution est d’utiliser l’option -I- : cette option est obsolète, mais elle permettait de marquer la limite entre les deux parties de la liste de recherche avant l’apparition des options -iquote et -isystem, mais elle avait aussi un effet de bord :

In addition, -I- inhibits the use of the directory of the current file directory as the first search directory for #include "file".
This option has been deprecated.

Malheureusement, il ne semble pas y avoir d’option moderne ayant cet effet !

Une autre solution, proposée sur StackOverflow, consiste à utiliser l’option -include pour inclure un fichier pré-compilé en tête du fichier source.

Documentation

Dans la doc de gcc:

Les autres notes au sujet de gcc :

Voir aussi :