Эффективное использование GNU Make


Автоматическое построение зависимостей от заголовочных файлов - часть 2


Как видно из таблицы компилятор может работать двумя способами - в одном случае компилятор выдает только список зависимостей и заканчивает работу (опции -M и -MM). В другом случае компиляция происходит как обычно, только в дополнении к объектному файлу генерируется еще и файл зависимостей (опции -MD и -MMD). Я предпочитаю использовать второй вариант - он мне кажется более удобным и экономичным потому что:

  • При изменении какого-либо из исходных файлов будет построен заново лишь один соответствующий ему файл зависимостей
  • Построение файлов зависимостей происходит "параллельно" с основной работой компилятора и практически не отражается на времени компиляции

Из двух возможных опций -MD и -MMD, я предпочитаю первую потому что:

  • С помощью директивы #include я часто включаю не только "стандартные", но и свои собственные заголовочные файлы, которые могут иногда меняться (например, заголовочные файлы моей прикладной библиотеки LIB).
  • Иногда бывает полезно взглянуть на полный список включаемых в модуль заголовочных файлов, в том числе и "стандартных".

После того как файлы зависимостей сформированы, нужно сделать их доступными утилите make. Этого можно добиться с помощью директивы include. include $(wildcard *.d)

Обратите внимание на использование функции wildcard. Конструкция include *.d будет правильно работать только в том случае, если в каталоге будет находиться хотя бы один файл с расширением ".d". Если таких файлов нет, то make аварийно завершится, так как потерпит неудачу при попытке "построить" эти файлы (у нее ведь нет на этот счет ни каких инструкций!). Если же использовать функцию wildcard, то при отсутствии искомых файлов, эта функция просто вернет пустую строку. Далее, директива include с аргументом в виде пустой строки, будет проигнорирована, не вызывая ошибки. Теперь можно составить новый вариант make-файла для моего "гипотического" проекта:

  • example_3-auto_depend /
    • main.cpp
    • main.h
    • Editor.cpp
    • Editor.h
    • TextLine.cpp
    • TextLine.h
    • Makefile
Вот как выглядит Makefile из этого примера: # # example_3-auto_depend/Makefile # # Пример автоматического построения зависимостей от заголовочных файлов # iEdit: $(patsubst %.cpp,%.o,$(wildcard *.cpp)) gcc $^ -o $@ %.o: %.cpp gcc -c -MD $< include $(wildcard *.d) После завершения работы make директория проекта будет выглядеть так:
  • example_3-auto_depend /
    • iEdit
    • main.cpp
    • main.h
    • main.o
    • main.d
    • Editor.cpp
    • Editor.o
    • Editor.d
    • Editor.h
    • TextLine.cpp
    • TextLine.o
    • TextLine.d
    • TextLine.h
    • Makefile
Файлы с расширением ".d" - это сгенерированные компилятором GCC файлы зависимостей.


- Начало -  - Назад -  - Вперед -