Portál AbcLinuxu, 17. května 2024 01:29


Dotaz: Makefile: problém se závislostmi

Gilhad avatar 16.4.2023 14:56 Gilhad | skóre: 20 | blog: gilhadoviny
Makefile: problém se závislostmi
Přečteno: 569×
Odpovědět | Admin
V Makefile mám (kromě dalších) následující pravidla (s příslušnými recepty a v tomto pořadí)
$(info [$(THIS_MAKEFILE)])

.PHONY: all html plain_files static rsync_upload help more_help clean clean_all
all: html
html: $(TARGETS) $(BUILD_DIR)/.nav_dir.nav generated.mk
$(BUILD_DIR)/.nav_dir.nav: $(DIRNAVS)
generated.mk: $(THIS_MAKEFILE) $(BUILD_DIR)/.nav_dir.nav

když smažu $(BUILD_DIR)/.nav_dir.nav a dám "make all", tak se mi generated.mk nezbuduje:

$ rm build/.nav_dir.nav 
$ make all
[Makefile]
build/.nav_dir.nav
=== html ===
=== all ===
$

teprve až když to dám podruhé

$ make all
[Makefile]
===  generated.mk ===
[Makefile]
compile_rst: input output build   file_5
compile_rst: input output build  directory_2/subdirectory_5 file_5
compile_rst: input output build  directory_2/subdirectory_5 file_2
....
=== html ===
=== all ===
$

Já si myslím, že když chybí ten build/.nav_dir.nav a dám přebudovat all, které závisí na html, které závisí na generated.mk, který závisí na tom build/.nav_dir.nav, tak by se měl přebudovat hned na poprvé

Make si to nemyslí. Kde dělám chybu? Jak ji opravit?

Řešení dotazu:


Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

Řešení 1× (Gilhad (tazatel))
16.4.2023 15:51 tttttttttttttt
Rozbalit Rozbalit vše Re: Makefile: problém se závislostmi
Odpovědět | | Sbalit | Link | Blokovat | Admin
Pravděpodobně jinde než v tom, co jsi poslal. Zkusil jsem podle toho vytvořit Makefile:
THIS_MAKEFILE=Makefile
BUILD_DIR=build
TARGETS=target

.PHONY: all html plain_files static rsync_upload help more_help clean clean_all

all: html

html: $(TARGETS) $(BUILD_DIR)/.nav_dir.nav generated.mk

$(BUILD_DIR)/.nav_dir.nav: $(DIRNAVS)
	mkdir -p $(BUILD_DIR)/
	touch $(BUILD_DIR)/.nav_dir.nav

generated.mk: $(THIS_MAKEFILE) $(BUILD_DIR)/.nav_dir.nav
		touch generated.mk

target: 
		touch target
a chová se tak, jak očekáváš:
❯ make
touch target
mkdir -p build/
touch build/.nav_dir.nav
touch generated.mk
❯ rm -r build                    
❯ make
mkdir -p build/
touch build/.nav_dir.nav
touch generated.mk
Většinou to jde vyčíst z make --debug resp. make --debug=all
Řešení 1× (Gilhad (tazatel))
Gilhad avatar 16.4.2023 19:55 Gilhad | skóre: 20 | blog: gilhadoviny
Rozbalit Rozbalit vše Re: Makefile: problém se závislostmi
Díky strašně moc!

Měl jsi naprostou pravdu a já žil léta v omylu. Celý ten problém způsobilo tohle (úplně jinde v tom Makefilu):

# .SECONDARY: bez targetu ponecha VSECHNY intermediate fily a nesmaze je (pokud se je podari vyrobit)
# Define the .SECONDARY target to keep intermediate files
.SECONDARY:

Ve skutečnosti to sice ty intermediate files sice zachová a nemaže, pokud už je jednou vytvoří (což bylo cílem), ale pokud je něco intermediate file a něco jiného ho potřebuje, ale to něco jiného se stejně bude přebudovávat, tak se ten intermediate file vůbec nemusí tvořit (a to je ten problém).

https://www.gnu.org/savannah-checkouts/gnu/make/manual/html_node/Special-Targets.html:
.SECONDARY can be used to avoid redundant rebuilds in some unusual situations. For example:

Suppose hello.bin is up to date in regards to the source files, but the object file hello.o is missing. Without .SECONDARY make would rebuild hello.o then rebuild hello.bin even though the source files had not changed. By declaring hello.o as .SECONDARY make will not need to rebuild it and won’t need to rebuild hello.bin either. Of course, if one of the source files were updated then all object files would be rebuilt so that the creation of hello.bin could succeed.

.SECONDARY with no prerequisites causes all targets to be treated as secondary (i.e., no target is removed because it is considered intermediate).
Ve skutečnosti tam mělo být
.NOTINTERMEDIATE

Prerequisites of the special target .NOTINTERMEDIATE are never considered intermediate files. See Chains of Implicit Rules. .NOTINTERMEDIATE with no prerequisites causes all targets to be treated as not intermediate.

If the prerequisite is a target pattern then targets that are built using that pattern rule are not considered intermediate.
Tak jsem to opravil a už to dělá co má :)

Já to používám na vytváření statických stránek na web a mám tam spoustu těch mezilehlých souborů pro urychlení zpracování (seznamy souborů používajících nějaký tag, nějakého autora, v nějakém adresáři ... a často se kvůli takovému mrňavému souboru musí zpracovat naprosto věechny zdrojáky, aby se zjistilo, že se to použije jen v jediném případě), takže když se jednou vytvoří, tak je chci zachovat tak dlouho, dokud je není nutno změnit.

A jak jsem se koukal, tak se se mnou tenhle špatný překlad/miskoncepce táhne minimálně od roku 2003 ... Takže ještě jednou díky :)

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.