Инструменты статического анализа включения заголовочного файла?

26
задан Community 23 May 2017 в 11:54
поделиться

8 ответов

Вывод gcc -w -H <file> может быть полезен (если вы проанализируете его и введете некоторые значения), то здесь -w будет подавлять все предупреждения, с которыми может быть неудобно иметь дело.

Из документации gcc:

-H

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

Вывод выглядит так:

. /usr/include/unistd.h
.. /usr/include/features.h
... /usr/include/bits/predefs.h
... /usr/include/sys/cdefs.h
.... /usr/include/bits/wordsize.h
... /usr/include/gnu/stubs.h
.... /usr/include/bits/wordsize.h
.... /usr/include/gnu/stubs-64.h
.. /usr/include/bits/posix_opt.h
.. /usr/include/bits/environments.h
... /usr/include/bits/wordsize.h
.. /usr/include/bits/types.h
... /usr/include/bits/wordsize.h
... /usr/include/bits/typesizes.h
.. /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stddef.h
.. /usr/include/bits/confname.h
.. /usr/include/getopt.h
. /usr/include/stdio.h
.. /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stddef.h
.. /usr/include/libio.h
... /usr/include/_G_config.h
.... /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stddef.h
.... /usr/include/wchar.h
... /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stdarg.h
.. /usr/include/bits/stdio_lim.h
.. /usr/include/bits/sys_errlist.h
Multiple include guards may be useful for:
/usr/include/bits/confname.h
/usr/include/bits/environments.h
/usr/include/bits/predefs.h
/usr/include/bits/stdio_lim.h
/usr/include/bits/sys_errlist.h
/usr/include/bits/typesizes.h
/usr/include/gnu/stubs-64.h
/usr/include/gnu/stubs.h
/usr/include/wchar.h
24
ответ дан Spudd86 23 May 2017 в 11:54
поделиться

Если вы используете gcc / g ++, опция -M или -MM выведет строку с информацией, которую вы ищете. (Первый будет включать системные заголовки, а второй - нет. Существуют и другие варианты; см. Руководство.)

$ gcc -M -c foo.c
foo.o: foo.c /usr/include/stdint.h /usr/include/features.h \
  /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \
  /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \
  /usr/include/bits/wchar.h

Вам нужно будет удалить foo.o: foo.c в начале, но остальное список всех заголовков, от которых зависит файл, поэтому не составит труда написать сценарий для их сбора и обобщения.

Конечно, это предложение полезно только в Unix и только в том случае, если у кого-то нет идеи получше. : -)

3
ответ дан Nemo 23 May 2017 в 11:54
поделиться

Несколько вещей-

  • используют «только препроцесс», чтобы посмотреть на ваш выход препроцессора. Опция gcc -E, другие компиляторы также имеют функцию

  • используют предварительно скомпилированные заголовки.

  • У gcc есть опции -verbose и --trace, которые также отображают полное дерево включения, MSVC имеет опцию / showInclude, найденную на странице свойств Advanced C ++

Также, Отображение иерархии #include для файла C ++ в Visual Studio

3
ответ дан Community 23 May 2017 в 11:54
поделиться

GCC имеет флаг -M, который выведет список зависимостей для данного исходного файла. Вы можете использовать эту информацию, чтобы выяснить, какие из ваших файлов имеют наибольшую зависимость, от каких файлов больше всего зависит и т. Д.

Посетите справочную страницу для получения дополнительной информации. Есть несколько вариантов -M.

1
ответ дан Carl Norum 23 May 2017 в 11:54
поделиться

Лично я не знаю, есть ли инструмент, который скажет «Удалить этот файл». Это действительно сложный вопрос, который зависит от многих вещей. Глядя на дерево включенных утверждений, вы наверняка сведете вас с ума ... Это сведет меня с ума и испортит мне глаза. Существуют более эффективные способы сократить время компиляции.

  1. Отключите ваши методы класса.
  2. После удаления их, повторно изучите включенные операторы и попытайтесь удалить их. Обычно полезно удалить их и начать заново.
  3. Предпочитаю использовать предварительные декларации в максимально возможной степени. Если вы деинлайн-методы в заголовочных файлах, вы можете сделать это много.
  4. Разбейте большие заголовочные файлы на более мелкие. Если класс в файле используется чаще, чем большинство, поместите его в заголовочный файл сам по себе.
  5. 1000 переводных единиц не очень много на самом деле. У нас между 10-20 тысячами. :)
  6. Получите Incredibuild, если время компиляции все еще слишком велико.
