Hi Ludovic, * Ludovic Courtès wrote on Wed, Jul 21, 2010 at 06:27:46PM CEST: > Ralf Wildenhues writes: > > * Ludovic Courtès wrote on Tue, Jul 20, 2010 at 06:28:46PM CEST: > >> For this to work, we need “make install” to guarantee the relation > >> mtime(installed-object) >= mtime(installed-source), assuming we have > >> mtime(builddir-object) >= mtime(srcdir-source), which will always be the > >> case unless the computer’s clock is skewed. > >> > >> Do Automake-generated makefiles provide such a guarantee? Regardless of > >> the ‘make’ implementation, OS, etc.?
> > Anyway, most of the time, these issues can be worked around, for example > > by sleeping for a second before building builddir objects, or between > > installing sources and installing object files, depending on whether > > install -C is used or not. > > The latter would be faster IIUC (sleep 1 second instead of N seconds, > with N the number of source files.) I'm not sure I understand. I didn't mean you should sleep separately for each of the objects. Sleeping just once overall should be enough. This semantics should not (need to) depend on whether 'install -C' is used or not. > The ‘install’ command is chosen by Automake or the user-specified > $INSTALL, so we can’t really determine whether it uses ‘-C’, right? Typically, that is right; well, at least we don't set it, the user does. I'm not sure how -C helps you, though: it just doesn't update the time stamp of a file already installed with the same contents; there is no relation between stamps of different installed files. > > Hope that helps. It might be a bit tricky or ugly to actually put this > > sleep command in a normal automake Makefile.am, so if you know what > > exactly you need, we can create an example. > > A typical Makefile.am looks like this: > > --8<---------------cut here---------------start------------->8--- > dist_foobar_SOURCES = foo.scm bar.scm > nodist_foobar_DATA = foo.go bar.go > > .scm.go: > guile-tools compile -o $@ $< > --8<---------------cut here---------------end--------------->8--- > > Actually we currently have this hook, which Andy added some time ago > (here $(moddir) contains installed source files and $(ccachedir) is for > installed object files): > > --8<---------------cut here---------------start------------->8--- > install-data-hook: > @$(am__vpath_adj_setup) \ > list='$(nobase_mod_DATA)'; for p in $$list; do \ > if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ > $(am__vpath_adj) \ > echo " touch -r '$$d$$p' '$(DESTDIR)$(moddir)/$$f'"; \ > touch -r "$$d$$p" "$(DESTDIR)$(moddir)/$$f"; \ > done > @$(am__vpath_adj_setup) \ > list='$(nobase_ccache_DATA)'; for p in $$list; do \ > if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ > $(am__vpath_adj) \ > echo " touch -r '$$d$$p' '$(DESTDIR)$(ccachedir)/$$f'"; \ > touch -r "$$d$$p" "$(DESTDIR)$(ccachedir)/$$f"; \ > done > --8<---------------cut here---------------end--------------->8--- > > IIUC it copies timestamps from $(srcdir) and $(builddir) to the > corresponding installed files. > > It looks like this is all we need, right? The code depends on internal Automake APIs am__vpath_adj_setup and am__vpath_adj so is in principle not safe against Automake upgrades. For extensibility (the user might need an install-data-hook for other reasons too) you should write it somehow like: install-data-hook: guile-install-data-hook guile-install-data-hook: ... commands ... .PHONY: guile-install-data-hook because only one set of rule commands is allowed with a non-double-colon rule. Then, the code ensures installed files have the same stamps as the uninstalled ones, but that is not actually what you need: you need to have newer timestamps on the installed objects over the installed sources. Now I need to ask in more detail: do you actually need "newer" or just "not older"? Because if the latter, then you could just let the rule to install $(nodist_foobar_DATA) depend on the rule to install $(dist_foobar_SOURCES), the latter of which I assume you still need to write, and hook to install-data-local. Or you do something like mod_DATA = $(dist_foobar_SOURCES) ccache_DATA = $(nodist_foobar_DATA) The install rules then still have internal names (install-nodist_foobarDATA or install-ccacheDATA or so) but at least the right thing happens, as long as the same $(INSTALL_DATA) command is used in both cases. And if you need "newer" then you could "sleep 1" as last bit of your hand-written rule to install $(dist_foobar_SOURCES), or let the install-ccacheDATA depend on a guile-install-sleep helper rule which itself depends on the install-nodist_foobarDATA rule or so. However, that doesn't help you when "install -C" is used. Now, there's one more technical complication for adding the dependency: automake will not put out its own install-ccacheDATA rule if you use it as target anywhere (on the grounds that it's the only method to override an automake-provided target), which you don't want here; you can trick automake by assigning the name to some variable though: guile_install_ccacheDATA = install-ccacheDATA $(guile_install_ccacheDATA): install-modDATA > Problem is, each package that installs Guile object and source files > needs this hook... Well, for that you could put the code into a guile-rules.am fragment and advise your users to put something like include $(top_srcdir)/build-aux/guile-rules.am into their Makefile.am files that need it. Cheers, Ralf