Makefile: flexibles Target anhand Verzeichnisinhalt?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
paedubucher
Beiträge: 932
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Makefile: flexibles Target anhand Verzeichnisinhalt?

Beitrag von paedubucher » 14.11.2021 11:20:53

Ich habe ein Verzeichnis von generierten Markdown-Dateien. Jeder dieser Dateien möchte ich nun in ein PDF umwandeln. Das mache ich mit Debianpandoc:

Code: Alles auswählen

pandoc -s --pdf-engine=xelatex -V papersize=a4 foo.md -o foo.pdf
pandoc -s --pdf-engine=xelatex -V papersize=a4 bar.md -o bar.pdf
Das funktioniert soweit. Nun kann es sein, dass sich einige Markdown-Dateien ändern, andere aber nicht. So wäre es doch schön, wenn ich mithilfe von einem Makefile nur diejenigen PDFs neu generieren muss, für welche sich die Markdown-Datei richtig geändert hat.

Grundsätzlich gibt es ja Suffixes, welche einem das Formulieren allgemeiner Regeln erlauben:

Code: Alles auswählen

.SUFFIXES .md .pdf
.md.pdf:
    pandoc -s --pdf-engine=xelatex -V papersize=a4 $< -o $@
Das Problem ist nun, dass ich nicht im Voraus (d.h. beim Verfassen vom Makefile) weiss, welche Markdown-Dateien es gibt. So müsste ich make etwas umständlich wie folgendermassen aufrufen:

Code: Alles auswählen

$ find . -type f -name '*.md' | sed 's/\.md$/.pdf/' | xargs make
So wird der Target-Name für jedes PDF dynamisch anhand des Namens der jeweiligen Markdown-Datei erstellt.

Kann ich das irgendwie in mein Makefile integrieren? Eine portable Lösung wäre mit natürlich am liebsten...
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

JTH
Moderator
Beiträge: 3077
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Makefile: flexibles Target anhand Verzeichnisinhalt?

Beitrag von JTH » 14.11.2021 12:41:32

Meine Make-Kenntnisse sind etwas eingestaubt, mag sein, dass Folgendes nicht ganz fehlerfrei ist.

Das kannst du über eine Pattern-Regel lösen, mit jeweils passender Abhängigkeit auf die .md-Datei(en):

Code: Alles auswählen

PDFS=$(patsubst %.md,%.pdf,$(wildcard *.md))

.PHONY: pdf
pdf: $(PDFS)

%.pdf: %.md
	pandoc ... $< -o $@

Damit wandelt nur alle veränderten .md um und ein einzelnes

Code: Alles auswählen

make foo.pdf
geht auch.
Manchmal bekannt als Just (another) Terminal Hacker.

Benutzeravatar
paedubucher
Beiträge: 932
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: Makefile: flexibles Target anhand Verzeichnisinhalt?

Beitrag von paedubucher » 14.11.2021 18:17:52

@JTH: Vielen Dank, das funktioniert prima! Weisst du auch, wie portabel das ist?
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

Benutzeravatar
Meillo
Moderator
Beiträge: 9224
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Makefile: flexibles Target anhand Verzeichnisinhalt?

Beitrag von Meillo » 14.11.2021 18:24:26

Nutzt denn irgendjemand was anderes als gmake? ;-)
Use ed once in a while!

Benutzeravatar
paedubucher
Beiträge: 932
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: Makefile: flexibles Target anhand Verzeichnisinhalt?

Beitrag von paedubucher » 14.11.2021 18:42:16

Meillo hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 18:24:26
Nutzt denn irgendjemand was anderes als gmake? ;-)
Ich habe dieses Jahr ab und zu mit OpenBSD gearbeitet, und war überrascht, wie anders portable Makefiles aussehen. Statt Wildcards wie %.pdf: %.md verwende ich seither Suffixes.

Auf meinem Rechner habe ich halt schon gmake im Einsatz, von daher kann ich damit schon arbeiten.

Nachtrag: der grössere Kontext ist ein Programm, das aus Excelzeilen Notenblätter generiert. Evtl. könnte ich den zweiten Teil (Markdown zu PDF) auch noch mit Python automatisieren, statt hier Make zu verwenden. Oder halt ein High-Level-Skript für beide Schritte schreiben.
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

JTH
Moderator
Beiträge: 3077
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Makefile: flexibles Target anhand Verzeichnisinhalt?

Beitrag von JTH » 14.11.2021 21:03:12

paedubucher hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 18:17:52
Weisst du auch, wie portabel das ist?
Ah, die Anmerkung zur Portabilität hab ich im ersten Beitrag wohl geschickt überlesen :D Ich merk mal vorab an, dass ich mich bei make da bisher nicht ernsthaft mit beschäftigt habe.

Wenn ich so die Beschreibung von Make in Posix und z.B. die Manpage von FreeBSDs Make überfliege, ist das nicht portabel. Es scheitert an wildcard, patsubst (das man allerdings problemlos ersetzen kann) und besonders dem %.pdf: %.md. Letzteres könnt man wie du schreibst mit .SUFFIXES nachbauen. Nur für wildcard gibts (anscheinend?!) keine Lösung, die beide Make-Dialekte können (oder?). Statt einer Wildcard, könntest du natürlich, wenn es nicht zu viele sind, die Markdown-Dateien auch von Hand einzeln auflisten.
Manchmal bekannt als Just (another) Terminal Hacker.

Benutzeravatar
paedubucher
Beiträge: 932
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: Makefile: flexibles Target anhand Verzeichnisinhalt?

Beitrag von paedubucher » 15.11.2021 21:11:08

JTH hat geschrieben: ↑ zum Beitrag ↑
14.11.2021 21:03:12
Statt einer Wildcard, könntest du natürlich, wenn es nicht zu viele sind, die Markdown-Dateien auch von Hand einzeln auflisten.
In meinem Anwendungsfall dürften es genau 52 Markdown-Dateien geben :wink:
Ich verwende also notfalls mal die nicht-portable Variante oder mache mir noch ein kleines Skript.
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

Antworten