Где gcc ищет заголовочные файлы C и C ++?

186

В системе Unix, где gcc ищет заголовочные файлы?

Сегодня утром я потратил немного времени на поиск некоторых системных заголовочных файлов, так что я подумал, что это будет хорошей информацией для вас.

Билл Ящерица
источник

Ответы:

227
`gcc -print-prog-name=cc1plus` -v

Эта команда спрашивает gcc, какой препроцессор C ++ он использует, а затем спрашивает, какой препроцессор там, где он ищет, включает.

Вы получите надежный ответ для вашей конкретной установки.

Аналогично для препроцессора C :

`gcc -print-prog-name=cpp` -v
Дрю Дорманн
источник
2
Что это значит? Мне трудно это искать.
Миджитурка
5
Я предполагаю , что C препроцессор это cppвместо cc1? На моем дебиане Джесси$(gcc -print-prog-name=cpp) -v (правильно) дает еще один путь, который/usr/include/x86_64-linux-gnu
wlnirvana
3
Если вы не хотите, чтобы ожидание ввода зависало, перенаправьте ввод с /dev/null, так что `gcc -print-prog-name=cc1` -v < /dev/null.
Стив Йоргенсен
@SteveJorgensen да! Или нажмите Ctrl+ D, что отправляет «конец файла» в Unix-talk.
Дрю Дорманн
40

Кроме того, gcc будет искать в каталогах, указанных после -Iопции.


Роберт
источник
4
@totaam: проверь свой шрифт! Этот ответ использует «-I» (заглавная «глаз»), а не «-l» (строчная «ell»).
3
-Я для <anglebracketed.h>, тогда как -iquote для "quotedfiles.h"
jcomeau_ictx
28

Вы можете создать файл, который пытается включить поддельный системный заголовок. Если вы запустите gcc в подробном режиме для такого источника, он перечислит все местоположения системного включения, как и ищет поддельный заголовок.

$ echo "#include <bogus.h>" > t.c; gcc -v t.c; rm t.c

[..]

#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc/i686-apple-darwin9/4.0.1/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)
End of search list.

[..]

t.c:1:32: error: bogus.h: No such file or directory
diciu
источник
3
Я думаю, что было бы более полезно, если бы вы просто сказали «использовать опцию -v».
Джей Конрод
Хорошо, если вы используете «-v» без файла C, который содержит несуществующий системный заголовок, вы не будете заставлять gcc перебирать все пути включения. Ключом к моему ответу является bogus.h, указанный как системный заголовок.
diciu
@ Джей - ты прав, это было слишком расплывчато - я объяснил, что я делал в сценарии оболочки.
diciu
9
без временных файлов:echo "#include <bogus.h>" | gcc -v -x c -
thejoshwolfe
2
gcc -v -E - < /dev/nullили cpp -v < /dev/nullдостаточно. Вы просто должны получить препроцессор работать , это не имеет значения , что он видит вход. (Пути поиска печатаются во время запуска, прежде чем он даже смотрит на свои входные данные.)
zwol
17

CPP Раздел в руководстве GCC указывает , что файлы заголовков могут быть расположены в следующих каталогах:

GCC ищет заголовки в нескольких разных местах. В обычной системе Unix, если вы не укажете иное, она будет искать заголовки, запрошенные с помощью #include в:

 /usr/local/include
 libdir/gcc/target/version/include
 /usr/target/include
 /usr/include

Для программ на C ++ он также сначала будет выглядеть в / usr / include / g ++ - v3.

Билл Ящерица
источник
Это хорошо для вашей текущей версии GCC. Реальные каталоги, в которые он смотрит, зависят от параметров, указанных при сборке gcc. Смотрите ответ Shmoopty для лучшего решения.
Мартин Йорк
PS: Мои заголовочные файлы C ++ находятся в: /usr/include/c++/4.0.0
Martin York,
3
@ Мартин: Ты старая школа. Мои находятся в /usr/include/c++/4.2 :)
Bill the Lizard
10

Чтобы заставить GCC распечатать полный набор каталогов, где он будет искать системные заголовки, вызовите его так:

$ LC_ALL=C gcc -v -E -xc - < /dev/null 2>&1 | 
  LC_ALL=C sed -ne '/starts here/,/End of/p'

который будет производить вывод формы

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

Если -Iв командной строке есть параметры -family, они будут влиять на то, что выводится на печать.

(The sedкоманда , чтобы избавиться от всех других барахла этого розария печатает, и LC_ALL=Cчтобы убедиться , что в sedкомандных произведениях - «начинается здесь» и «Конец списка результатов поиска» фразы будут переведены IIRC) .

zwol
источник
9
g++ -print-search-dirs
gcc -print-search-dirs
user292283
источник
3
Эти команды выводят пути поиска по умолчанию для библиотек ссылок и внутренних компонентов компилятора; они ничего не говорят вам о заголовочных файлах.
Звол
6

Набор путей, по которым компилятор ищет файлы заголовков, можно проверить с помощью команды: -

CPP-V

Если вы объявляете #include "" , компилятор сначала ищет в текущем каталоге исходного файла и, если не найден, продолжает поиск в вышеупомянутых найденных каталогах.

Если вы объявляете #include <> , компилятор выполняет поиск непосредственно в тех каталогах, которые были получены из приведенной выше команды.

Источник: - http://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art026

Сухас Чикканна
источник
1

Можно посмотреть (дополнительный) путь включения для программы на C из bash, проверив следующее:

echo $C_INCLUDE_PATH

Если это поле пустое, его можно изменить, добавив местоположения включения по умолчанию:

export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/include
user2844647
источник
1

Это каталоги, которые gcc просматривает по умолчанию для указанных заголовочных файлов (учитывая, что заголовочные файлы включены в шевроны <>); 1. / usr / local / include / - используется для сторонних заголовочных файлов. 2. / usr / include / - используется для системных заголовочных файлов.

Если в случае, если вы решили поместить свой пользовательский заголовочный файл в место, отличное от вышеупомянутых каталогов, вы можете включить их следующим образом: 1. используя кавычки ("./custom_header_files/foo.h") с путем к файлу вместо шевронов в заявлении включения. 2. используя ключ -I при компиляции кода. gcc -I / home / user / custom_headers / -c foo.c -p foo.o Обычно ключ -I указывает компилятору сначала искать каталог, указанный с помощью ключа -I (перед проверкой стандартных каталогов). с помощью ключа -I файлы заголовков могут быть включены с помощью шевронов.

ахил тивари
источник