Thread: preserve timestamps when installing headers

preserve timestamps when installing headers

From
Alexander Kuzmenkov
Date:
Hi hackers,

I noticed that `make install` updates modification time for all
installed headers. This leads to recompilation of all dependent
objects, which is inconvenient for example when working on a
third-party extension. A way to solve this would be to pass
`INSTALL="install -p"` to `configure`, to make `install` preserve the
timestamp. After this, a new problem arises -- the
`src/include/Makefile` doesn't use `install` for all headers, but
instead uses `cp`. This patch adds `-p` switch to `cp` invocation in
these files, to make it preserve timestamps. Combined with the
aforementioned install flag, it allows a developer to hack on both
postgres and a third-party extension at the same time, without the
unneeded recompilation.


--
Alexander Kuzmenkov
Timescale

Attachment

Re: preserve timestamps when installing headers

From
Aleksander Alekseev
Date:
The following review has been posted through the commitfest application:
make installcheck-world:  tested, passed
Implements feature:       tested, passed
Spec compliant:           tested, passed
Documentation:            tested, passed

Personally, I don't often encounter the problem that Alexander is describing, but I agree that there are cases when the
simplestway to debug a tricky bug is to make a modification to the core. In fact, I used this technique to diagnose
[1].

Unless anyone can think of the scenario when the proposed change will break something, I would suggest merging it.

[1]: https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=98ec35b0

The new status of this patch is: Ready for Committer

Re: preserve timestamps when installing headers

From
Michael Paquier
Date:
On Tue, Oct 12, 2021 at 01:22:50PM +0300, Alexander Kuzmenkov wrote:
> I noticed that `make install` updates modification time for all
> installed headers. This leads to recompilation of all dependent
> objects, which is inconvenient for example when working on a
> third-party extension. A way to solve this would be to pass
> `INSTALL="install -p"` to `configure`, to make `install` preserve the
> timestamp. After this, a new problem arises -- the
> `src/include/Makefile` doesn't use `install` for all headers, but
> instead uses `cp`. This patch adds `-p` switch to `cp` invocation in
> these files, to make it preserve timestamps. Combined with the
> aforementioned install flag, it allows a developer to hack on both
> postgres and a third-party extension at the same time, without the
> unneeded recompilation.

The use of cp instead of $(INSTALL_DATA) for the installation of the
headers comes from a703269, back from 2005.  How do numbers compare
today, 16 years later?
--
Michael

Attachment

Re: preserve timestamps when installing headers

From
Tom Lane
Date:
Michael Paquier <michael@paquier.xyz> writes:
> On Tue, Oct 12, 2021 at 01:22:50PM +0300, Alexander Kuzmenkov wrote:
>> This patch adds `-p` switch to `cp` invocation in
>> these files, to make it preserve timestamps.

> The use of cp instead of $(INSTALL_DATA) for the installation of the
> headers comes from a703269, back from 2005.  How do numbers compare
> today, 16 years later?

According to a nearby copy of POSIX, "cp -p" does a lot more than
preserve timestamps.  It also specifies preserving file ownership,
which seems absolutely catastrophic for the standard use-case of
"build as some ordinary user, then install as root".

TBH, I am not convinced that the complained-of case is enough of a
problem to justify any change in our build rules, even if there
weren't any semantic issues.  If you are worried about build times,
you should be using ccache, and IME builds using ccache are not
terribly impacted by file timestamp changes.

            regards, tom lane



Re: preserve timestamps when installing headers

From
Peter Eisentraut
Date:
On 06.12.21 07:51, Tom Lane wrote:
> TBH, I am not convinced that the complained-of case is enough of a
> problem to justify any change in our build rules, even if there
> weren't any semantic issues.  If you are worried about build times,
> you should be using ccache, and IME builds using ccache are not
> terribly impacted by file timestamp changes.