1
ответ дан C Johnson 23 May 2017 в 11:54
поделиться

Я слышал, что есть некоторые инструменты, но я ими не пользуюсь.

Я создал какой-то инструмент https://sourceforge.net/p/headerfinder , может быть, это полезно. К сожалению, это инструмент "HOME MADE" со следующими проблемами:

  • Разработано в Vb.Net
  • Исходный код нужно скомпилировать
  • Очень медленно и потребляет память.
  • Помощь недоступна.
0
ответ дан Oz123 23 May 2017 в 11:54
поделиться
  • 1
    Это было единственным способом, которым я мог получить его работающий на сценарий, который я использовал. – Nick W. 26 July 2017 в 18:59
  • 2
    Это было единственным способом, которым я мог получить его работающий на сценарий, который я использовал. – Nick W. 26 July 2017 в 18:59
  • 3
    Это было единственным способом, которым я мог получить его работающий на сценарий, который я использовал. – Nick W. 26 July 2017 в 18:59
  • 4
    Это было единственным способом, которым я мог получить его работающий на сценарий, который я использовал. – Nick W. 26 July 2017 в 18:59
  • 5
    Это было единственным способом, которым я мог получить его работающий на сценарий, который я использовал. – Nick W. 26 July 2017 в 18:59

GCC Имеет флаг (-save-temps), с помощью которого вы можете сохранять промежуточные файлы. Это включает в себя файлы .ii, которые являются результатами препроцессора (так до компиляции). Вы можете написать скрипт для его анализа и определения веса / стоимости / размера того, что включено, а также дерева зависимостей.

Я написал скрипт Python для этого (общедоступно здесь: https://gitlab.com/p_b_omta/gcc-include-analyzer ).

0
ответ дан Paul Omta 23 May 2017 в 11:54
поделиться
  • 1
    Почему doesn' t Visual Studio включают ссылку автоматически, когда мы непосредственно говорим его using System.Management;?: ( – Filip Vondrášek 27 September 2013 в 07:36
  • 2
    Почему doesn' t Visual Studio включают ссылку автоматически, когда мы непосредственно говорим его using System.Management;?: ( – Filip Vondrášek 27 September 2013 в 07:36
  • 3
    Почему doesn' t Visual Studio включают ссылку автоматически, когда мы непосредственно говорим его using System.Management;?: ( – Filip Vondrášek 27 September 2013 в 07:36
  • 4
    Почему doesn' t Visual Studio включают ссылку автоматически, когда мы непосредственно говорим его using System.Management;?: ( – Filip Vondrášek 27 September 2013 в 07:36
  • 5
    Почему doesn' t Visual Studio включают ссылку автоматически, когда мы непосредственно говорим его using System.Management;?: ( – Filip Vondrášek 27 September 2013 в 07:36

У «Большого масштаба C ++ Software Design» Джона Лакоса были инструменты, которые извлекали зависимости времени компиляции среди исходных файлов.

К сожалению, их хранилище на сайте Аддисона-Уэсли пропало (вместе с самим сайтом AW), но я нашел тарбол здесь: http://prdownloads.sourceforge.net/introspector/LSC-rpkg-0.1. tgz? download

Я нашел это полезным несколько работ назад, и он достоин того, чтобы быть свободным.

Кстати, если вы еще не читали книгу Лакоса, похоже, ваш проект принесет пользу. (Текущее издание немного устарело, но я слышал, что у Лакоса есть другая книга, выходящая в 2012 году.)

1
ответ дан Gnawme 23 May 2017 в 11:54
поделиться