Make recursive dependencies

I am currently working on a project that requires translating a list of files into a directory into a C ++ header to store resource information. For instance:

/ update.py resources.h Makefile /resources resource1.png /sub1 /sub2 resource2.png 

I want the Makefile to run update.py only when one of the resources in the directory tree changes. No other makefiles will concern resources, only resources.h. What makefile do I need to do?

PS From what I read, recursive searching with make is a bad idea, but if nothing else touches the same file, would it be a problem?

+7
source share
3 answers

I'm not sure what you read, but there is no problem writing such a rule in make:

 RESOURCES := $(shell find . -name resource\*.png -print) resources.h: update.py $(RESOURCES) ./update.py $(RESOURCES) 

or something else.

+15
source

I think you are mistaken: Recursive Make is considered to be malicious; it explains that you should not call one make from another, because it will not have a complete overview of dependencies. This sooner or later leads to incorrect builds that can only be sorted with make clean .

makepp is an alternative that will help you avoid this trap. It also solves your problem with a recursive (nothing to do with the above) pattern:

 RESOURCES := **/resource\*.png resources.h: $(RESOURCES) .$/update.py $(inputs) 

This even works if there are no files yet, as makepp wildcards take into account what can be built according to your rules. Notice how the program dependency is automatically recorded. A ridiculous $/ will rely in any case, depending on which system it works on, so its more portable.

There are more to makepp. Besides doing just about everything GNU can do, there are many more useful things, and you can even extend your makefiles with some Perl programs.

+2
source

Note that you can also use the $(shell find) for dependencies without a variable:

 resources.h: $(shell find . -name 'resource*.png') ./update.py $^ 

So this is similar to @MadScientist's answer, but you get a list of dependencies in the $^ automatic variable. (In this case, update.py is not so easy to include depending).

What makes this powerful is that you can use templates with it, for example, if you need to compile multiple destination files ( resourcesN.h ) from several corresponding directories ( resourcesN/ ):

 targets: resources1.h resources2.h %.h: $(shell find $*/ -name 'resource*.png') ./update.py $^ 

Here $* gets the values โ€‹โ€‹of resources1 and resources2 , and then $^ contains a list of dependencies found in the corresponding directory.

+1
source

Source: https://habr.com/ru/post/947997/


All Articles