I have never heard of a dependency-based build system taking into 
account the timestamps of files outside of the source (or build) tree. 
It does make sense to some degree, but it seems very unusual, and 
basically nothing works like that.  I'm also not sure how packaging 
systems preserve file timestamps.  Maybe it's a thing now, but I'd like 
to see a more comprehensive analysis before we commit to this.



Re: preserve timestamps when installing headers

From
Peter Eisentraut
Date:
On 06.12.21 12:15, Michael Paquier wrote:
> FWIW, I am not on board with changing build semantics or any
> assumptions the header installation relies on either, but I could see
> a point in switching back to INSTALL_DATA instead of cp to be
> consistent with the rest of the build, iff the argument made back in
> 2005 about the performance of this code path does not hold anymore.

I think you will find that it is still very slow.



Re: preserve timestamps when installing headers

From
Tom Lane
Date:
Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes:
> On 06.12.21 12:15, Michael Paquier wrote:
>> FWIW, I am not on board with changing build semantics or any
>> assumptions the header installation relies on either, but I could see
>> a point in switching back to INSTALL_DATA instead of cp to be
>> consistent with the rest of the build, iff the argument made back in
>> 2005 about the performance of this code path does not hold anymore.

> I think you will find that it is still very slow.

That would likely depend on whether configure had found a suitable
"install" program or decided to fall back on config/install-sh.
The latter will definitely be horribly slow, but C-coded install
utilities are probably no slower than "cp".

However, there's another problem with using INSTALL_DATA as a solution
to this issue: why would you expect that to preserve timestamps?
install-sh won't.  I see that /usr/bin/install (which configure picks
on my RHEL box) won't preserve them by default, but it has a -p
option to do so.  I would not bet on that being portable to all of
the myriad of foo-install programs that configure will accept, though.

On the whole, I think we should just reject this proposal and move on.
The portability hazards seem significant, and it's really unclear
to me what the advantages are (per Peter's earlier comment).

            regards, tom lane



Re: preserve timestamps when installing headers

From
Peter Eisentraut
Date:
On 04.01.22 22:21, Tom Lane wrote:
> However, there's another problem with using INSTALL_DATA as a solution
> to this issue: why would you expect that to preserve timestamps?
> install-sh won't.  I see that /usr/bin/install (which configure picks
> on my RHEL box) won't preserve them by default, but it has a -p
> option to do so.  I would not bet on that being portable to all of
> the myriad of foo-install programs that configure will accept, though.

I don't think preserving timestamps should be the default behavior, but 
I would support organizing things so that additional options can be 
passed to "install" to make it do whatever the user prefers.  But that 
won't work if some installations don't go through install.

We could have some mode where "install" is used instead of "cp", if 
someone wants to figure out exactly how to make that determination.

Btw., a quick test of make -C src/include/ install:

cp (current code): 0.5 s
GNU install: 0.6 s
install-sh: 12.5 s



Re: preserve timestamps when installing headers

From
Tom Lane
Date:
Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes:
> I don't think preserving timestamps should be the default behavior, but 
> I would support organizing things so that additional options can be 
> passed to "install" to make it do whatever the user prefers.  But that 
> won't work if some installations don't go through install.

Check, but ...

> Btw., a quick test of make -C src/include/ install:
> cp (current code): 0.5 s
> GNU install: 0.6 s
> install-sh: 12.5 s

So this says that there's only a performance issue with install-sh;
but that's used by just a tiny minority of systems anymore.  Scraping
the buildfarm's configure results, I find this many animals reporting
each of these choices:

      4 /bin/install -c
      8 config/install-sh -c
      2 /opt/packages/coreutils-8.6/inst/bin/install -c
      1 /usr/bin/ginstall -c
    100 /usr/bin/install -c
      1 /usr/gnu/bin/install -c

The 8 holdouts are

gaur
haddock
hake
hornet
hoverfly
mandrill
sungazer
tern

ie, ancient HPUX, OpenIndiana (Solaris), and AIX, none of which
are likely development platforms anymore --- and if somebody
did care about this, there's nothing stopping them from
installing GNU install on their machine.

