Сделать вычисление подстановочного знака слишком рано? - PullRequest
0 голосов
/ 02 февраля 2010

У меня есть файл make, более или менее, следующей структуры, которая компилирует исходный код C ++:

.PHONY: all
all: compile_obj_files my_binary

# This rule generates the object files. It works fine afaik.
.PHONY: compile_obj_files
compile_obj_files:
    $(MAKE) --file=child.makefile

# my_binary is a real binary file that I wish to build.
my_binary: $(wildcard *.o)
    $(CC) $(wildcard *.o) -o my_binary

При первом запуске этот make-файл сгенерировал все объектные файлы, но $(wildcard *.o) вернул пустой список. При втором запуске он ничего не компилировал, как ожидалось, и $(wildcard *.o) действительно вернул все объектные файлы. Похоже, что $(wildcard *.o) выполняется перед созданием всех объектных файлов, несмотря на то, что правило my_binary всегда выполняется после compile_obj_files. Я сижу беспомощно в этом сценарии, не зная, что здесь не так (должно быть, глупо). Вы можете что-нибудь придумать?

1 Ответ

3 голосов
/ 02 февраля 2010

Вы действительно не должны использовать $(wildcard ...) внутри правил, а делать что-то вроде

MYSRC:=$(wildcard *.c)
MYOBJ:=$(patsubst %.c, %.o, $(MYSRC))

%.o: %.c
        $(CC) -c $< -o $@

my_binary: $(MYOBJ)
        $(CC) $^ -o $@

Таким образом, вы знаете, что MYSRC и MYOBJ совпадают. Также обратите внимание на использование $< для обозначения зависимости текущей цели и $@ для обозначения целевого имени файла текущей цели.

EDIT: изменено $< на $^ в шаге ссылки, чтобы включить все объектные файлы, а не только последний.

РЕДАКТИРОВАТЬ: Если вы не хотите извлекать исходные имена файлов из child.makefile, вы должны иметь возможность сделать что-то вроде этого:

.PHONY: all
all: 
    $(MAKE) --file=child.makefile
    $(MAKE) my_binary OBJS="$(wildcard *.o)"

my_binary: $(OBJS)
    $(CC) $< -o my_binary

Важной частью является то, что значение OBJS является постоянным при построении my_binary. Таким образом, вы четко разбиваете сборку на два этапа, и список объектных файлов читается перед выполнением второй сборки.

...