Thanks Thomas and Tom for your detective work.
Thomas Munro <thomas.munro@enterprisedb.com> writes:
> As for what could be done about it, it seems like we (or the Nix
> project, in a local patch) could declare individual targets to have
> .LOW_RESOLUTION_TIME:
>
> https://www.gnu.org/software/make/manual/html_node/Special-Targets.html
>
> That doesn't seem any better than using "touch" to make a better mtime
> though. I'm kinda surprised that the Nix project doesn't have this
> problem on other projects, though, if they're always using a modern
> GNU make. What are they doing differently?
I think this is slightly better than using "touch", because it's a
Makefile-level fix instead of kludging around with the file system, and
its designed purpose is to deal with broken tools.
IMHO, The Nth-degree "correct" thing for the postgresql build system
would be check if the most recent versions are vulnerable, and if so
update the configure script to detect a high-resolution filesystem and a
truncating ranlib, and if that is true for that build, then set a
variable so the Makefiles can conditionally add static libraries to
`.LOW_RESOLUTION_TIME` targets. This seems like a lot of work for
marginal payoff, particularly if releases newer than 9.x are not brittle
in this way.
On the Nix question: I'm an itinerant nixpkgs contributor, so I can't
speak definitively, but I think there are at least a couple of things
going on:
1. Nix on macOS is still a bit of a second-class citizen. (I recently
had to fix code that assumed shared objects always ended in ".so",
instead of substituting a variable that expanded to ".dylib" on
macOS).
2. If Nix successfully builds postgres and adds it to a binary cache,
most people will not run the build themselves.
3. This bug seems to be tickled because two different Makefiles use
attempt to build the same target at the same time, using a tool
(macOS libtool/ranlib, albeit through a recursive $(MAKE) invocation)
that doesn't support subsecond timestamps, on a filesystem that does
(APFS). That's a bit of a corner case. I speculate that building a
static library with a nonrecursive Makefile would only kick off one
build of the `.a` file, because make will only invoke the command
once as it walks the DAG of dependencies.
#1 and #2 mean the actual amount of building done is relatively low, and
#3 means that it is actually somewhat hard to trip over.
I have filed https://github.com/NixOS/nixpkgs/issues/51221 with nixpkgs,
and now @dalroth is talking about patching cctools' ranlib.
Thanks again for all your help. I probably won't have time to dig into
this further but if you need more information I'll see what I can do.
-- Jack