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

B Организация иерархии каталогов в сложных проектах


Для сложных проектов, состоящих из большого количества файлов, я предпочитаю более сложную организацию каталогов, чем та, которая приводилась в качестве примера в разделе 1.7. "Разнесение разных версий программы по отдельным директориям". Основная идея заключается в том, чтобы файлы с разным "назначением" помещались в разные каталоги. В моих проектах дерево каталогов выглядит примерно так:
  • имя_проекта /
    • bin /
      • linux_debug /
      • linux_release /
      • windows_debug /
      • windows_release /
    • doc /
      • README.txt
    • project /
      • Makefile
      • make_debug
      • make_release
    • src /


В каталог bin помещаются результаты компиляции - объектные и исполняемые файлы, библиотеки и тому подобное. Этот каталог можно "безболезненно" удалить - при следующей компиляции он будет автоматически создан заново. В этом каталоге каждая из возможных конфигураций программы имеет свою отдельную директорию. Как правило, я делаю четыре конфигурации программы - для каждой из двух операционных систем (Linux и Windows) имеется отладочная и рабочая версии программы.

В директорию doc я помещаю различные текстовые файлы - документацию, замечания, список ошибок и тому подобное. Здесь же располагается и файл README.txt.

В каталоге project находится make-файл проекта и командные файлы, используемые для сборки программы в разных конфигурациях.

В каталог src я помещаю исходные тексты программы. Внутри директории src имеется своя иерархия каталогов, отражающая логическую структуру программы.

Вот пример make-файла, который работает с подобной структурой директорий проекта: # # example_7-complex/project/Makefile # # Пример проекта со "сложной" структурой директорий # program_name := iEdit source_dirs := . Editor TextLine include_dirs := /c/aproj/lib /c/aproj/lib/linux link_flags := -static source_dirs := $(addprefix ../../src/, $(source_dirs) ) source_files := $(wildcard $(addsuffix /*.cpp, $(source_dirs) ) ) object_files := $(notdir $(source_files) ) object_files := $(object_files:.cpp=.o) $(program_name): $(object_files) gcc $^ -o $@ $(link_flags) -pipe VPATH := $(source_dirs) %.o: %.cpp gcc $< -c $(compile_flags) $(addprefix -I, $(include_dirs)) $(addprefix -I, $(source_dirs)) -MD -pipe 2>log include $(wildcard *.d) Список директорий, где располагаются файлы с исходными текстами (source_dirs), задается относительно каталога src. Вот как выглядит командный файл, собирающий отладочную версию программы: mkdir -p ../bin/linux_debug make compile_flags="-O0 -g" \ --directory=../bin/linux_debug \ --makefile=../../project/Makefile Командный файл, собирающий рабочую версию программы выглядит аналогично: mkdir -p ../bin/linux_release make compile_flags="-O3 -funroll-loops -fomit-frame-pointer" \ --directory=../bin/linux_release \ --makefile=../../project/Makefile

Содержание раздела