Dockerfile构建glibc-2.28报错,交互式容器正常的解决方法
问题描述
以下是改编自GitHub评论的Dockerfile:
FROM centos:centos7 #--------------------------------- #**gcc 8.2.0 :** RUN yum -y install wget bzip2 gcc gcc-c++ glibc-headers make RUN yum upgrade -y ca-certificates RUN mkdir /software RUN wget -c -P /software/ https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-8.2.0/gcc-8.2.0.tar.gz RUN cd /software/ \ && tar -zxvf gcc-8.2.0.tar.gz \ && cd gcc-8.2.0 \ && ./contrib/download_prerequisites #result: #gmp-6.1.0.tar.bz2: OK #mpfr-3.1.4.tar.bz2: OK #mpc-1.0.3.tar.gz: OK #isl-0.18.tar.bz2: OK #All prerequisites downloaded successfully. RUN cd /software/gcc-8.2.0/ \ && mkdir build \ && cd build \ && ../configure --prefix=/usr/local/gcc-8.2.0 --enable-bootstrap --enable-checking=release --enable-languages=c,c++ --disable-multilib \ && make #Can take up to 3 hours RUN cd /software/gcc-8.2.0/build \ && make install \ && echo -e '\nexport PATH=/usr/local/gcc-8.2.0/bin:$PATH\n' >> /etc/profile.d/gcc.sh && source /etc/profile.d/gcc.sh \ && ln -sv /usr/local/gcc-8.2.0/include/ /usr/include/gcc \ && ldconfig -v \ && ldconfig -p |grep gcc #result: #libgcc_s.so.1 (libc6,x86-64) => /lib64/libgcc_s.so.1 #check version RUN gcc -v #------------------------------------ #**make 4.2.1:** RUN cd /software \ && make -v \ && wget https://ftp.gnu.org/gnu/make/make-4.2.1.tar.gz \ && tar -zxvf make-4.2.1.tar.gz \ && cd make-4.2.1 \ && mkdir build \ && cd build \ && ../configure --prefix=/usr \ && sh build.sh \ && make install \ && make -v #---------------------------------------- #**bison 3.0.4** RUN yum install -y bison RUN bison -V #-------------------------------------------------------- #all prereqs complete, install glibc-2.28 #Download glibc-2.28 from http://ftp.gnu.org/gnu/glibc into /software RUN cd /software \ && wget http://ftp.gnu.org/gnu/glibc/glibc-2.28.tar.gz \ && tar -xf glibc-2.28.tar.gz \ && cd glibc-2.28 \ && mkdir build \ && cd build \ && ../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin \ && make \ && make install \ && ls -l /lib64/libc.so.6 #Check versions : #strings /lib64/libc.so.6 | grep GLIBC # #result: #..... #GLIBC_2.26 #GLIBC_2.27 #GLIBC_2.28 #GLIBC_PRIVATE
执行docker build时,最后一个RUN块会报错:
#17 2.197 configure: error: #17 2.197 *** These critical programs are missing or too old: compiler #17 2.197 *** Check the INSTALL file for required versions
但通过以下操作执行最后RUN块的命令时却无错误:
- 基于去掉最后RUN块的Dockerfile构建镜像;
- 使用
docker run ...创建交互式容器; - 在容器内手动执行最后RUN块的所有命令。
已尝试将cd与configure放在同一个RUN块,但无效。此外,通过yum/dnf直接使用patchelf的方法不可行,但可能通过Nix或Buildroot实现。另外,执行make install后yum包管理器会损坏,原因不明。
需要解决docker build与docker run上下文差异导致的编译错误问题。
解决方案
1. 强制指定新gcc的完整路径
Docker build时,每个RUN块是独立的shell会话,/etc/profile.d/gcc.sh中的PATH设置仅对当前RUN块生效,后续RUN块不会自动加载。修改最后一个RUN块,在configure时直接指定新gcc的路径:
RUN cd /software \ && wget http://ftp.gnu.org/gnu/glibc/glibc-2.28.tar.gz \ && tar -xf glibc-2.28.tar.gz \ && cd glibc-2.28 \ && mkdir build \ && cd build \ && CC=/usr/local/gcc-8.2.0/bin/gcc CXX=/usr/local/gcc-8.2.0/bin/g++ ../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin \ && make \ && make install \ && ls -l /lib64/libc.so.6
2. 在RUN块开头显式加载环境变量
在最后一个RUN块开头手动source环境变量,确保PATH生效:
RUN source /etc/profile.d/gcc.sh \ && cd /software \ && wget http://ftp.gnu.org/gnu/glibc/glibc-2.28.tar.gz \ && tar -xf glibc-2.28.tar.gz \ && cd glibc-2.28 \ && mkdir build \ && cd build \ && ../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin \ && make \ && make install \ && ls -l /lib64/libc.so.6
3. 关于yum损坏的说明
升级glibc到2.28会替换CentOS 7的系统核心库,而CentOS 7的yum依赖旧版glibc,因此yum损坏是预期结果。如果后续需要使用包管理,建议:
- 在升级glibc前完成所有yum安装操作;
- 将glibc升级放在镜像构建的最后一层,且不再使用yum;
- 备选方案:使用Nix或Buildroot构建包含新版glibc的基础镜像,避免直接替换CentOS 7的系统库。
内容的提问来源于stack exchange,提问作者jrbe228
相关产品推荐
相关产品推荐

