I got a g++ compile error when trying to upgrade from Docker image php:7.2-apache to php:7.4-apache. The base image of php:7.2-apache is debian:buster-slim, and the base image of 7.4-apache is debian:bullseye-slim.
I then recreated the problem between debian:buster-slim and debian:bullseye-slim.
Here's a dockerfile that works:
FROM debian:buster-slim
RUN apt-get -y update && \
apt-get install --yes --no-install-recommends \
openssh-client \
git \
nano \
cron \
ffmpeg \
libjpeg-dev \
libmariadb-dev-compat \
libpng-dev \
libxpm-dev \
libfreetype6-dev \
libwebp-dev \
libjpeg62-turbo-dev \
libgd-dev \
g++
WORKDIR "/test"
RUN printf "#include <stdio.h>\n#include <mysql.h>\n#include <jpeglib.h>\nusing namespace std;\nint main(int argc, const char * argv[]) {\nMYSQL mysql;\nmysql_init(&mysql);\nstruct jpeg_decompress_struct cinfo;\n}" > main.cpp
RUN g++ -std=c++11 -I/usr/include/mysql -lmysqlclient -ljpeg main.cpp -o test
Here's a dockerfile that doesn't work:
FROM debian:bullseye-slim
RUN apt-get -y update && \
apt-get install --yes --no-install-recommends \
openssh-client \
git \
nano \
cron \
ffmpeg \
libjpeg-dev \
libmariadb-dev-compat \
libpng-dev \
libxpm-dev \
libfreetype6-dev \
libwebp-dev \
libjpeg62-turbo-dev \
libgd-dev \
g++
WORKDIR "/test"
RUN printf "#include <stdio.h>\n#include <mysql.h>\n#include <jpeglib.h>\nusing namespace std;\nint main(int argc, const char * argv[]) {\nMYSQL mysql;\nmysql_init(&mysql);\nstruct jpeg_decompress_struct cinfo;\n}" > main.cpp
RUN g++ -std=c++11 -I/usr/include/mysql -lmysqlclient -ljpeg main.cpp -o test
The errors I get include:
main.cpp:(.text+0x23): undefined reference to `mysql_init'
(There's a similar error for the jpeg library if I remove mysql from the dockerfile.)
I believe the problem is that it can't link the mysqlclient and jpeg libraries.
Anyone know the root cause and how to fix? Thanks!
NOTE: I edited the question so that the dockerfiles are self-contained with a "mini" C program (RUN printf...). The image can be built by anyone using:
docker build . -t myimage
I do reproduce the failed build (W11, Docker Desktop 4.21.1 (114176), Docker 24.0.2):
But this Dockerfile worked:
Meaning not:
But instead:
The source file
main.cppis placed before the-loptions.And note that if you were compiling multiple files, they should all come before the
-loptions.For example:
g++ -std=c++11 file1.cpp file2.cpp -I/usr/include/mysql -lmysqlclient -ljpeg -o test.The buster-slim image includes a
gcc-8-base:amd64=8.3.0-6.The bullseye-slim image includes a
gcc-10-base:amd64=10.2.1-6.The GCC 10 release included several linker changes.
And the current gcc linker option documentation includes:
It is best practice to always list libraries after your source or object files when compiling with
gccorg++. That ensures that the linker will correctly resolve all symbols. That is why moving the-loptions to the end of the command solved your problem.