Как реализовать Makefile, который запоминает последнюю цель сборки? - PullRequest
6 голосов
/ 07 марта 2011

Допустим, у вас есть Makefile с двумя псевдо-целями, 'all' и 'debug'.Цель debug предназначена для создания того же проекта, что и all, за исключением нескольких различных параметров компиляции (например, -ggdb).Поскольку цели используют разные ключи компиляции, вам, очевидно, нужно перестроить весь проект, если вы переключаетесь между ними.Но GNUmake не распознает это естественным образом.

Так что если вы наберете make all, вы получите

Building ...
...

Тогда, если вы наберете make debug, вы получите

make: Nothing to be done for `debug'.

Итак, мой вопрос: как реализовать чистое решение в Makefile, чтобы заметить, что в последней сборке использовалась другая псевдо-цель или другие параметры компиляции, чем тот, который вы хотите в данный момент? Если они отличаются, Makefile перестроит все.

Ответы [ 3 ]

2 голосов
/ 07 марта 2011

Поместите продукты сборки в разные деревья каталогов (сохраняя, конечно, одну копию исходного кода).Таким образом, вы всегда просто короткая компиляция из современной сборки, будь то отладка или выпуск (или даже другие).Также нет никакой путаницы.

РЕДАКТИРОВАТЬ

Эскиз выше.

src := 1.c 2.c 3.c
bare-objs := ${src:%.c=%.o}
release-objs := ${bare-objs:%=Release/%}
debug-objs := ${bare-objs:%=Debug/%}

Release/prog: ${release-objs}
Debug/prog: ${debug-objs}

${release-objs}: Release/%.o: %.c # You gotta lurve static pattern rules
    gcc -c $< -o $@

${debug-objs}: Debug/%.o: %.c
    gcc -c $< -o $@

Release/prog Debug/prog:
    gcc $^ -o $@

.PHONY: all
all: Release/prog ; echo $@ Success

.PHONY: debug
debug: Debug/prog ; echo $@ Success

(Отказ от ответственности: не проверено, и даже не выполнить через make.)

Вот, пожалуйста.Это даже -j безопасно, так что вы можете сделать make -j5 all debug.Есть много очевидных котловых плит, которые просто кричат ​​о уборке.

1 голос
/ 07 марта 2011

Хранение наборов вариантов объектных файлов (как в решении bobbogo), вероятно, лучший способ, но если по какой-то причине вы не хотите этого делать, вы можете использовать пустые файлы в качестве маркеров, чтобы указать, каким образом вы в последний раз построилиисполняемый файл:

%-marker:
        @rm -f $(OBJECTS) *-marker
        @touch $@

debug: GCCFLAGS += -ggdb

debug: SOMEOTHERFLAG = WHATEVER

all debug: % : %-marker
        @echo making $@
        @$(MAKE) -S GCCFLAGS='$(GCCFLAGS)' SOMEOTHERFLAG='$(SOMEOTHERFLAG)' main

Есть и другие варианты этой идеи;у вас может быть небольшой файл с настройками флага, который создаст make-файл и include.Это было бы умно, но на самом деле не чище, чем это.

0 голосов
/ 07 марта 2011

Единственное чистое решение - включить разницу в целевые имена.Например, вы можете определить переменную $(DEBUG) и последовательно использовать ее во всех целях, которые зависят от этапа компиляции.

...