Список всех заголовочных файлов C или C ++, которые использовались для компиляции проекта - PullRequest
0 голосов
/ 06 марта 2020

Я хотел бы знать пути всех файлов кода, которые были включены в компиляцию всего проекта C / C ++ с несколькими полученными двоичными файлами. Я знаю о https://github.com/rizsotto/Bear и др., Которые вы можете обернуть вокруг своего вызова make и которые сообщают вам вызовы gcc / g ++, но они, конечно, показывают мне только файлы C / C ++, которые были скомпилированы - как я могу узнать, какие заголовки были необходимы для компиляции и оказались в одном из полученных двоичных файлов?

Ответы [ 2 ]

7 голосов
/ 06 марта 2020

G CC имеет опцию времени выполнения -M. Со страницы руководства G CC:

   -M  Instead of outputting the result of preprocessing, output a rule
       suitable for make describing the dependencies of the main source
       file.  The preprocessor outputs one make rule containing the object
       file name for that source file, a colon, and the names of all the
       included files, including those coming from -include or -imacros
       command-line options.

       Unless specified explicitly (with -MT or -MQ), the object file name
       consists of the name of the source file with any suffix replaced
       with object file suffix and with any leading directory parts
       removed.  If there are many included files then the rule is split
       into several lines using \-newline.  The rule has no commands.

       This option does not suppress the preprocessor's debug output, such
       as -dM.  To avoid mixing such debug output with the dependency
       rules you should explicitly specify the dependency output file with
       -MF, or use an environment variable like DEPENDENCIES_OUTPUT.
       Debug output is still sent to the regular output stream as normal.

       Passing -M to the driver implies -E, and suppresses warnings with
       an implicit -w.

Clang поддерживает ту же самую опцию

2 голосов
/ 06 марта 2020

G CC и Clang поддерживают опцию -H (а также опцию -M и ее родственников).

-H

Печать имени каждого используемого файла заголовка в дополнение к другим обычным действиям. Каждое имя имеет отступ, чтобы показать, насколько глубоко оно находится в стеке #include. Предварительно скомпилированные заголовочные файлы также печатаются, даже если они признаны недействительными; неверный предварительно скомпилированный заголовочный файл печатается с '...x', а действительный с '...!'.

Вывод -H сообщается о стандартной ошибке, а не о стандартном выводе.

Опция -H дает больше и другую информацию по сравнению с опцией -M. Он сообщает об уровнях вложенности (одна или несколько начальных точек) и показывает каждый раз, когда заголовок включен - даже если содержимое игнорируется из-за макросов защиты заголовка:

#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED

…content of header…

#endif /* HEADER_H_INCLUDED */

Это может быть полезно; форматированные make строки зависимостей (генерируемые -M) также могут быть полезны.


Пример вывода (при компиляции одного исходного файла из одной из моих программ - make сгенерировал компилятор командная строка, конечно):

