Як визначити, звідки включений файл заголовка?


97

Як я можу визначити, де g ++ зміг знайти файл включення? В основному, якщо я

#include <foo.h>

g ++ сканує шлях пошуку, використовуючи будь-які параметри включення, щоб додати або змінити шлях. Але, наприкінці днів, чи є спосіб, яким я можу визначити абсолютний шлях foo.h, який g ++ обрав для компіляції? Особливо актуально, якщо в безлічі шляхів пошуку є більше одного foo.h.

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


1
Пов’язане: чи є спосіб визначити, з яких батьківських файлів включення було включено дочірній файл включення? Тобто, щоб показати включений графік (Підказка: gcc -E не зовсім там ... може бути оброблено, щоб отримати його).
Krazy Glew

Відповіді:


78

Це дасть залежності make, які перелічують абсолютні шляхи включення файлів:

gcc  -M showtime.c

Якщо ви не хочете, щоб система включала (тобто #include <something.h>), тоді використовуйте:

gcc  -MM showtime.c

18
Слід зазначити, що якщо ви використовуєте спільно з "-o myObj.o", результат, а не скомпільований двійковий файл, надходить у "myObj.o". -M має неявний -E, тому компіляція не виконується. Я знайшов -MD - дуже корисний варіант, замість цього він виконує компіляцію та розміщує висновок у myObj.d. Створення відповідного параметра для простого додавання до вашого рядка компіляції без дивних ефектів, таких як * .o, тепер містить висновок замість двійкового файлу. Спасибі за вашу допомогу.
harschware

Усі відповідні параметри gcc описані тут .
акхан

105
g++ -H ...

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


7
З мого досвіду, це здається кориснішим, ніж -М. Мені подобається ієрархічне відображення того, що включає що.
Брайан Мінтон

Добре, це корисно для налагодження.

1
Це найкраща відповідь. Ви можете додати його до процесу збірки, не змінюючи нічого іншого.
Тімммм

4
Це насправді відповідає на питання більше, ніж прийнята відповідь. Єдиною прикрою проблемою є те, що я не міг змусити Кланга зупинити спроби нормальної компіляції файлу, тому в підсумку я використав clang++ -MM -H(що є трохи корисною комбінацією).
rookie1024

@ rookie1024 Використовуйте, clang++ -H -fsyntax-only ...якщо хочете уникнути створення вихідних файлів (працює gccтакож).
Лекенштейн

8

Впевнене використання

g++ -E -dI  ... (whatever the original command arguments were)

2
У цього рішення є кілька переваг: 1. Ви можете виявити кілька включень одного заголовного файлу (-H та -M роздрукуйте кожен включений файл лише один раз) 2. Ви можете побачити, куди він включений (ім'я та номер рядка оригіналу включати інструкцію). 3. Тим самим ви можете достовірно (!) Розрізнити, включений чи заголовок прямо чи опосередковано, або і те, і інше (Це важливо для очищення.)
hagello

5

Якщо ви використовуєте -MMабо один із пов'язаних параметрів ( -Mтощо), ви отримуєте лише список заголовків, які включені, не маючи всіх інших вихідних даних препроцесора (які ви, мабуть, отримуєте із запропонованим g++ -E -dIрішенням).


g++ -MM t.ccне показує взагалі ніякого включення, просто t.o: t.cc. Чи потрібно щось інше?
wallyk

3
Приємно - для повноти ви можете отримати подібне з MSVC, використовуючи /showIncludesопцію. MSVC навіть зробить відступ, щоб показати вам вкладеність заголовків (я не бачу, що з -Mна GCC).
Michael Burr
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.