Subject: Problems with statically linking libpq of Postgres 12.0 + musl

From: Pyry Kontio <[email-masked]>
Date: Mon, 17 Feb 2020 13:35:25 +0900

Hi, I maintain a Docker image for easily building static Rust binaries,
with some commonly used libraries pre-built for static linking.
The image is being used to build, for example, a statically linked
Rust wrapper for libpq. The image uses the Musl C standard library.

I recently tried to upgrade to Postgres 12.0, but I'm encountering
some linking issues I didn't use to have with 11.7.
I've been able to reproduce these issues by linking libpq with
a simple C program.

A short script demonstrating the difference between 12.0 and 11.7
can be found here:

https://pastebin.com/ZLR5zQzY

The script uses a Docker images built from a Dockerfile here:
https://gitlab.com/rust_musl_docker/image/-/blob/master/BaseDockerfile.template

The gist of the problem seems to be that linking against libpq
works with 11.7 like this:
(All the packages built from source against musl reside under /musl;
note also that we use the musl GCC wrapper to build and link.)

$ musl-gcc -static -o test test.o -L /musl/lib/ -lpq

But fails with a bunch of "undefined references" to symbols defined in
libpgcommon and libpgport, with 12.0. Here's a listing of filtered output
of the linker: https://pastebin.com/XYXkg30B

Adding libpgcommon and libpgport fixes the issue:

$ musl-gcc -static -o test test.o -L /musl/lib/ -lpq -lpgport -lpgcommon

I guess I could just add those libraries, and call it a day, but there's a bunch
of things that bother me:

1) What changed between 11.7 and 12.0? Is this change intentional or not?
2) The documentation about building libpq
( https://www.postgresql.org/docs/10/libpq-build.html
doesn't say anything about libpgport and libpgcommon being dependencies.
Are they or are they not?

I'd appreciate any insight about this issue.

All the best,
Pyry Kontio

---

From: Pyry Kontio <[email-masked]>
Date: Mon, 17 Feb 2020 14:31:42 +0900

After posting the last post, I got an helpful answer on the
[email-masked], so I'm sharing that here.

It seems that in 12.0 branch, the following change was made:
https://github.com/postgres/postgres/commit/ea53100d5

Some needed source files from libpgcommon and libpqport
used to be directly symlinked to libpq and ecpg sources.
This practice was eschewed to improve maintainability,
so linking libpgcommon and libpqport separatelybecame a necessity.

I was also pointed out that especially libpgcommon defines
some common names without the pg prefix, and if those collide
with names defined elsewhere, funny things will happen.

Nevertheless, the way to link libpq statically from
Postgres 12.0 and on is to include libpgcommon and libpqport.

Thanks for the help to all!
Pyry Kontio