Onde o gcc procura por arquivos de cabeçalho C e C ++?

186

Em um sistema Unix, onde o gcc procura por arquivos de cabeçalho?

Passei um pouco de tempo esta manhã procurando alguns arquivos de cabeçalho do sistema, então achei que seria uma boa informação para ter aqui.

Bill the Lizard
fonte

Respostas:

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

Este comando pergunta ao gcc qual pré-processador C ++ está usando e, em seguida, pergunta ao pré-processador onde ele procura inclui.

Você receberá uma resposta confiável para sua configuração específica.

Da mesma forma, para o pré-processador C :

`gcc -print-prog-name=cpp` -v
Drew Dormann
fonte
2
O que significam os `s? Estou achando difícil procurar por isso.
Mjiturka
5
Eu acho que o pré - processador C é em cppvez de cc1? No meu debian Jessie $(gcc -print-prog-name=cpp) -v(corretamente) dá mais um caminho, que é/usr/include/x86_64-linux-gnu
wlnirvana
3
Se você deseja que isso não fique esperando pela entrada, redirecione a entrada de /dev/null, então `gcc -print-prog-name=cc1` -v < /dev/null.
Steve Jorgensen
@SteveJorgensen yep! Ou pressione Ctrl+ D, que envia "fim do arquivo" no Unix-talk.
Tirou Dormann
40

Além disso, o gcc procurará nos diretórios especificados após a -Iopção.


Robert
fonte
4
@totaam: Verifique sua fonte! Esta resposta usa "-I" (maiúscula "olho") e não "-l" (minúscula "ell").
3
-I é para <anglebracketed.h> enquanto -iquote é para "quotedfiles.h"
jcomeau_ictx
28

Você pode criar um arquivo que tente incluir um cabeçalho de sistema falso. Se você executar o gcc no modo detalhado nessa fonte, ele listará todos os locais de inclusão do sistema, à medida que procura o cabeçalho falso.

$ 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
fonte
3
Eu acho que isso seria mais útil se você dissesse "use a opção -v".
Jay Conrod
Bem, se você usar "-v" sem um arquivo C que inclua um cabeçalho de sistema inexistente, não fará com que o gcc repita todos os caminhos de inclusão. A chave da minha resposta é falsa.h listada como um cabeçalho do sistema.
diciu 05/12/08
@ Jay - você está certo, era muito vago - eu expliquei o que estava fazendo no script de shell.
diciu 05/12/08
9
sem arquivos temporários:echo "#include <bogus.h>" | gcc -v -x c -
thejoshwolfe 4/12/12
2
gcc -v -E - < /dev/nullou cpp -v < /dev/nullsão suficientes. Você apenas tem que obter o pré-processador para executar , não importa o que de entrada que vê. (Os caminhos de pesquisa são impressos durante a inicialização, antes mesmo olha para sua entrada.)
Zwol
17

A seção CPP do manual do GCC indica que os arquivos de cabeçalho podem estar localizados nos seguintes diretórios:

O GCC procura em vários lugares diferentes cabeçalhos. Em um sistema Unix normal, se você não o instruir de outra forma, ele procurará os cabeçalhos solicitados com #include in:

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

Para programas em C ++, ele também procurará em / usr / include / g ++ - v3, primeiro.

Bill the Lizard
fonte
Isso é bom para a sua versão atual do gcc. Os diretórios atuais em que ele pesquisa dependem das opções especificadas quando o gcc foi criado. Veja a resposta Shmoopty para uma solução melhor.
Martin York
PS: Meus arquivos de cabeçalho C ++ estão em: /usr/include/c++/4.0.0
Martin York
3
@ Martin: Você é da velha escola. Os meus estão em /usr/include/c++/4.2 :) #
Bill the Lizard
10

Para que o GCC imprima o conjunto completo de diretórios em que ele procurará os cabeçalhos do sistema, chame-o assim:

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

que produzirá a saída do formulário

#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.

Se você tiver -Iopções -family na linha de comando, elas afetarão o que é impresso.

(O sedcomando é se livrar de todos os outros itens indesejados que esta invocação imprime, e LC_ALL=Cé para garantir que o sedcomando funcione - as frases "começa aqui" e "Fim da lista de pesquisa" são traduzidas como IIRC.)

zwol
fonte
9
g++ -print-search-dirs
gcc -print-search-dirs
user292283
fonte
3
Esses comandos imprimem os caminhos de pesquisa padrão para bibliotecas de links e componentes internos do compilador; eles não dizem nada sobre os arquivos de cabeçalho.
Zwol
6

O conjunto de caminhos em que o compilador procura os arquivos de cabeçalho pode ser verificado pelo comando: -

cpp -v

Se você declarar #include "" , o compilador procurará primeiro no diretório atual do arquivo de origem e, se não for encontrado, continuará pesquisando nos diretórios recuperados acima.

Se você declarar #include <> , o compilador pesquisará diretamente nos diretórios obtidos no comando acima.

Fonte: - http://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art026

Suhas Chikkanna
fonte
1

Pode-se visualizar o caminho de inclusão (adicional) para um programa C a partir do bash, verificando o seguinte:

echo $C_INCLUDE_PATH

Se estiver vazio, pode ser modificado para adicionar locais de inclusão padrão, por:

export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/include
user2844647
fonte
1

Esses são os diretórios nos quais o gcc procura por padrão os arquivos de cabeçalho especificados (considerando que os arquivos de cabeçalho estão incluídos nas divisões <>); 1. / usr / local / include / - usado para arquivos de cabeçalho de terceiros. 2. / usr / include / - usado para arquivos de cabeçalho do sistema.

Se você decidir colocar seu arquivo de cabeçalho personalizado em um local diferente dos diretórios mencionados acima, poderá incluí-los da seguinte maneira: 1. usando aspas ("./custom_header_files/foo.h") com o caminho dos arquivos, em vez das divisas na instrução include. 2. usando a opção -I ao compilar o código. gcc -I / home / user / custom_headers / -c foo.c -p foo.o Basicamente, a opção -I informa ao compilador que primeiro procure no diretório especificado com a opção -I (antes de verificar os diretórios padrão). usando a opção -I, os arquivos de cabeçalho podem ser incluídos usando as divisas.

akhil tiwari
fonte