Błąd „Brak celu” przy użyciu opcji Make

12

Uczę się, jak używać makei makefile, więc napisałem ten mały plik:

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

Ale kiedy biegam make, wszystko co dostaję to make: *** No targets. Stop.Co się dzieje?

Ahmed
źródło
Są to spacje lub tabulator przed pandocpoleceniem. Make jest notorycznie wybredny, jeśli chodzi o tabulatory, a nie spacje.
slm
@slm: to karta. Czytałem gdzieś, że EOL systemu Windows nie jest kompatybilny, więc przekonwertowałem na cały plik na EOL kompatybilny z Uniksem.
Ahmed

Odpowiedzi:

17

Problem:

Problem polega na tym, makeże nie wiesz o swoich celach.

Możesz make stackoverflow.markdownna przykład uruchomić powyższy Makefile i będzie działać.

make tylko się nie powiedzie, ponieważ określiłeś tylko, jak utworzyć swoje cele, ale nie które.

Jak wskazuje punkt Leiaz, powyższa reguła wzorcowa nazywana jest regułą domyślną .

Makefile:

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

.PHONY: all clean

all: $(TAR)

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

clean:
    rm -f $(TAR)

Wyjaśnienie:

SRCget to wszystkie pliki źródłowe (te kończące się na .html) przez Makefile's wildcard.

TAR zastępuje każdy plik źródłowy wymieniony w SRCcelu celem kończącym się na .markdownzamiast .html.

.PHONY wymienia niefizyczne cele, które są zawsze nieaktualne i dlatego są zawsze wykonywane - są to często alli clean.

Celall ma za zależnościami (pliki na liście po prawej stronie :) wszystkich *.markdownplików. Oznacza to, że wszystkie te cele są wykonywane.

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

Ten fragment mówi: Każdy cel kończący się na .markdownjest zależny od pliku o tej samej nazwie, z tą różnicą, że kończy się zależność .html. Symbol wieloznaczny% należy traktować *jak skorupę. %Po prawej stronie, jest jednak w porównaniu do meczu na lewej stronie. Źródło .

Zauważ, że sekwencja białych znaków przed pandocjest TAB, ponieważ makedefiniuje to jako standard.

Wreszcie fałszywy cleancel przedstawia sposób czyszczenia systemu z plików utworzonych za pomocą tego pliku Makefile. W tym przypadku usuwa wszystkie cele (te pliki, które zostały nazwane *.markdown.

polim
źródło
1
Świetna odpowiedź, a oto inne linki, które znalazłem, próbując ją lepiej zrozumieć: funkcja wieloznaczna , odwołania do podstawienia i fałszywe cele .
Ahmed
Jeszcze jedno pytanie: czy można makefiletworzyć pliki od zera, czy aktualizuje tylko istniejące pliki? Ponieważ po usunięciu wygenerowanych plików przestaje działać. Głupie pytanie, wiem, ale to dla mnie Nowa Fundlandia ^^ "
Ahmed
1
masz na myśli, że jeśli nie ma plików .markdown, to zostaną one utworzone? tak, powinienem to zrobić, o ile mi wiadomo
polim
1
W porządku. Zrobię więcej kopania. Dzięki za odpowiedzi, dzięki tobie jestem teraz na dobrej drodze:)
Ahmed
1
Chciałem ci tylko podziękować za świetną odpowiedź. Sposób, w jaki wyjaśniłeś, jest bardzo łatwy do zrozumienia, dlaczego polecenie nie działało, i bardzo szczegółowe instrukcje, jak postępować. Dzięki jeszcze raz.
zanona
5

Reguły wzorców są regułami niejawnymi.

Nie masz zdefiniowanych celów w swoim Makefile. Możesz określić cel w wierszu poleceń: make something.markdownużyje przepis do tworzenia something.markdownz something.html.

Lub możesz dodać do swojego pliku Makefile regułę określającą domyślne cele.

all: file1.markdown file2.markdown

Lub z symbolem wieloznacznym:

all: *.markdown

Po uruchomieniu po prostu make, pierwszym celem pierwszej reguły jest domyślnym cel . Nie trzeba go nazywać all.

Tak więc powyżej cel allzawiera wszystkie pliki, które chcesz utworzyć jako warunki wstępne, więc kiedy make allto zrobisz, wszystkie wymienione pliki.

Leiaz
źródło