Помилка "Без цілі" за допомогою функції Make


12

Я вчусь користуватися makeта makefiles, тому я написав цей маленький файл:

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

Але коли я біжу make, все, що я отримую, це make: *** No targets. Stop.те, що відбувається?


Це пробіли чи вкладка перед pandocкомандою. Make є сумно прискіпливим щодо тих, хто є вкладкою, а не пробілами.
slm

@slm: це вкладка. Десь я читав, що EOL для Windows 'не сумісний, тому я перетворив цілий файл на сумісний з Unix EOL.
ахмед

Відповіді:


17

Проблема:

Ваша проблема полягає в тому, makeщо не знаєте про свої цілі.

Ви можете запустити свій вище Makefile, make stackoverflow.markdownнаприклад, і він буде працювати.

make тільки, проте, не вдасться, оскільки ви вказали лише, як створити цілі, але не які.

Як зазначає leiaz, вищезазначене правило називається неявним правилом .

Makefile:

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

.PHONY: all clean

all: $(TAR)

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

clean:
    rm -f $(TAR)

Пояснення:

SRCотримати всі вихідні файли (ті, що закінчуються .html) через Makefile wildcard.

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

.PHONY перераховує нефізичні цілі, які завжди застаріли і тому завжди виконуються - це часто allі clean.

Метаall має в якості залежностей (файли перераховані на правій стороні :) все *.markdownфайли. Це означає, що всі ці цілі виконуються.

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

Цей фрагмент говорить: Кожна цільова група, що закінчується .markdown, залежить від файлу з тим самим іменем, за винятком того, що залежність закінчується .html. Символи% слід розглядати як *як в оболонці. Однак %праворуч порівняно з матчем з лівого боку. Джерело .

Зауважимо, що послідовність пробілів, що pandocзнаходиться перед TAB, є a , оскільки makeвизначає це як стандарт.

Нарешті, підроблена cleanмета зображує, як очистити вашу систему від файлів, створених за допомогою цього Makefile. У цьому випадку це видалення всіх цілей (тих файлів, які були названі *.markdown.


1
Великий відповідь , і це інші посилання , які я знайшов при спробі подальшого розуміння його: підстановочні функції , посилання на заміщення , і липові мети .
ахмед

Ще одне запитання, будь ласка: чи можна makefileстворювати файли з нуля або він лише оновлює наявні файли? Тому що коли я видаляю згенеровані файли, він перестає працювати. Дурне питання я знаю, але це для мене Ньюфаундленд ^^ "
ахмед

1
ви маєте на увазі, якщо немає .markdown файлів, то вони будуть створені? так, це повинно зробити це, наскільки я знаю
полим

1
В порядку, то. Я ще трохи викопаю. Дякую за ваші відповіді, завдяки вам я зараз на правильному шляху
:)

1
Просто хотів подякувати за чудову відповідь. Спосіб, який ви пояснили, дуже легко зрозуміти причину, по якій команда не працювала, і дуже детальні інструкції, як діяти далі. Знову дякую.
zanona

5

Правила шаблону - це неявні правила.

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

Або ви можете додати у свій Makefile правило із зазначенням цілей за замовчуванням.

all: file1.markdown file2.markdown

Або з підстановкою:

all: *.markdown

Коли ви запускаєтесь лише make, першою ціллю першого правила є мета за замовчуванням . Це не потрібно викликати all.

Отже вище, у цілі allє всі файли, які ви хочете зробити як передумови, тож коли ви make allзробите всі перелічені файли.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.