2010-11-09 2 views
4

Я пытаюсь понять, почему я не могу указать цель как находящуюся в другом каталоге.Как указать цель makefile в другом каталоге?

Я пытаюсь сгенерировать некоторые php-классы из json-файлов, но я изменил строку, которая фактически генерирует php для фиктивного утверждения эха, поэтому кто-то еще может просто скопировать пасту и проверить, чувствуют ли они себя очень щедрыми.

Есть две вещи, чтобы добавить в каталог, содержащий Makefile:

  • Файл фиктивная зависимость называется PatientDbPath.json
  • Каталог окликнул

Если у меня есть Makefile в том числе:

.SUFFIXES: .php .json 
.json.php: 
    echo "HelloMe" > PatientDbPath.php 

PatientDbPath.php: PatientDbPath.json 

clean: 
    $(RM) PatientDbPath.php 

Тогда все работает, когда я запустить make; PatientDbPath.php создан правильно и в следующий раз я бегу сделать, я получаю сообщение make: 'PatientDbPath.php' is up to date.

Однако я хочу, чтобы создать файл PHP в отдельном каталоге, так что я обновил свой Makefile на следующее:

.SUFFIXES: .php .json 
.json.php: 
    echo "HelloMe" > out/PatientDbPath.php 

out/PatientDbPath.php: PatientDbPath.json 

clean: 
    $(RM) out/PatientDbPath.php 

Как только я это сделаю, Make сообщает мне make: Nothing to be done for 'out/PatientDbPath.php', хотя в каталоге out нет файла PatientDbPath.php.

Так что я подумал, что это было что-то с правилами суффикса, и я создал третий make-файл.

out/PatientDbPath.php: PatientDbPath.json 
    echo "Whatever" > out/PatientDbPath.php 

clean: 
    rm out/PatientDbPath.php 

Это хорошо работает, как и первый. Может ли кто-нибудь увидеть, что я делаю неправильно в своем втором make-файле?

Спасибо.

ответ

3

В вашем подстановочном правиле (.json -> .php) есть две ошибки: одна концептуальная и одна практическая.

Концептуальная ошибка заключается в том, что это правило, как преобразовать произвольные json-файлы (скажем, foo.json) в произвольные, но именованные .php-файлы (скажем, json.php). Тем не менее, ваше правило специфично для заражения PatientDbPth.php. Лучшее правило будет

.json.php: 
    echo "HelloMe" > [email protected] 

где [email protected] переменная именования выходного файла.

Это также показывает практическую проблему: эти правила действительно ограничены одноименными файлами. Если у вас есть правило, переводящее .json в .php, и у вас есть foo.php, и вы хотите bar.php, тогда правило подстановки не будет соответствовать. Согласование включает в себя все имя файла, поэтому правило подстановки не соответствует, когда вы запрашиваете выход/PatientDbPath.php. Это оставляет вам правило, которое не имеет никаких действий, и, следовательно, делает информацию о том, что ничего не нужно делать.

Если это единственный файл, который вы хотите преобразовать, лучше написать его так, как вы сделали в третьем файле. Если у вас много json-файлов, и вы все хотите их преобразовать в/*.PHP, и вы используете GNU сделать, вы можете использовать обобщенные правила подстановочных GNU Make в:

out/%.php: %.json 
    action 
+0

Спасибо за ответ, я попытаюсь изменить свой настоящий make-файл, чтобы использовать предложенные обозначения. Я буду следить или отметить, что он ответил в ближайшее время. Что касается концептуальных проблем, то, что я разместил здесь, это всего лишь образец makefile, который показывает проблему, а не как мой настоящий make-файл. –

+0

Хорошо, я протестировал его, и вы были абсолютно правы, изменив мой makefile, чтобы использовать 'out /%. Php:% .json' сделал трюк. У меня есть следующий вопрос. Мне нужно создать отдельное правило для каждого .json-файла в этом каталоге? –

+0

Я нашел решение для того, что хотел, в основном мне нужно добавить следующую строку: 'all :: $ (patsubst% .json, out /%. Php, $ (wildcard * .json))' Это добавит зависимость каждого из php-файлов, которые должны быть сгенерированы из каждого из .json в этом каталоге –

2

Там еще один способ сделать то же самое, возможно, более элегантно:

$(JSON_FILES): out/%.php: %.json 
    action 

Это создаст правило для каждого файла, указанного в JSON_FILES, так что, если она была определена JSON_FILES= foo.json bar.json, то это было бы эквивалентно:

out/foo.php: foo.json 
    action 

out/bar.php: bar.json 
    action 

Вы могли бы использовать $(wildcard *.json) чтобы установить это значение, если вы действительно хотели все .json-файлы или задали его вручную, если правило уникально для нескольких.