Makefile для архивирования / связывания вместе автоматически сгенерированных исходных файлов - PullRequest
1 голос
/ 27 октября 2009

По сути, у меня есть файл 'blah.txt'. Эти файлы анализируются «компилятором» и из него генерируется N выходных файлов .c. Мне нужен make-файл, который из этого файла .txt сгенерирует файлы c, затем скомпилирует их все и заархивирует в libmystuff.a

Я думал о чем-то вроде этого:

all: dogen libmystuff.a

dogen: source.txt
    mycompiler $^

libmystuff.a: $(addsuffix .o, $(shell ls *.c))
    $(AR) rcs $@ $^

.PHONY: dogen

Но очевидно, что это не работает, потому что зависимости оцениваются в начале, и в этот момент * .c просто ничего не дает, поскольку их не существует.

Кто-нибудь видит, как этого добиться (без явного перечисления всех сгенерированных * .c)?

Ответы [ 3 ]

3 голосов
/ 27 октября 2009

Используйте часовой "makefile", чтобы заставить make перечитать make-файл и подставить правильный список в *.c:

include sources-sentry

sources-sentry: source.txt
    mycompiler $^
    touch $@

libmystuff.a: $(addsuffix .o, $(shell ls *.c))
    $(AR) rcs $@ $^
Директива

include используется для включения других make-файлов (как C * #include). Он имеет приятную особенность: если make-файл, который он включает, сам является целью, программа make сначала рассматривает его как цель и пытается выполнить обновление. Если он не обновлен, make вызывает команды, необходимые для его обновления, а затем перечитывает make-файл, подставляя все переменные снова .

Таким образом, если source.txt изменился с тех пор, как вы в последний раз обработали его (время записывается как метка времени источника-1019 * файла ), источники будут обновлены, а make будет вызван повторно *.c заменяется набором обновлений c-файлов.

2 голосов
/ 27 октября 2009

Если ваши файлы .c создаются только с помощью .txt, то вы можете позволить libmystuff.a зависеть от txt и вместо этого оценивать $ (shell ls * .c) в теле правила.

1 голос
/ 27 октября 2009

Павел Швед прав (*), вы должны перезапустить Make. Вот трюк, которым я горжусь. Он будет обрабатывать зависимости от объектов, которые могут еще не существовать, и не будет запускаться без необходимости.

SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)

all: libmystuff.a

ifeq ($(MAKELEVEL),0) 
libmystuff.a: source.txt
    mycompiler $^ 
    @$(MAKE) -s $@
else
libmystuff.a: $(OBJECTS)
    $(AR) rcs $@ $^ 
endif

(*) Мой старый враг, мы снова встретимся.

EDIT:
Если некоторые другие звонят , это делает ... Я не думал об этом. Но я думаю, что это решит это:

SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)

all: libmystuff.a

libmystuff.a: source.txt
    mycompiler $^ 
    @$(MAKE) -s phonyLib

.PHONY: phonyLib
phonyLib: $(OBJECTS)
    $(AR) rcs libmystuff.a $^ 

(Да, я знаю, если вы испытываете желание создать файл с именем "phonyLib", вы не сможете сделать это с этим make-файлом, но давайте не будем извращаться.)

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