Де gcc шукає файли заголовків C і C ++?


186

У системі Unix, де gcc шукає файли заголовків?

Я витратив трохи часу сьогодні вранці на пошуки деяких файлів заголовків системи, тому я подумав, що це буде хорошою інформацією.

Відповіді:


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

Ця команда запитує gcc, який C ++ препроцесор він використовує, а потім запитує цей препроцесор, де він шукає.

Ви отримаєте надійну відповідь для вашої конкретної установки.

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

`gcc -print-prog-name=cpp` -v

2
Що означає `s? Мені важко це шукати.
mijiturka


5
Я здогадуюсь , замість цього є препроцесор C ? На моїй debian Джессі (правильно) cppcc1$(gcc -print-prog-name=cpp) -v/usr/include/x86_64-linux-gnu
подається

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

3
Я думаю, це було б корисніше, якби ви просто сказали "використовувати опцію -v".
Джей Конрод

Добре, якщо ви будете використовувати "-v" без файлу C, що включає неіснуючий системний заголовок, ви не змусите ісправити gcc через всі маршрути включення. Ключовим моєю відповіддю є bogus.h, зазначений у заголовку системи.
diciu

@Jay - ти маєш рацію, це було занадто невиразно - я пояснив, що робив у сценарії оболонки.
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. Див. Відповідь Шмоопти для кращого рішення.
Мартін Йорк

PS: Мої файли заголовків C ++ знаходяться у: /usr/include/c++/4.0.0
Мартін Йорк

3
@Martin: Ти стара школа. Мої знаходяться в /usr/include/c++/4.2 :)
Білл Ящера

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у командному рядку є параметри сімейства, вони впливатимуть на те, що роздруковується.

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


9
g++ -print-search-dirs
gcc -print-search-dirs

3
Ці команди друкують стандартні шляхи пошуку для бібліотек посилань та внутрішніх компонентів компілятора; вони нічого не розповідають про файли заголовків.
zwol

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

1

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.