Автоматическое обнаружение зависимостей C

Мне нужно написать документацию для моего текущего проекта, в которой перечислены все .c файлы, и для каждого из них перечисляется каждый .h файл, который прямо или косвенно включен в этот файл.

Это большой проект, и хотя у нас есть Makefiles, которые теоретически имеют эту информацию, эти Makefile иногда ошибочны (мы унаследовали этот проект от другой компании). Нам часто приходилось делать make clean ; make, чтобы наши изменения действительно отражались в перекомпиляции, поэтому я не хочу полагаться на эти Make файлы.

Итак, есть ли инструмент, который позволяет нам указать имя файла .c и путь include и сообщить ли он нам все файлы .h, которые прямо или косвенно включены в файл .c? У нас нет ничего странного, как

#define my_include "some_file.h"
#include my_include

поэтому инструмент не должен быть идеальным. Все, что искало файлы .c и .h во включенном пути для регулярных включений, будет достаточно хорошим.

Ответ 1

То, что я делаю в моем Makefile,

SRCS=$(wildcard *.c)

depend: $(SRCS)
    gcc -M $(CFLAGS) $(SRCS) >depend

include depend

Это означает, что если какой-либо из исходных файлов будет обновлен, будет выполняться правило зависимости и использовать gcc -M для обновления файла с именем depend. Затем он включается в make файл, чтобы обеспечить правила зависимостей для всех исходных файлов.

Make будет проверять, что файл обновлен до его включения, поэтому это правило зависимостей будет выполняться при необходимости, когда вы запустите make, не требуя сделать "make depend".

Это будет выполняться в любое время, когда любой файл будет изменен. Я никогда не обнаружил, что это проблема, но если у вас было огромное количество файлов в каталоге, это может занять слишком много времени, и в этом случае вы можете попробовать иметь один файл зависимостей для исходного файла, например:

SRCS=$(wildcard *.c)
DEPS=$(SRCS:.c=.dep)

%.dep : %.c
    gcc -M $(CFLAGS) $< >[email protected]

include $(DEPS)

Обратите внимание, что вы можете использовать -MM вместо -M, чтобы не включать заголовки системы.

Ответ 2

"gcc -M file.c" делает то, что вам нужно.

Ответ 3

Альтернативой gcc -M является fastdep. Fastdep автор сообщает, что fastdep будет в десять раз быстрее, чем gcc -M. Если проект требует времени, чтобы построить, возможно, стоит заглянуть назад.

Ответ 4

Использовать SCons

$ scons --tree=all
scons: Reading SConscript files ...

scons: done reading SConscript files.
scons: Building targets ...
scons: `.' is up to date.
+-.
  +-SConstruct
  +-app
  | +-test.o
  | | +-test.c
  | | +-/include/PCI_1149_1.h
  | | +-/include/Pci.h
  | | +-/usr/bin/gcc
  | +-/usr/bin/gcc
  | +-/lib/libpci1149_64.a
  ...

Ответ 5

В MSVC (по крайней мере, в 2005 и 2008 годах, возможно, в других версиях, но не в VC6) вы можете заставить компилятор рассказать обо всех файлах, которые были включены во время компиляции. Результат довольно многословный, но полный и довольно простой для анализа с человеческими глазами.

В разделе "Настройки проекта" перейдите на вкладку "C/С++ > Дополнительно" и переключите "Показать включает", затем перестройте проект с нуля.