Иногда надо сгенерить исходники. Часто это yacc/bison+flex, в моём случае asn1c. С помощью функции $(wildcard) можно получить список сгенеренных .c файлов:
| Код | SOURCES = $(wildcard asngen/*.c)
|
Из него можно получить список .o файлов:
| Код | OFILES = $(SOURCES:.c=.o)
|
и в конце:
Но если сгенерированных файлов ещё нет, $(wildcard) вернёт пустой список. http://stackoverflow.com/questions/10164924/code-generation-and-make-rule-expansion, что для таких случаев можно сделать так, чтобы make сам перезапускался после генерации файлов.
| Цитата |
| Код | # Get the list of auto-generated sources. If this file doesn't exist, or if it is older # than auto.template, it will get built using the rule defined below, according to the # standard behavior of GNU make. If autosrcs.mk is rebuilt, GNU make will automatically # restart itself after autosrcs.mk is updated.
include autosrcs.mk
# Once we have the list of auto-generated sources, getting the list of targets to build # from them is a simple pattern substitution.
TARGETS=$(patsubst %.src,%.target,$(AUTO_SRCS))
all: $(TARGETS)
# Rule describing how to build autosrcs.mk. This generates the sources, then computes # the list of autogenerated sources and writes that to autosrcs.mk in the form of a # make variable. Note that we use *shell* constructs to get the list of sources, not # make constructs like $(wildcard), which could be expanded at the wrong time relative # to when the source files are actually created.
autosrcs.mk: auto.template ./generate-sources auto.template echo "AUTO_SRCS=`echo *.src`" > autosrcs.mk
# How to build *.target files from *.src files.
%.target: %.src @echo 'build $< > $@'
|
|
С этим примером проблема в том, что при вызове 'make clean' исходники будут сгенерены всё равно. Из мануала make:
| Цитата | An example of appropriate use is to avoid including .d files during clean rules (see Automatic Prerequisites), so make won't create them only to immediately remove them again:
| Код | sources = foo.c bar.c ifneq ($(MAKECMDGOALS),clean) include $(sources:.c=.d) endif
|
|
Но здесь не учитывается то, что кроме "clean" может быть несколько других целей. Например, 'make clean all' - обычный способ пересобрать проект. Здесь надо сначала всё стереть, потом сгенерировать исходники, потом рестартовать make, и при этом не вызвать 'clean' снова.
|