This seems to work: # syntax=docker/dockerfile:1 FROM alpine:3.20 AS builder
# Fails with 17.0 succeeds with 16.4 ARG PG=17.0 USER root RUN apk update && apk add --no-cache --update-cache \ ca-certificates-bundle \ util-linux-dev \ execline-dev \ libedit-dev \ libxml2-dev \ clang17-dev \ llvm18-dev \ build-base \ net-tools \ zlib-dev \ autoconf \ automake \ busybox \ icu-dev \ clang17 \ llvm18 \ cmake \ bison \ meson \ ninja \ flex \ perl \ curl \ bash WORKDIR /app RUN curl -L https://github.com/openssl/openssl/releases/download/openssl-3.3.2/openssl-3.3.2.tar.gz > openssl.tar.gz RUN mkdir openssl && tar --extract --file=openssl.tar.gz --strip-components=1 --directory=openssl && rm openssl.tar.gz RUN cd openssl && CC=clang CXX=clang++ perl ./Configure \ linux-$(uname -m) \ --prefix=/usr \ --libdir=lib \ --openssldir=/etc/ssl \ enable-ktls \ shared \ no-zlib \ no-async \ no-comp \ no-idea \ no-mdc2 \ no-rc5 \ no-ec2m \ no-sm2 \ no-sm4 \ no-ssl3 \ no-seed \ no-weak-ssl-ciphers \ -Wa,--noexecstack && \ perl configdata.pm --dump && \ make -j$(nproc) && make install RUN curl -L https://ftp.postgresql.org/pub/source/v$PG/postgresql-$PG.tar.bz2 > postgresql.tar.bz2 RUN mkdir postgresql && tar --extract --bzip2 --file=postgresql.tar.bz2 --strip-components=1 --directory=postgresql && rm postgresql.tar.bz2 COPY <<EOF ./pg.patch Subject: [PATCH] Fix static build --- Index: src/bin/initdb/Makefile <+>UTF-8 =================================================================== diff --git a/src/bin/initdb/Makefile b/src/bin/initdb/Makefile --- a/src/bin/initdb/Makefile (revision c4b8a916f8a53379621825028532b038e004f891) +++ b/src/bin/initdb/Makefile (date 1728466911177) @@ -20,7 +20,8 @@ # from libpq, else we have risks of version skew if we run with a libpq # shared library from a different PG version. Define # USE_PRIVATE_ENCODING_FUNCS to ensure that that happens. -override CPPFLAGS := -DUSE_PRIVATE_ENCODING_FUNCS -I$(libpq_srcdir) -I$(top_srcdir)/src/timezone $(ICU_CFLAGS) $(CPPFLAGS) +#override CPPFLAGS := -DUSE_PRIVATE_ENCODING_FUNCS -I$(libpq_srcdir) -I$(top_srcdir)/src/timezone $(ICU_CFLAGS) $(CPPFLAGS) +override CPPFLAGS := -I$(libpq_srcdir) -I$(top_srcdir)/src/timezone $(ICU_CFLAGS) $(CPPFLAGS) # We need libpq only because fe_utils does. LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport) $(ICU_LIBS) Index: src/common/Makefile <+>UTF-8 =================================================================== diff --git a/src/common/Makefile b/src/common/Makefile --- a/src/common/Makefile (revision c4b8a916f8a53379621825028532b038e004f891) +++ b/src/common/Makefile (date 1728466354406) @@ -143,7 +143,7 @@ # Files in libpgcommon.a should use/export the "xxx_private" versions # of pg_char_to_encoding() and friends. # -$(OBJS_FRONTEND): CPPFLAGS += -DUSE_PRIVATE_ENCODING_FUNCS +#$(OBJS_FRONTEND): CPPFLAGS += -DUSE_PRIVATE_ENCODING_FUNCS # EOF RUN apk update && apk add --no-cache --update-cache git RUN cd postgresql && git apply ../pg.patch RUN cd postgresql && export CC=clang && export CXX=clang++ && \ ./configure --with-openssl --with-libedit-preferred --with-uuid=e2fs --with-libxml --prefix=/usr/local && \ cd src/include && make && make install && \ cd ../common && make && make install && \ cd ../port && make && make install && \ cd ../interfaces/libpq && make && make install COPY <<EOF ./main.cpp #include <algorithm> #include <iostream> #include <chrono> #include <thread> #include <cstring> #include <csignal> #include <vector> #include <libpq-fe.h> void sig_handler(int /*_signo*/, siginfo_t * info, void * /*_ctx*/) { raise(info->si_signo); _exit(EXIT_FAILURE); } void registerSignalHandlers() { std::vector<int> signals = { // Signals for which the default action is "Core". SIGABRT, // Abort signal from abort(3) SIGBUS, // Bus error (bad memory access) SIGFPE, // Floating point exception SIGILL, // Illegal Instruction SIGIOT, // IOT trap. A synonym for SIGABRT SIGQUIT, // Quit from keyboard SIGSEGV, // Invalid memory reference SIGSYS, // Bad argument to routine (SVr4) SIGTRAP, // Trace/breakpoint trap SIGXCPU, // CPU time limit exceeded (4.2BSD) SIGXFSZ, // File size limit exceeded (4.2BSD) SIGTERM }; for (size_t i = 0; i < signals.size(); ++i) { struct sigaction action; memset(&action, 0, sizeof action); action.sa_flags = static_cast<int>(SA_SIGINFO | SA_ONSTACK | SA_NODEFER | SA_RESETHAND); sigfillset(&action.sa_mask); sigdelset(&action.sa_mask, signals[i]); action.sa_sigaction = &sig_handler; sigaction(signals[i], &action, nullptr); } } int main() { registerSignalHandlers(); std::cout << "start" << std::endl; PGconn *conn = PQconnectdb(""); if (conn == NULL) { std::cout << "fail" << std::endl; } else { if (PQstatus(conn) == CONNECTION_OK) { std::cout << "success" << std::endl; } else { fprintf(stderr, "fail: %s", PQerrorMessage(conn)); } PQfinish(conn); } while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } return 0; } EOF # Fails with "-static" succeeds without RUN CC=clang CXX=clang++ clang++ \ -std=c++20 \ -static \ -flto \ -O3 \ -march=native \ -Wpedantic \ -Wall \ -Wextra \ -Wsign-conversion \ -Wconversion \ -o main main.cpp \ -lpq \ -lpgcommon \ -lpgport \ -lssl \ -lcrypto \ -lpthread \ -ldl ENTRYPOINT ["./main"] CMD [] On Wed, Oct 9, 2024 at 10:10 AM Mikael Sand <ms...@seaber.io> wrote: > Hello dear Hackers > > I'm trying to upgrade to v17 and encountering a strange issue. > > I've made a minimal reproduction that works with 16.4 but fails with 17.0, > it also works without the "-static" compile flag: > > > # syntax=docker/dockerfile:1 >> FROM alpine:3.20 AS builder >> >> # Fails with 17.0 succeeds with 16.4 >> ARG PG=17.0 >> >> USER root >> RUN apk update && apk add --no-cache --update-cache \ >> ca-certificates-bundle \ >> util-linux-dev \ >> clang17-dev \ >> execline-dev \ >> llvm18-dev \ >> libedit-dev \ >> libxml2-dev \ >> build-base \ >> net-tools \ >> clang17 \ >> zlib-dev \ >> autoconf \ >> automake \ >> busybox \ >> llvm18 \ >> icu-dev \ >> cmake \ >> bison \ >> flex \ >> perl \ >> curl \ >> bash \ >> flex >> WORKDIR /app >> >> RUN curl -L >> https://github.com/openssl/openssl/releases/download/openssl-3.3.2/openssl-3.3.2.tar.gz >> > openssl.tar.gz >> RUN mkdir openssl && tar --extract --file=openssl.tar.gz >> --strip-components=1 --directory=openssl && rm openssl.tar.gz >> RUN cd openssl && CC=clang CXX=clang++ perl ./Configure \ >> linux-$(uname -m) \ >> --prefix=/usr \ >> --libdir=lib \ >> --openssldir=/etc/ssl \ >> enable-ktls \ >> shared \ >> no-zlib \ >> no-async \ >> no-comp \ >> no-idea \ >> no-mdc2 \ >> no-rc5 \ >> no-ec2m \ >> no-sm2 \ >> no-sm4 \ >> no-ssl3 \ >> no-seed \ >> no-weak-ssl-ciphers \ >> -Wa,--noexecstack && \ >> perl configdata.pm --dump && \ >> make -j$(nproc) && make install >> >> RUN curl -L >> https://ftp.postgresql.org/pub/source/v$PG/postgresql-$PG.tar.bz2 > >> postgresql.tar.bz2 >> RUN mkdir postgresql && tar --extract --bzip2 --file=postgresql.tar.bz2 >> --strip-components=1 --directory=postgresql && rm postgresql.tar.bz2 >> RUN cd postgresql && CC=clang CXX=clang++ ./configure --with-openssl >> --with-libedit-preferred --with-uuid=e2fs --with-libxml --prefix=/usr/local >> RUN cd postgresql/src/include && CC=clang CXX=clang++ make && make install >> RUN cd postgresql/src/common && CC=clang CXX=clang++ make && make install >> RUN cd postgresql/src/port && CC=clang CXX=clang++ make && make install >> RUN cd postgresql/src/interfaces/libpq && CC=clang CXX=clang++ make && make >> install >> >> COPY <<EOF ./main.cpp >> #include <algorithm> >> #include <iostream> >> #include <chrono> >> #include <thread> >> #include <cstring> >> #include <csignal> >> #include <vector> >> >> #include <libpq-fe.h> >> >> void sig_handler(int /*_signo*/, siginfo_t * info, void * /*_ctx*/) { >> raise(info->si_signo); >> _exit(EXIT_FAILURE); >> } >> >> void registerSignalHandlers() { >> std::vector<int> signals = { >> // Signals for which the default action is "Core". >> SIGABRT, // Abort signal from abort(3) >> SIGBUS, // Bus error (bad memory access) >> SIGFPE, // Floating point exception >> SIGILL, // Illegal Instruction >> SIGIOT, // IOT trap. A synonym for SIGABRT >> SIGQUIT, // Quit from keyboard >> SIGSEGV, // Invalid memory reference >> SIGSYS, // Bad argument to routine (SVr4) >> SIGTRAP, // Trace/breakpoint trap >> SIGXCPU, // CPU time limit exceeded (4.2BSD) >> SIGXFSZ, // File size limit exceeded (4.2BSD) >> SIGTERM >> }; >> >> for (size_t i = 0; i < signals.size(); ++i) { >> struct sigaction action; >> memset(&action, 0, sizeof action); >> action.sa_flags = static_cast<int>(SA_SIGINFO | SA_ONSTACK | SA_NODEFER >> | SA_RESETHAND); >> sigfillset(&action.sa_mask); >> sigdelset(&action.sa_mask, signals[i]); >> action.sa_sigaction = &sig_handler; >> sigaction(signals[i], &action, nullptr); >> } >> } >> >> int main() { >> registerSignalHandlers(); >> std::cout << "start" << std::endl; >> PGconn *conn = PQconnectdb(""); >> if (conn == NULL) { >> std::cout << "fail" << std::endl; >> } else { >> if (PQstatus(conn) == CONNECTION_OK) { >> std::cout << "success" << std::endl; >> } else { >> fprintf(stderr, "fail: %s", PQerrorMessage(conn)); >> } >> PQfinish(conn); >> } >> while (true) { >> std::this_thread::sleep_for(std::chrono::milliseconds(1000)); >> } >> return 0; >> } >> EOF >> >> # Fails with "-static" succeeds without >> RUN CC=clang CXX=clang++ clang++ \ >> -std=c++20 \ >> -static \ >> -flto \ >> -O3 \ >> -march=native \ >> -Wpedantic \ >> -Wall \ >> -Wextra \ >> -Wsign-conversion \ >> -Wconversion \ >> -o main main.cpp \ >> -lpq \ >> -lpgcommon \ >> -lpgport \ >> -lssl \ >> -lcrypto \ >> -lpthread \ >> -ldl >> ENTRYPOINT ["./main"] >> CMD [] >> >> > And here is the output: > > 15/15 > RUN CC=clang CXX=clang++ clang++ -std=c++20 -static -flto -O3 > -march=native -Wpedantic -Wall -Wextra -Wsign-conversion -Wconversion -o > main main.cpp -lpq -lpgcommon -lpgport -lssl -lcrypto -lpthread -ldl > ERROR > 1.0s > 1 > /usr/bin/ld: /usr/local/lib/libpq.a(fe-connect.o): in function > `pqConnectOptions2': > 2 > fe-connect.c:(.text+0x1cb4): undefined reference to `pg_encoding_to_char' > 3 > /usr/bin/ld: /usr/local/lib/libpq.a(fe-connect.o): in function > `PQsetClientEncoding': > 4 > fe-connect.c:(.text+0x64a8): undefined reference to `pg_encoding_to_char' > 5 > /usr/bin/ld: /usr/local/lib/libpq.a(fe-exec.o): in function > `pqSaveParameterStatus': > 6 > fe-exec.c:(.text+0x1168): undefined reference to `pg_char_to_encoding' > 7 > /usr/bin/ld: /usr/local/lib/libpq.a(fe-misc.o): in function > `PQenv2encoding': > 8 > fe-misc.c:(.text+0x1394): undefined reference to `pg_char_to_encoding' > 9 > clang++: error: linker command failed with exit code 1 (use -v to see > invocation) > > Any ideas? > > Best regard > Mikael Sand >