J'ai inclus sys/ptrace.h
dans mon programme C.
La sortie de /usr/lib/gcc/x86_64-linux-gnu/4.8/cc1 -v
donne les chemins suivants où gcc recherche les fichiers d'en-tête
#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
End of search list.
la sortie de gcc -M
mon programme donne les emplacements des fichiers d'en-tête suivants
pt.o: pt.c /usr/include/stdc-predef.h /usr/include/stdio.h \
/usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \
/usr/include/x86_64-linux-gnu/bits/wordsize.h \
/usr/include/x86_64-linux-gnu/gnu/stubs.h \
/usr/include/x86_64-linux-gnu/gnu/stubs-64.h \
/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \
/usr/include/x86_64-linux-gnu/bits/types.h \
/usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \
/usr/include/_G_config.h /usr/include/wchar.h \
/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \
/usr/include/x86_64-linux-gnu/bits/stdio_lim.h \
/usr/include/x86_64-linux-gnu/bits/sys_errlist.h \
/usr/include/x86_64-linux-gnu/sys/ptrace.h
Puisqu'il /usr/include/x86_64-linux-gnu/
n'est pas contenu dans la première sortie, comment gcc le trouve- sys/ptrace.h
t-il?
ÉDITER:
La sortie des echo '#include <sys/ptrace.h>' | gcc -fsyntax-only -xc -v -H -
résultats dans
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
/usr/include
.. Quel problème essayez-vous de résoudre?/sys/ptrace.h
maissys/ptrace.h
, non?/usr/include/x86_64-linux-gnu
est traité comme un répertoire système et doit être inclus dans la liste des chemins de recherche imprimée pargcc -v
. Je ne sais pas comment quelqu'un a réussi à résoudre ce bogue; si je me souviens bien, la façon la plus évidente d'ajouter des répertoires système comprend les ajoute à ce qui est imprimé par-v
. (J'ai écrit ~ 50% du préprocesseur de GCC, mais c'était il y a 15 ans, donc je me souviens peut-être de quelque chose.)/usr/include
. Cela briserait à peu près toutes les bibliothèques C du monde.Réponses:
Réponse plus courte.
Votre question concerne la sortie de
cc1 -v
, mais cela ne prend pas en compte le CPP (C Pre-Processor) et ses inclus sont mélangés dans toute la chaîne de compilation. Si vous exécutezcpp -v
sur votre système, vous devriez voir, un mélange d'inclusions qui ressemble à la sortie decc1 -v
mais avec au moins le/usr/include/x86_64-linux-gnu
chemin d'accès qui y est ajouté.Réponse plus longue.
Techniquement, il
/usr/include/x86_64-linux-gnu/
n'est pas explicitement défini dans la première sortie, mais/usr/include/
l'est définitivement. Et c'est un chemin de recherche par défaut comme expliqué dans la documentation officielle de GNU GCC :Et expliqué plus en détail ici:
Cela implique donc que le
x86_64-linux-gnu/
chemin est simplement inséré/usr/include/*/sys/
comme ceci:C'est du moins ce que je pensais initialement dans une version antérieure de cette question . Mais après avoir consulté ce site, l'explication de ce qui se passe est un peu plus détaillée et la réponse directe de ce site au contenu équivalent à ce que j'ai publié ci-dessus est republiée ci-dessous; je souligne:
Sachez que le CPP (C Pre-Processor) est la première étape du processus du compilateur, regardons la sortie «include» de
cpp -v
mon système de test Ubuntu 12.04.5:Là, vous pouvez voir clairement
/usr/include/x86_64-linux-gnu
. Et pour comparer, voici la sortie «include» similaire/usr/lib/gcc/x86_64-linux-gnu/4.6/cc1 -v
du même système de test Ubuntu 12.04.5:Notez comment
/usr/include/x86_64-linux-gnu
est clairement inséré dans le mix par l'action initiale CPP (C Pre-Processor). Et le message sur ce site continue pour expliquer d'où viennent ces chemins; encore une fois, je souligne:Donc, tout se résume à l'appel du CPP (C Pre-Processor) en tant que première partie d'une chaîne de compilation C.
la source
$TARGET
partie que j'ai mentionnée dans ma réponse et mon commentaire. C'est la sortie deconfig.guess
quand GCC a été compilé, ou qui a été donnée à sonconfigure
script avec le--target
drapeau. La vraie question est, comment ce chemin est-il assemblé? Revient-il simplement dans la même liste, s'ajoutant$TARGET
à chacun, après avoir échoué à trouver l'en-tête la première fois?À moins de me plonger dans le code source de GCC, je ne peux pas vous donner de "pourquoi", mais je peux vous dire que la version de GCC que j'ai ici retombe
/usr/include/$TARGET
après avoir épuisé les choix que vous et JakeGould avez trouvés . Vous pouvez le voir comme ceci:où
foo.c
contient un#include <sys/ptrace.h>
.Vous avez besoin de l'
-f
argument ici parce que lesgcc
enfants sont engendrés pour effectuer le travail de compilation proprement dit. Vous avez besoin du2>&1
carstrace
écrit ses résultats dans stderr, pas stdout.Notez que vous obtenez des
ENOENT
erreurs pour tous les répertoires documentés avant d'essayer enfin celui qui réussit.la source