Como saber de onde um arquivo de cabeçalho é incluído?

97

Como posso saber onde o g ++ conseguiu localizar um arquivo de inclusão? Basicamente se eu

#include <foo.h>

g ++ fará a varredura do caminho de pesquisa, usando qualquer opção de inclusão para adicionar ou alterar o caminho. Mas, no final dos dias, há uma maneira de saber o caminho absoluto de foo.h que o g ++ escolheu para compilar? Especialmente relevante se houver mais de um foo.h na miríade de caminhos de pesquisa.

Sem uma maneira de fazer isso ... há uma maneira de fazer com que o g ++ me diga qual é o caminho de pesquisa final após incluir os padrões e todas as opções de inclusão?

harschware
fonte
1
Relacionado: existe alguma maneira de saber de quais arquivos de inclusão pai um arquivo de inclusão filho foi incluído? Ou seja, para mostrar o gráfico incluído de (Dica: gcc -E não está exatamente lá ... pode ser processado para gerá-lo.)
Krazy Glew

Respostas:

78

Isso fornecerá dependências de make que listam os caminhos absolutos dos arquivos de inclusão:

gcc  -M showtime.c

Se você não quiser que o sistema inclua (ou seja #include <something.h>), use:

gcc  -MM showtime.c
Sodved
fonte
18
Deve-se observar que se você usar em conjunto com "-o myObj.o", a saída, não o binário compilado, irá para "myObj.o". -M tem um -E implícito, portanto a compilação não é realizada. Descobri que -MD é uma opção muito útil, ele executa a compilação e coloca a saída em myObj.d. Criar um parâmetro adequado para apenas prefixar a linha de compilação sem efeitos estranhos como * .o agora contém a saída em vez do binário. Obrigado pela ajuda.
harschware
Todas as opções relacionadas ao gcc são descritas aqui .
Akhan de
105
g++ -H ...

também imprimirá o caminho completo dos arquivos de inclusão em um formato que mostra quais cabeçalhos incluem quais

Bulletmagnet
fonte
7
Isso parece ser mais útil do que -M em minha experiência. Gosto da exibição hierárquica do que inclui o quê.
Brian Minton
Ótimo, é útil para fins de depuração.
1
Esta é a melhor resposta. Você pode adicioná-lo ao seu processo de construção sem alterar nada.
Timmmm
4
Isso realmente responde à pergunta mais do que a resposta aceita. O único problema infeliz é que não consegui fazer com que ele impedisse o Clang de tentar compilar o arquivo normalmente, então acabei usando clang++ -MM -H(que é uma combinação ligeiramente útil).
rookie1024 de
@ rookie1024 Use clang++ -H -fsyntax-only ...se quiser evitar a geração de arquivos de saída (funciona gcctambém).
Lekensteyn
8

Claro uso

g++ -E -dI  ... (whatever the original command arguments were)
Wallyk
fonte
2
Existem vários benefícios para esta solução: 1. Você pode descobrir várias inclusões de um único arquivo de cabeçalho (-H e -M imprime cada arquivo incluído apenas uma vez) 2. Você pode ver onde ele está incluído (nome e número da linha do original incluir instrução). 3. Desse modo, você pode distinguir com segurança (!) Se um cabeçalho está incluído direta ou indiretamente ou ambos (isso é importante para limpezas.)
hagello
5

Se você usar -MMou uma das opções relacionadas ( -M, etc), obterá apenas a lista de cabeçalhos incluídos, sem ter todas as outras saídas do pré-processador (que parece obter com a g++ -E -dIsolução sugerida ).

Jonathan Leffler
fonte
g++ -MM t.ccnão mostra nenhuma inclusão, apenas t.o: t.cc. Precisa de algo mais?
wallyk
3
Legal - para completar, você pode obter similaridade com MSVC usando a /showIncludesopção. O MSVC irá até mesmo indentar para mostrar o aninhamento de cabeçalhos (não vejo isso -Mno GCC).
Michael Burr