I now have a build tree that works and a build tree that breaks, from
the same machine and environment, simply by re-running the build with
make --shuffle.
The working jsonapi.o has functions like appendStringInfoChar,
resetStringInfo, etc. The one that fails to link has
appendPQExpBufferChar, resetPQExpBuffer, etc.
This is a makefile dependency bug exposed in parallel builds, and can
be reproduced on demand with a minimal reproducer. From a clean but
configured tree, in src/common:
$ make jsonapi.o
$ readelf -sW jsonapi.o | grep reset
64: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND resetStringInfo
This builds a jsonapi.o using the direct target, and
JSONAPI_USE_PQEXPBUFFER is not defined.
$ make clean
$ make jsonapi_shlib.o
$ readelf -sW jsonapi.o | grep reset
65: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND resetPQExpBuffer
This builds jsonapi_shlib.o, which adds JSONAPI_USE_PQEXPBUFFER to
CPPFLAGS. However jsonapi.o hasn't been built yet so that is also
built, but with the PQEXPBUFFER define set this time.
My builds are with -j32 but also --shuffle, which is very good at
shaking out Makefiles which have dependencies that work via luck: if a
target has dependencies A B C, then normal make would be A then B then
C, but --shuffle might build C then B then A.
Ross