$ gcc -H -g -O3 -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -DSYSTEM=MACOS_X -DSTR_SYSTEM='"(macOS Mojave 10.14.6 - Darwin 18.7.0)"' -I/Users/jonathanleffler/inc -DDEBUG -DHASH_STATISTICS -c main.c
. make.h
.. /Users/jonathanleffler/inc/posixver.h
.. config.h
.. /usr/include/assert.h
... /usr/include/sys/cdefs.h
.... /usr/include/sys/_symbol_aliasing.h
.... /usr/include/sys/_posix_availability.h
.. /usr/include/ctype.h
... /usr/include/_ctype.h
.... /usr/include/runetype.h
..... /usr/include/_types.h
...... /usr/include/sys/_types.h
....... /usr/include/machine/_types.h
........ /usr/include/i386/_types.h
....... /usr/include/sys/_pthread/_pthread_types.h
.. /usr/include/errno.h
... /usr/include/sys/errno.h
.. /usr/include/inttypes.h
... /usr/include/Availability.h
.... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/AvailabilityInternal.h
... /usr/include/sys/_types/_wchar_t.h
... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include/stdint.h
.... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/stdint.h
..... /usr/include/sys/_types/_int8_t.h
..... /usr/include/sys/_types/_int16_t.h
..... /usr/include/sys/_types/_int32_t.h
..... /usr/include/sys/_types/_int64_t.h
..... /usr/include/_types/_uint8_t.h
..... /usr/include/_types/_uint16_t.h
..... /usr/include/_types/_uint32_t.h
..... /usr/include/_types/_uint64_t.h
..... /usr/include/sys/_types/_intptr_t.h
...... /usr/include/machine/types.h
....... /usr/include/i386/types.h
........ /usr/include/sys/_types/_u_int8_t.h
........ /usr/include/sys/_types/_u_int16_t.h
........ /usr/include/sys/_types/_u_int32_t.h
........ /usr/include/sys/_types/_u_int64_t.h
........ /usr/include/sys/_types/_intptr_t.h
........ /usr/include/sys/_types/_uintptr_t.h
..... /usr/include/_types/_intmax_t.h
..... /usr/include/_types/_uintmax_t.h
.. /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/limits.h
... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/syslimits.h
.... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/limits.h
..... /usr/include/limits.h
...... /usr/include/machine/limits.h
....... /usr/include/i386/limits.h
........ /usr/include/i386/_limits.h
...... /usr/include/sys/syslimits.h
.. /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include/stdbool.h
.. /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/stdio.h
... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include/stdarg.h
... /usr/include/_stdio.h
.... /usr/include/sys/_types/_va_list.h
.... /usr/include/sys/_types/_size_t.h
.... /usr/include/sys/_types/_null.h
.... /usr/include/sys/stdio.h
... /usr/include/sys/_types/_off_t.h
... /usr/include/sys/_types/_ssize_t.h
... /usr/include/secure/_stdio.h
.... /usr/include/secure/_common.h
.. /usr/include/stdlib.h
... /usr/include/sys/wait.h
.... /usr/include/sys/_types/_pid_t.h
.... /usr/include/sys/_types/_id_t.h
.... /usr/include/sys/signal.h
..... /usr/include/sys/appleapiopts.h
..... /usr/include/machine/signal.h
...... /usr/include/i386/signal.h
..... /usr/include/machine/_mcontext.h
...... /usr/include/i386/_mcontext.h
....... /usr/include/mach/machine/_structs.h
........ /usr/include/mach/i386/_structs.h
..... /usr/include/sys/_pthread/_pthread_attr_t.h
..... /usr/include/sys/_types/_sigaltstack.h
..... /usr/include/sys/_types/_ucontext.h
...... /usr/include/machine/_mcontext.h
..... /usr/include/sys/_types/_sigset_t.h
..... /usr/include/sys/_types/_uid_t.h
.... /usr/include/sys/resource.h
..... /usr/include/sys/_types/_timeval.h
... /usr/include/sys/_types/_wchar_t.h
... /usr/include/malloc/_malloc.h
.. /usr/include/string.h
... /usr/include/secure/_string.h
.. /usr/include/sys/stat.h
... /usr/include/sys/_types/_timespec.h
... /usr/include/sys/_types/_blkcnt_t.h
... /usr/include/sys/_types/_blksize_t.h
... /usr/include/sys/_types/_dev_t.h
... /usr/include/sys/_types/_ino_t.h
... /usr/include/sys/_types/_mode_t.h
... /usr/include/sys/_types/_nlink_t.h
... /usr/include/sys/_types/_gid_t.h
... /usr/include/sys/_types/_time_t.h
... /usr/include/sys/_types/_s_ifmt.h
.. /usr/include/unistd.h
... /usr/include/sys/unistd.h
.... /usr/include/sys/_types/_posix_vdisable.h
.... /usr/include/sys/_types/_seek_set.h
... /usr/include/sys/_types/_useconds_t.h
.. /Users/jonathanleffler/inc/debug.h
... /Users/jonathanleffler/inc/kludge.h
.. /Users/jonathanleffler/inc/emalloc.h
.. list.h
.. /Users/jonathanleffler/inc/sastrings.h
.. /Users/jonathanleffler/inc/stderr.h
... /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include/stdarg.h
. /Users/jonathanleffler/inc/getopt.h
Multiple include guards may be useful for:
/opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/syslimits.h
/usr/include/assert.h
/usr/include/errno.h
/usr/include/machine/limits.h
/usr/include/secure/_stdio.h
/usr/include/secure/_string.h
/usr/include/sys/_posix_availability.h
/usr/include/sys/_symbol_aliasing.h
/usr/include/sys/_types/_seek_set.h
$

, которая перечисляет 110 заголовков; повторяются только пять:

2 /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include-fixed/limits.h
2 /opt/gcc/v9.2.0/lib/gcc/x86_64-apple-darwin18.7.0/9.2.0/include/stdarg.h
2 /usr/include/machine/_mcontext.h
2 /usr/include/sys/_types/_intptr_t.h
2 /usr/include/sys/_types/_wchar_t.h

В других проектах, над которыми я работаю, повторений много. Если взять один исходный файл, более или менее произвольно (я знаю, что это большой файл; я не думаю, что он худший), то есть список заголовков, включенных 4 или более раз - многие включаются 2 и 3 раза. Общее количество строк заголовка из -H для этого файла составляет 592. Специфичные для проекта c имена каталогов и файлов были изменены, чтобы защитить невинных - и имена файлов были замаскированы с realpath(2), чтобы иметь дело с особенностями c использование имен стилей ../subdir/header.h в исходном коде и во включенных заголовках, которые -H расширяются до имен, таких как:

../incl/../subdir1/../subdir1/../subdir2/../subdir2/header27.h

Количество:

  4 /usr/include/errno.h
  4 /usr/include/time.h
  4 /opt/project/incl/header1.h
  4 /opt/project/incl/header2.h
  4 /opt/project/subdir/header3.h
  4 /opt/project/subdir/header4.h
  4 /opt/project/subdir/header5.h
  5 /opt/project/incl/header6.h
  5 /opt/project/subdir/header7.h
  6 /opt/project/subdir/header8.h
  6 /opt/project/subdir/header9.h
  6 /work5/gcc/v9.2.0/lib/gcc/x86_64-pc-linux-gnu/9.2.0/include-fixed/limits.h
  7 /opt/project/subdir/header10.h
 14 /usr/include/bits/wordsize.h
 14 /opt/project/subdir/header11.h
 22 /work5/gcc/v9.2.0/lib/gcc/x86_64-pc-linux-gnu/9.2.0/include/stddef.h
...