Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Make, zpracování souborů vytvořených až při kompilaci

Dělám generátor statických stránek (Static Site Generator) pomocí make

V podstatě čtu .RST soubory a vytvářím .HTML soubory, což je lehké:


TARGETS_R = $(shell find . -name '*.rst')
TARGETS_H = $(TARGETS_R:.rst=.html)
regular_files: $(TARGETS_H)
    @echo "Generating HTML files and tag files..."
%.html: %.rst
    @./compile.py $< $@ # create also tags/<tag_name>.tag files as side-effect

Problém je, že vstupní soubory obsahují tagy, takže seznam tagů zjistím teprve až je všechny nějak zpracuju. Tagy se mi objeví jako tags/*.tag soubory, s tím, že jejich jména předem neznám (protože jsou uvnitř těch vstupních souborů, odkud se dají relativně snadno vyparsovat).

Takhle nějak bych si to naivně představoval - akorát, že to nechodí jak má, ale při prvním spuštění to vygeneruje ty *.tag soubory (ale žádné *.nav), teprve po druhém spuštění to z už existujících souborů .tag udělá všechny potřebné .nav (tady je zjednodušené řešení, protože nejde o obsah, ale o existenci souborů)


TARGETS_R = $(shell find . -name '*.rst')
TARGETS_H = $(TARGETS_R:.rst=.html)
regular_files: $(TARGETS_H)
    @echo "Generating HTML files and tag files..."
%.html: %.rst
    @./compile.py $< $@ @# create also tags/<tag_name>.tag files as side-effect

# ----------- tohle bych chtěl, aby se vyhodnotilo až když je vršek hotový
TAGS = $(shell find . -name '*.tag')
NAVS = $(TAGS:.tag=.nav)
navigation.nav: $(NAVS)
    echo $^ >$@ # some magic here
%.nav: %.tag
    echo $^ >$@ # some magic here

.PHONY: all regular_files

all: regular_files navigation.nav

No a navíc bych to rád spouštěl paralelně s argumentem "-j24", abych využil všechna jádra.

Myslím, že na to musí být nějaký trik, jak to dělat, protože něco podobného už muselo řešit asi bambilión lidí přede mnou, ale nějak jsem nepřišel na to, co hledat, na co se ptát, takže jsem nenašel nic k tématu.
Zkoušel jsem to jak s googlem (vždycky mi vypsal mraky věcí, které s tím nesouvisely), tak jsem to zkusil s chatGPT (a ten zase vůbec nepochopil, o co mi jde na navrhoval samé nefunkční kraviny)

Takže jestli někdo zná řešení, nebo aspoň na co se ptát, tak bych byl velice rád.

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
makefile jsem nikdy nevyráběl, ale pokud všechno selže, můžeš použít nástroje bashe, ne? edit: troc…
touchwood 10.04.2023 19:47
touchwood
Jo, jasně, že můžu, akorát pak přijdu o dost šikovné funkcionality právě toho make (řešení závislost…
gilhad 11.04.2023 02:50
gilhad
a nemůžeš si v makeskriptu udělat několik metod a ty pak postupně spouštět ve třetí? Co se tak pamat…
touchwood 11.04.2023 05:37
touchwood
Zatím jsem to obešel tím, že při startu make prostě projdu všechny RST, vytahám z nich všechny tagy… poslední
gilhad 13.04.2023 03:35
gilhad

Jo, jasně, že můžu, akorát pak přijdu o dost šikovné funkcionality právě toho make (řešení závislostí, paralelní běh s -j24 a jiné hezké výmysly a krátké výstižné zápisy).
Ono to make je právě dělané (a velmi dlouho laděné) na tyhle problémy.
Takže pokud to nepůjde po dobrém, tak popřemýšlím o nějakém shellskriptu, co by ten make pospouštěl opakovaně, nebo tak něco.
Kdyby bylo úplně nejhůř, tak si to můžu postupně všechno napsat a odladit skoro v čemkoli, co mě napadne (abych řekl v čemkoli, na to znám až moc esoterických jazyků ). Jenže to by bylo zoufale dlouhé, pracné a neefektivní.
Takže mnohem raději bych byl, kdyby to šlo nějak nativně.

Dokonce si myslím, že jsem o něčem takovém četl na nějakém anglickém internetu, ale nedaří se mi to dohledat (a ani nevím, jestli to šlo úplně normálně, nebo nějakým fikaným trikem).

Co se TAGS a find týče, tak tam bude různých podivností víc.

Já to tak nějak řeším za pochodu, protože zároveň píšu ten program na RST -> HTML s různýma speciálníma vychytávkama - např. pokud je v adresáři u RST souboru taky symlink, nazvaný %root%, tak se jak v tom RST, tak v templatech, tak i leckde jinde nahradí všechny řetězce %root% obsahem toho symlinku převedeným na relativní adresu. Takže tam pak kdekoliv funguje třeba %root%/logos/favicon.ico, což se hodí, protože plánuju používat košaté a hluboké adresářové struktury (což jsem stejně dělal vždycky, jen to spousta generátorů a jiných softwarů moc nepodporovala a já se s nima o to musel dost prát). Takře teď se starám, abych se prát nemusel. Navíc takhle pojmenované symlinky jsou fajn, že jsou názorné a pokud je používám v tom zdrojové RST, tak mi editor nativně doplňuje věci přez ně dostupné. A po jejich překladu na relativní cesty to bude fungovat stejně na webu, jako na lokálním disku při ladění, nebo když si to někdo postahuje k sobě - furt bude všechno jak má být :-)

No a podobných vychytávek tam mám mraky, ale do tohohle zadání jsem je nedal, protože by to všechno jen komplikovaly, zatímco mě jde jen o to správně uchopit tu myšlenku ...

No a zároveň teda dělám k tomu i templaty v Jinja2 a snažím se vychytat vlastnorušně psané CSS pro to a snažím se to aspoň nějak dokumentovat už přímo na těch nových stránkách ... prostě dělám toho moc naráz, tak to zatím dělám jen jako proof-of-concept a časem to snad i poladím a učešu. Až to bude spolehlivě fungovat a budu tak schopný při refaktorování snadno hledat regrese.

No a aby toho snad nebylo málo, [strike]spřáhnul se s pankáčema ]:)[/strike], tak se na tom učím používat chatGPT, kdy na něj hážu nápady a kousky kódu a žádosti o běžné obraty a tak a on na mě háže něco, co občas nefunguje vůbec, občas to dělá něco úplně jiného a občas to dělá "něco, co se téměř úplně, ale ne zcela naprosto nepodobá čaji". Takže z toho vytahám, co se nezdá být na první pohled zcela špatně, něco z toho splácám a když to i dělá to, co má, tak už se v tom nevrtám, ale jdu honem dál řešit jiné věci, s tím, že detaily vylepším, až bude celek funkční a stabilní.

a nemůžeš si v makeskriptu udělat několik metod a ty pak postupně spouštět ve třetí? Co se tak pamatuju, tak "make install" běžně spustí i kompilaci, pokud není hotova.

Jinak makefile je poměrně čitelný, kdysi jsem celkem obstojně zvládal m4 (skriptovací nástroj sendmailu) a dokonce i jeho "kompiláty."

Zatím jsem to obešel tím, že při startu make prostě projdu všechny RST, vytahám z nich všechny tagy a autory a pokud nemají příslušné soubory, tak je aspoň udělám, i když nenaplňuju.
Takže make pak už má všechna jména souborů a může s nima machrovat (i když jsou třeba zatím prázdné) - a díky závislostem se ty soubory i naplní.
A při dalším spuštění make už ty soubory mají správné hodnoty a pohoda.
Akorát to počáteční projití mi teď sežere něco jako 0.1sec a to na té pokusné sitě mám jen nějakých 32 souborů s mizernými 1.200 řádky textu ... no zatím to jde, můžu aspoň dopsat další chybějící věci a k tomuhle se vrátit později, až mě to začne tlačit víc ...

Je to v podstatě oneliner, teda dva stejné, jeden pro tagy a druhý pro autory. A i když se to nezdá, tak ten sort -u uprostřed to urychluje asi 5x :-)


mkdir -p build/.tags
mkdir -p input/.tags
mkdir -p build/.authors
mkdir -p input/.authors
find input -type f -name "*.rst" -exec grep -h "^:tags:" {} \; | sed "s/^:tags:\s*//; s/\s*,\s*/,/g" | tr "," "\n" | sort -u | sed "s@^.*@( [ ! -e 'build/.tags/\0.tag' ] \&\& touch 'build/.tags/\0.tag' ;  [ ! -e 'input/.tags/\0.rst' ] \&\& sed < .theme/defaults/tag.rst >'input/.tags/\0.rst' 's/%TAG_NAME%/\0/g')@" |sh
find input -type f -name "*.rst" -exec grep -h "^:authors:" {} \; | sed "s/^:authors:\s*//; s/\s*,\s*/,/g" | tr "," "\n" | sort -u | sed "s@^.*@( [ ! -e 'build/.authors/\0.author' ] \&\& touch 'build/.authors/\0.author' ;  [ ! -e 'input/.authors/\0.rst' ] \&\& sed < .theme/defaults/author.rst >'input/.authors/\0.rst' 's/%TAG_NAME%/\0/g')@" |sh

Zpět do poradny Odpovědět na původní otázku Nahoru