Как реализовать файл Makefile, который запоминает последнюю цель сборки?
Допустим, у вас есть Makefile с двумя псевдо-целями, 'all' и 'debug'. Цель "debug" предназначена для построения того же проекта, что и "all", за исключением некоторых различных параметров компиляции (например,- ggdb). Поскольку целевые объекты используют разные переключатели компиляции, Вам, очевидно, нужно перестроить весь проект, если вы переключаетесь между ними. Но GNUmake не естественно признать это.
Так что если вы наберете make all
, то получите
Building ...
...
Тогда, если вы наберете make debug
, Вы get
make: Nothing to be done for `debug'.
Итак, мой вопрос: как вы реализуете чистое решение в файле Makefile, чтобы заметить, что последняя сборка использовала другую псевдо-цель или другие ключи компиляции, чем та, которую вы хотите в данный момент? если они отличаются, файл Makefile перестроит все.
3 ответа:
Поместите продукты сборки в разные деревья каталогов (сохраняя при этом одну копию исходного кода, конечно). Таким образом, вы всегда просто короткая компиляция из последней сборки, будь то debug или release (или даже другие). И никакой возможности запутаться тоже.
EDIT
Набросок вышесказанного.
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
. Есть много очевидных котельных плит просто кричала, чтобы прибрались.
Сохранение наборов вариантов объектных файлов (как в решении 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
Есть и другие варианты этой идеи; у вас может быть небольшой файл, содержащий настройки флага, который будет создан файлом makefile и
include
. Это было бы умно, но не намного чище, чем это.