Использование make для сборки нескольких двоичных файлов - PullRequest
1 голос
/ 16 февраля 2012

Я хочу создать Makefile (в родительском dir) для вызова нескольких других Makefile (в sub dir), чтобы я мог создать несколько двоичных файлов (по одному на sub sub dir проекта), вызывая только один родительский Makefile.

Мое исследование было затруднено поиском множества материалов по рекурсивным файлам Makefile, но я думаю, что именно здесь вы пытаетесь встроить несколько файлов Makefile для каталогов в один двоичный файл?

Может быть, то, что я хочу сделать, лучше обрабатывается сценарием оболочки, возможно, вызывая make в каждом подкаталоге по очереди, но я подумал, что Makefile может быть более элегантным решением?

с благодарностью получили любые указатели

PS с использованием linux и цепочки инструментов GNU

Ответы [ 4 ]

2 голосов
/ 18 февраля 2012

Решение for for, данное в первом ответе выше, на самом деле не должно использоваться, как есть.В этом методе, если один из ваших подзадач завершится неудачно, сборка не завершится неудачей (как и должно быть), а продолжится с другими каталогами.Не только это, но и конечный результат сборки будет таким, каким был код выхода последней сборки подкаталога, поэтому, если это удалось, сборка завершится успешно, даже если какой-то другой подкаталог не удался.Не хорошо !!

Вы можете исправить это, выполнив что-то вроде этого:

all: 
        @for dir in $(SUBDIRS); \
        do \
            $(MAKE) -C $${dir} $@ || exit $$?; \
        done

Однако теперь у вас возникла обратная проблема: если вы запускаете "make -k" (продолжайте, даже если естьошибки), то в этой ситуации это не будет выполнено.Он все равно завершится при ошибке.

Дополнительная проблема с обоими вышеупомянутыми методами заключается в том, что они сериализуют сборку всех подкаталогов, поэтому, если вы включите параллельные сборки (с опцией make -j), это произойдет тольков пределах одного подкаталога, а не во всех подкаталогах.

Eregrith и sinsedrix имеют решения, которые ближе к тому, что вы хотите, хотя, к вашему сведению, вам никогда не следует использовать «make», когда вы вызываете рекурсивный вызов make.Как в примере с johfel, вы ВСЕГДА должны использовать $ (MAKE).

Что-то вроде этого - то, что вы хотите:

SUBDIRS = subdir1 subdir1 subdir3 ...

all: $(addprefix all.,$(SUBDIRS))
all.%:
        @ $(MAKE) -C '$*' '$(basename $@)'
.PHONY: $(addprefix all.,$(SUBDIRS))

И, конечно, вы можете добавить больше строф, подобных этому, для других целей, таких каккак "установить" или что-то еще.Есть еще более причудливые способы обработки подкаталогов сборки с любой общей целью, но для этого требуется немного больше деталей.

Если вы хотите поддерживать параллельные сборки, вам может потребоваться объявить зависимости на этом уровне, чтобы избежать параллельных сбороккаталоги, которые зависят друг от друга.Например, в приведенном выше примере, если вы не можете собрать subdir3 до тех пор, пока не завершены оба subdir1 и subdir2 (но это нормально для параллельного создания subdir1 и subdir2), вы можете добавить что-то подобное в свой make-файл:

all.subdir3 : all.subdir1 all.subdir2
0 голосов
/ 16 февраля 2012

Вы можете вызывать цели в подкаталоге makefiles через

all: 
    $(MAKE) -C subdirectory1 $@
    $(MAKE) -C subdirectory2 $@
   ...

или лучше

SUBDIRS=subd1 subd2 subd3

all: 
    @for dir in $(SUBDIRS); \
    do \
      $(MAKE) -C $${dir} $@; \
    done
0 голосов
/ 16 февраля 2012

вы действительно должны использовать cmake для автоматического создания Makefile из заданного CMakeLists.txt файла конфигурации.

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

0 голосов
/ 16 февраля 2012

Каждый make-файл может иметь несколько целей, это все еще верно для рекурсивных make-файлов, обычно записывается:

all: target1 target2 target3

target1 :
    make -C subdir

Тогда make all

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...