Here is a simpler Dockerfile for making a static build of a c++ application using libpq from postgresql 17
# syntax=docker/dockerfile:1 > FROM alpine:3.20 AS builder > USER root > WORKDIR /app > RUN apk update && apk add --no-cache --update-cache \ > openssl-libs-static \ > e2fsprogs-dev \ > readline-dev \ > libxml2-dev \ > openssl-dev \ > zlib-dev \ > clang17 \ > icu-dev \ > bison \ > flex \ > perl \ > make \ > curl \ > git > > ARG PG=17.0 > 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 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 > > 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 another to verify that the build is actually static, run inside wolfi undistro made for running a single static binary (and using clang-19 instead of 17): # syntax=docker/dockerfile:1 > FROM cgr.dev/chainguard/git:latest-dev AS builder > USER root > WORKDIR /app > RUN apk update && apk add --no-cache --update-cache \ > e2fsprogs-dev \ > clang-19-dev \ > execline-dev \ > libedit-dev \ > libxml2-dev \ > openssl-dev \ > llvm-19-dev \ > build-base \ > clang-19 \ > zlib-dev \ > icu-dev \ > llvm-19 \ > bison \ > flex \ > perl \ > curl > > ARG PG=17.0 > 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 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 > > RUN ln /usr/lib/llvm-19/lib/LLVMgold.so /usr/lib/LLVMgold.so > 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 [] > > FROM cgr.dev/chainguard/static:latest AS runner > WORKDIR /app > COPY --from=builder --chown=65532:65532 /app/main . > USER 65532 > ENTRYPOINT ["./main"] > CMD [] > > Hope this can help somebody Br Mikael On Wed, Oct 9, 2024 at 11:51 AM Mikael Sand <ms...@seaber.io> wrote: > 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 >> >