2017-02-16 36 views
2

Я изучаю make-файлы и не могу просто обернуть голову вокруг этой проблемы, которую у меня есть, и хотел бы понять, как/почему это не удается.Правила шаблона Makefile не работают

У меня есть полдюжины файлов erlang в каталоге src. Я хочу скомпилировать их в каталог ebin, не требуя определения правила для каждого из них. Согласно документации Gnu make, pattern rules should be right up my alley.

Однако со следующим make-файлом все, что я получаю от make, - make: *** No targets. Stop. Почему это?

ebin/%.beam: src/%.erl 
    mkdir -p ebin 
    erlc -o ebin $< 

Edit: На основе this answer, теперь я понимаю, что я должен был бы явно объявлять цели, например, с помощью make ebin/cmplx.beam. Тем не менее, я до сих пор не понимаю, как я должен писать свой make-файл, чтобы получить мое желаемое поведение - поскольку у меня есть полдюжины целей (а в других проектах - еще больше), это кажется ненужной проблемой. Не существует способа определить цели на основе имен исходных файлов?

+0

Возможный дубликат [правило шаблона шаблона файла не работает?] (Http://stackoverflow.com/questions/5155510/makefile-pattern-rule-fails) –

+1

Make-файлы являются старыми и слишком низкоуровневыми (это означает: слишком легко сделать человеческие ошибки) способ создания программного обеспечения. Для Erlang, если вы действительно хотите придерживаться Make-файлов, я предлагаю очень хороший https://erlang.mk. Если вы хотите рассмотреть другие варианты, то https://www.rebar3.org. Вне Erlang, рассмотрите https://cmake.org/, который будет генерировать либо Makefiles, либо (лучше!) Настройки ниндзя. –

ответ

2

Целевое правило говорит, что делать, когда это необходимо, чтобы произвести beam файл в каталоге ebin, и существует соответствующий erl файл в каталоге src, он может использовать erlc.

Однако это не говорит о том, что это то, что нужно. Вы можете явно указать сделать то, что ему нужно сделать, придав ему цель в командной строке:

make ebin/foo.beam 

Если вы не даете целей в командной строке, сделать подберете первое правило, не в шаблоне makefile в качестве цели. Однако ваш make-файл не имеет никаких правил без шаблонов, поэтому нет цели.

То, что вы, вероятно, хотите, что для каждого существующего erl файла в src, сделать следует рассмотреть соответствующий beam файл в ebin быть мишенью. Вы можете достичь этого путем вызова wildcard и patsubst:

erl_files=$(wildcard src/*.erl) 
beam_files=$(patsubst src/%.erl,ebin/%.beam,$(erl_files)) 

ebin/%.beam: src/%.erl 
     mkdir -p ebin 
     erlc -o ebin $< 

all: $(beam_files) 

(Вдавленные линии должны быть реальные физические вкладки, а не пространства.)

Таким образом, бег make восстановит все beam файлы, которые находятся вне Дата. all выбирается в качестве целевой цели по умолчанию, и это в свою очередь зависит от всех существующих beam существующих или потенциальных, каждый из которых, в свою очередь, зависит от соответствующего файла erl.

Этот трюк described in the GNU make manual.