Ошибка «Нет цели» при использовании Make

12

Я учусь использовать makeи создавать файлы, поэтому я написал этот маленький файл:

%.markdown: %.html
    pandoc -o $< $@

Но когда я бегу make, все, что я получаю, это make: *** No targets. Stop.то, что происходит?

Ahmed
источник
Эти пробелы или табуляция перед pandocкомандой. Make, как известно, требователен к тем, что является табуляцией, а не пробелами.
SLM
@slm: это вкладка. Я где-то читал, что Windows EOL не совместимы, поэтому я преобразовал весь файл в Unix-совместимый EOL.
Ахмед

Ответы:

17

Проблема:

makeВаша проблема в том, что не знает о ваших целях.

Вы можете запустить ваш вышеупомянутый Makefile, make stackoverflow.markdownнапример, и он будет работать.

make однако, только потерпит неудачу, поскольку вы только указали, как создавать свои цели, а не какие.

Как указывает Лейаз, указанное выше шаблонное правило называется неявным правилом .

Makefile:

SRC = $(wildcard *.html)
TAR = $(SRC:.html=.markdown)

.PHONY: all clean

all: $(TAR)

%.markdown: %.html
    pandoc -o $< $@

clean:
    rm -f $(TAR)

Объяснение:

SRCget получает все исходные файлы (те, которые заканчиваются на .html) через Makefile wildcard.

TAR заменяет каждый указанный в списке исходный файл SRCна целевое, заканчивающееся .markdownвместо .html.

.PHONY перечисляет нефизические цели, которые всегда устарели и, следовательно, всегда выполняются - это часто allи clean.

Цельall имеет в качестве зависимостей (файлы перечислены на правой стороне :) все *.markdownфайлы. Это означает, что все эти цели выполнены.

%.markdown: %.html
    pandoc -o $< $@

В этом фрагменте говорится: Каждая цель, заканчивающаяся на .markdown, зависит от файла с тем же именем, за исключением того, что зависимость заканчивается на .html. Подстановочные% следует рассматривать как *как в оболочке. Однако %на правой стороне сравнивается с матчем на левой стороне. Источник .

Обратите внимание, что последовательность пустого пространства pandocперед a является TAB, поскольку makeопределяет это как стандарт.

Наконец, фальшивая cleanцель показывает, как очистить вашу систему от файлов, которые вы создали с помощью этого Makefile. В этом случае он удаляет все цели (те файлы, которые были названы *.markdown.

Polym
источник
1
Отличный ответ, и это другие ссылки, которые я нашел, пытаясь понять его: функция подстановочных знаков , ссылки на подстановки и фальшивые цели .
Ахмед
Пожалуйста, еще один вопрос: можно makefileсоздавать файлы с нуля или он только обновляет существующие файлы? Потому что, когда я удаляю сгенерированные файлы, он перестает работать. Глупый вопрос, который я знаю, но для меня это Ньюфаундленд ^^ "
Ахмед
1
Вы имеете в виду, что если нет файлов .markdown, то они будут созданы? да, это должно сделать это, насколько я знаю
Polym
1
Ладно. Я сделаю еще кое-что. Спасибо за ваши ответы, спасибо вам, что я на правильном пути
:)
1
Просто хотел поблагодарить вас за отличный ответ. То, как вы объяснили, очень легко понять, почему команда не работает, и очень подробные инструкции о том, как действовать. Еще раз спасибо.
Занона
5

Шаблонные правила являются неявными правилами.

У вас нет целей, определенных в вашем Makefile. Вы можете указать цель в командной строке: make something.markdownиспользовать рецепт для создания something.markdownиз something.html.

Или вы можете добавить в свой Makefile правило, определяющее цели по умолчанию.

all: file1.markdown file2.markdown

Или с подстановочным знаком:

all: *.markdown

Когда вы просто запускаете make, первая цель первого правила является целью по умолчанию . Это не нужно называть all.

Итак, выше, у цели allесть все файлы, которые вы хотите сделать в качестве предварительных условий, поэтому, когда вы make allсоздадите все перечисленные файлы.

Leiaz
источник