Сделать файл для большей структуры каталогов - PullRequest
5 голосов
/ 20 февраля 2011

У меня есть несколько каталогов с подкаталогами, содержащими файлы c или asm, и я хочу, чтобы все они были скомпилированы / собраны и затем связаны.Я не особенно требователен к объектным файлам (например, к специальной папке bin или в папке src), пока make clean удаляет их все.

Структура будет выглядеть примерно так:

/src
    /dir1
        /dir1_1
            +file1_1.s
            +file1_2.s
        +file1.s
    /dir2
        +file2.c

Я уверен, что есть какой-то простой способ создать make-файл, который компилирует все файлы, и мне не нужно указывать, где он должен выглядеть (сборка всех файлов в одном каталоге возможна с использованием подстановочных знаков, но что тогда?).1006 *

Ответы [ 2 ]

5 голосов
/ 20 февраля 2011

Выполните в Google поиск по запросу «рекурсивный код считается вредоносным». Вы найдете оригинальную статью, в которой постулируется, что рекурсивная процедура make является плохим способом ведения бизнеса, и вы найдете некоторые ссылки на другие места, в которых обсуждается обоснованность предложения.

В принципе, существует два способа построения в иерархии каталогов (с make).

  1. Рекурсивный make: каждый каталог содержит make-файл, который встраивается в подкаталоги, а затем встраивается в текущий каталог.
  2. Нерекурсивная сборка: сборочный файл включает в себя все зависимые сборочные файлы, создает полную структуру зависимостей для всего проекта и создает только необходимое программное обеспечение.

Я обычно работаю над продуктом, в котором основная последовательность сборки управляется гибридной системой, которая использует сценарий оболочки и один make-файл для каждого каталога. Один раздел продукта управляется make-файлом 'RMCH'; большая часть этого не. Сценарий сборки работает с фазами сборки, упорядочивает каталоги и запускает make в каждом каталоге, когда это необходимо. (Исходный код находится в 20k + файлах, распределенных по множеству каталогов - это большой проект / продукт.)

Я также преобразовал небольшой по размеру проект (около 20 релевантных каталогов и около 400 исходных файлов) для работы с RMCH (из системы script + makefile-per-directory). Сначала это было немного ошеломляюще, но теперь все работает довольно аккуратно. Правильно ли я это сделал, открыто для обсуждения; это было в основном учебное упражнение, хотя я также проделал некоторую работу по изменению кода для работы с современной библиотекой curses вместо архаичной библиотеки BSD, которая использовалась как часть кода (архаичной, как в винтажном 1982 году - код был последний серьезно разрабатывался примерно в 1986 г.) и в целом обновлялся до современных (стандартных С) стандартов. Это был также шанс поработать с git - так что, в целом, достаточно обширный опыт обучения.

Если вы можете обернуть свой мозг вокруг RMCH, это хорошая система. Если все сделано правильно, с полным и точным отслеживанием зависимостей, он удаляет догадки из последовательности сборки и работает быстро. Однако перенести на него даже проект среднего размера - довольно тяжелая работа - это будет непростой задачей для основного продукта, над которым я работаю, хотя система вполне может извлечь из этого выгоду.

Альтернативой является поиск других альтернатив make, таких как cmake, rake, scons, bras, imake или ant или что-либо еще, что вам нравится. Большинство из них легко обнаружить с помощью поиска Google; самый сложный - bras, который основан на Tcl (как в Tcl / Tk), но, вероятно, в настоящее время в основном мертв И imake упоминается скорее для полноты, чем для серьезного предложения. Вы также можете посмотреть на GNU Autotools. Те не покидают make; они строят на вершине make.

4 голосов
/ 20 февраля 2011

Если ваш проект достаточно мал, вам может понадобиться использовать один созданный вручную make-файл вместо более сложной системы сборки: посмотрите страницу руководства по функциям преобразования , чтобы узнать, что возможно.

Ваш пример проекта может быть скомпилирован со следующим нерекурсивным make-файлом:

targets = $(patsubst %$(1),%$(2),$(foreach dir,$(3),$(wildcard $(dir)/*$(1))))

asmdirs := src/dir1 src/dir1/dir1_1
cdirs := src/dir2

asmobjects := $(call targets,.s,.o,$(asmdirs))
cobjects := $(call targets,.c,.o,$(cdirs))

.PHONY : all clean

all : $(asmobjects) $(cobjects)

clean :
    rm -f $(asmobjects) $(cobjects)

$(cobjects) : %.o : %.c
    gcc -o $@ -c $<

$(asmobjects) : %.o : %.s
    gcc -o $@ -c $<

Однако, поскольку make может получить доступ к оболочке, вы также можете использовать стандартные инструменты Unix, такие как find, вместо несколько ограниченных встроенных функций, например

asmsources := $(shell find src -name '*.s')
csources := $(shell find src -name '*.c')

asmobjects := $(asmsources:.s=.o)
cobjects := $(csources:.c=.o)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...