Re: Build issue with postgresql 17 undefined reference to `pg_encoding_to_char' and `pg_char_to_encoding' - Mailing list pgsql-hackers

From Mikael Sand
Subject Re: Build issue with postgresql 17 undefined reference to `pg_encoding_to_char' and `pg_char_to_encoding'
Date
Msg-id CAAwAxZcOvH1Uo5+GQGEJqpCd4V-jrVnirGovO3+P4FYpe2-c+g@mail.gmail.com
Whole thread Raw
In response to Re: Build issue with postgresql 17 undefined reference to `pg_encoding_to_char' and `pg_char_to_encoding'  (Aleksander Alekseev <aleksander@timescale.com>)
Responses Re: Build issue with postgresql 17 undefined reference to `pg_encoding_to_char' and `pg_char_to_encoding'
List pgsql-hackers
Hmm, so is static linking of all applications that include libpq intentionally broken?

At least googling around, it seems like a relatively common practice.

At least it seems that 2ndquadrant builds and uses libpq statically.
https://www.postgresql.org/message-id/20327.1501536978%40sss.pgh.pa.us

I don't see how your script would fix the naming of these functions, can you elaborate?

Here is a Dockerfile demonstrating the same issue with the postgres:17.0-alpine3.20 image:

FROM postgres:17.0-alpine3.20 AS builder
USER root
WORKDIR /app
RUN apk update && apk add --no-cache --update-cache \
openssl-libs-static \
cyrus-sasl-static \
libevent-static \
libxml2-static \
libedit-static \
libxslt-static \
sqlite-static \
openldap-dev \
libxslt-dev \
libxml2-dev \
zstd-static \
zlib-static \
libedit-dev \
openssl-dev \
lz4-static \
e2fsprogs \
zstd-dev \
keyutils \
zlib-dev \
gdbm-dev \
clang17 \
lz4-dev \
libldap \
bison \
curl \
perl \
make

COPY <<EOF ./main.cpp
#include<libpq-fe.h>
int main(){return PQconnectdb("")==NULL;}
EOF

RUN curl -L https://kerberos.org/dist/krb5/1.21/krb5-1.21.3.tar.gz > krb5-1.21.3.tar.gz && tar xf krb5-1.21.3.tar.gz
RUN cd krb5-1.21.3/src && \
./configure && make && make install && \
./configure --disable-shared --enable-static && make && make install

RUN curl -L https://github.com/cyrusimap/cyrus-sasl/releases/download/cyrus-sasl-2.1.28/cyrus-sasl-2.1.28.tar.gz > cyrus-sasl-2.1.28.tar.gz
RUN tar xf cyrus-sasl-2.1.28.tar.gz && cd cyrus-sasl-2.1.28 && ./configure --enable-static && make && make install

RUN clang++ -fno-common -static -o main main.cpp \
-L/usr/local/lib -lpq -L/usr/lib/llvm15/lib -L/usr/local/lib -lpgcommon -lpgport -lgssapi_krb5 -lm -lldap -lcrypto -ldl -pthread \
-lldap -levent -lsasl2 -lssl -lcrypto -llber -levent \
-lsqlite3 \
-L/usr/local/lib -lkrb5 -lk5crypto -lcom_err -lkrb5support \
-lgdbm \
-lssl \
-lgssapi_krb5


On Thu, Oct 10, 2024 at 1:51 PM Aleksander Alekseev <aleksander@timescale.com> wrote:
Hi Mikael,

> This is for compiling a c++ application that uses libpq with the -static flag, the server compiles fine.

OK. I couldn't quite do this because the only Linux machine I have at
the moment runs Raspbian and there doesn't seem to be a static glibc
available for it. But here is how to achieve what you want *in
theory*.

First compile Postgres from the source code, for instance (change the
flags as needed, you probably want a release build):

```
# sudo apt install clang-16
# git clean -dfx
CFLAGS="-static" meson setup --buildtype debug -Dicu=disabled
-Dldap=disabled -Dreadline=disabled -Dzlib=disabled -Dlz4=disabled
-Dprefix=/home/eax/pginstall build
ninja -C build
```

I recommend using Meson and Ninja. Autotools and Make are still
supported but are slow and probably will be gone in a few years. The
"ninja -C build" steps fail for me with various errors about the need
for static glibc but I think it should work on other distributions and
architectures.

Next install Postgres. I use a script for this [1]:

```
~/pgscripts/single-install-meson.sh
```

Change the script as needed - you probably don't need pg_ctl,
createdb, etc for your task.

Now in order to compile and execute your C++ program:

```
export PRFX=/home/eax/pginstall
g++ -g -Wall -o test_libpq -I$PRFX/include
-L$PRFX/lib/aarch64-linux-gnu/ test_libpq.cpp -lpq -static
LD_LIBRARY_PATH=$PRFX/lib/aarch64-linux-gnu/ ./test_libpq
```

This being said I don't recall seeing anything about the support of
static linking of libpq in the documentation [2]. To my knowledge this
is not officially supported / tested / maintained which means you and
your colleagues are on your own with the -static flag. Since you are
already using Docker, perhaps the easiest thing to do would be to back
the application and all its dependencies (dynamically linked) in a
Docker container.

Good luck.

[1]: https://github.com/afiskon/pgscripts/
[2]: https://www.postgresql.org/docs/current/libpq.html

--
Best regards,
Aleksander Alekseev

pgsql-hackers by date:

Previous
From: Bertrand Drouvot
Date:
Subject: Re: BF mamba failure
Next
From: Fujii Masao
Date:
Subject: Re: Using per-transaction memory contexts for storing decoded tuples