So I fear we're optimizing for a case that stopped being mainstream
a decade or more back.  I could get behind switching the code back
to using $(INSTALL) for this, and then offering some way to inject
user-selected switches into the $(INSTALL) invocations.  That
wouldn't need much more than another gmake macro.  (Does there
need to be a way to inject such switches only into header
installations, or is it OK to do it across the board?)

[ wanders away wondering how this'd affect the meson conversion
project ]

            regards, tom lane



Re: preserve timestamps when installing headers

From
Heikki Linnakangas
Date:
On 11/01/2022 00:03, Tom Lane wrote:
> Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes:
>> I don't think preserving timestamps should be the default behavior, but
>> I would support organizing things so that additional options can be
>> passed to "install" to make it do whatever the user prefers.  But that
>> won't work if some installations don't go through install.

+1. We just bumped into this with Neon, where we have a build script 
that generates Rust bindings from the PostgreSQL header files. The build 
script runs "make install", and because that changes the mtime even if 
there were no changes to the headers, the bindings are also regenerated 
every time.

> So I fear we're optimizing for a case that stopped being mainstream
> a decade or more back.  I could get behind switching the code back
> to using $(INSTALL) for this, and then offering some way to inject
> user-selected switches into the $(INSTALL) invocations.  That
> wouldn't need much more than another gmake macro.  (Does there
> need to be a way to inject such switches only into header
> installations, or is it OK to do it across the board?)

Here's a patch to switch back to $(INSTALL). With that, you can do:

./configure INSTALL="/usr/bin/install -C"

> [ wanders away wondering how this'd affect the meson conversion
> project ]

If anything, I guess this will help, by making the Makefile a bit less 
special.

- Heikki
Attachment

Re: preserve timestamps when installing headers

From
Justin Pryzby
Date:
On Fri, Sep 09, 2022 at 10:23:57PM +0300, Heikki Linnakangas wrote:
> On 11/01/2022 00:03, Tom Lane wrote:
> > Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes:
> > > I don't think preserving timestamps should be the default behavior, but
> > > I would support organizing things so that additional options can be
> > > passed to "install" to make it do whatever the user prefers.  But that
> > > won't work if some installations don't go through install.

> Here's a patch to switch back to $(INSTALL). With that, you can do:
> 
> ./configure INSTALL="/usr/bin/install -C"

+1, I recently looked for a way to do that while trying to accelerate
Cygwin/Mingw.

-- 
Justin



Re: preserve timestamps when installing headers

From
Peter Eisentraut
Date:
On 09.09.22 21:23, Heikki Linnakangas wrote:
>> So I fear we're optimizing for a case that stopped being mainstream
>> a decade or more back.  I could get behind switching the code back
>> to using $(INSTALL) for this, and then offering some way to inject
>> user-selected switches into the $(INSTALL) invocations.  That
>> wouldn't need much more than another gmake macro.  (Does there
>> need to be a way to inject such switches only into header
>> installations, or is it OK to do it across the board?)
> 
> Here's a patch to switch back to $(INSTALL).

I'm content to go ahead with this.




Re: preserve timestamps when installing headers

From
Heikki Linnakangas
Date:
On 12/09/2022 18:49, Peter Eisentraut wrote:
> On 09.09.22 21:23, Heikki Linnakangas wrote:
>>> So I fear we're optimizing for a case that stopped being mainstream
>>> a decade or more back.  I could get behind switching the code back
>>> to using $(INSTALL) for this, and then offering some way to inject
>>> user-selected switches into the $(INSTALL) invocations.  That
>>> wouldn't need much more than another gmake macro.  (Does there
>>> need to be a way to inject such switches only into header
>>> installations, or is it OK to do it across the board?)
>>
>> Here's a patch to switch back to $(INSTALL).
> 
> I'm content to go ahead with this.

Committed.

- Heikki