On 01.02.2013 16:18, Matěj Týč wrote: > Hi, > I have noticed that if we have a target that has prerequisities, if > those prerequisities are missing and I want to make the target, then > even if the target file exists, prerequisities are remade if possible > and then, consequently, the target has to be remade, too, since its > prerequisity is now more up-to-date. Which, of course, makes perfect sense. > > However, if a prerequisity is order-only, it is also going to be remade > despite the target file existis already, but unlike the case above, the > target won't be remade because it is allowed to be older than its > order-only prerequisity. This is normally not an issue, since order-only > prereqs are probably often cheap commands lke mkdir etc., but my case is > different: > > Consider a server process that can execute commands and that can load > (huge) data into cache to spped the execution up. Loading the data is a > make task and a target file cache-foo is created to expose that the data > has been succesfully loaded into the server cache. Then cache-foo is an > order-only dependency of foo1, foo2 and foo3 targets that take advantage > of it (rules to make them call the server process that uses the foo > cache). Therefore those targets are not made before setting the cache up > and also the cache is loaded once, not concurently even if like -j4 is > used as a make argument. > > As you might guess, if I have a target 'bar' that depends on 'foo1' and > 'foo2', then even if 'foo1' and 'foo2' exist, if 'cache-foo' is missing, > it is remade and data are loaded into the cache without being of any > use, which is quite annoying. In other words, the whole server might > have to start, load the cache and then do nothing.
This is what I understand to be our current Makefile: bar_deps = foo1 foo2 bar: $(bar_deps) $(bar_deps): | cache-foo %: touch $@ Now you want that cache-foo is not built if all of $(bar_deps) exist. We can achieve that by only adding cache-foo as a dependency, if former is not the case. So let's replace the line $(bar_deps): | cache-foo by $(bar_deps): | $(if $(call any_file_missing,$(bar_deps)),cache-foo,) using two custom functions: # $(call file_missing,file_1) # returns: # true (actually $(file_1)) if the file is missing # false (empty string) if the file exists define file_missing $(if $(wildcard $1),,$1) endef # $(call any_file_missing,file_1 file_2 ..) # returns: # true (a non-empty string) if any file is missing # false (empty string) if all file exist define any_file_missing $(strip $(foreach filename,$(1),$(call file_missing,$(filename)))) endef I hereby put that into the public domain. This session confirms it working: $ touch foo1 foo2 bar $ make make: `bar' is up to date. # cache-foo not built! $ rm foo1 $ make touch cache-foo # cache-foo built, since foo1 is missing touch foo1 touch bar I'm curious, if that helps. Best, Sebastian _______________________________________________ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make