[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: mtime of installed files
From: |
Ralf Wildenhues |
Subject: |
Re: mtime of installed files |
Date: |
Wed, 21 Jul 2010 22:53:59 +0200 |
User-agent: |
Mutt/1.5.20 (2010-04-22) |
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