CentOS 7이 설치된 지하 이미지에서 도커 이미지를 구축 중입니다.
컴파일해야 하는 코드에는 C++14/17 표준의 일부 기능이 필요하므로 기본 gcc/g++ 버전을 4.8.5에서 상위 버전으로 업데이트해야 합니다.
Dockerfile에서 g++를 업데이트하기 위해 다음 명령을 실행하는 일부 게시물과 기사를 읽었습니다.
RUN yum -y install centos-release-scl && \
yum -y install devtoolset-7-gcc* && \
source scl_source enable devtoolset-7 &&
g++ -version
올바른 버전이 인쇄됩니다.
g++(GCC) 7.3.1 20180303(레드햇 7.3.1-5)
하지만 make를 통해 코드를 빌드하면 여전히 이전 버전을 사용하므로 -std=c++14
빌드 플래그를 인식하지 못합니다. 이를 확인하기 위해 Makefile에 버전 대상을 추가하고 아래와 같이 Dockerfile에서 명령을 실행했습니다.
파일 생성:
# ...
CXX:=g++
FLAGS:=-Wall -fPIC -std=c++14
# ...
%.o: %.cpp
$(CXX) $(FLAGS) -c $< -o $@ $(INCLUDE_PATH)
# ...
version:
g++ -v
도커파일:
RUN cd /home/admin/${APP_NAME}/nginx-base/cplusplus && make version && make
Docker 빌드 단계 중 출력:
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)
g++ -Wall -fPIC -std=c++14 -c image_engine.cpp -o image_engine.o -I /opt/taobao/tengine/data/include
g++: error: unrecognized command line option '-std=c++14'
make: *** [image_engine.o] Error 1
The command '/bin/sh -c cd /home/admin/${APP_NAME}/nginx-base/cplusplus && make version && make' returned a non-zero code: 2
그렇다면 CentOS의 기본 g++ 대신 Makefile에서 g++-7을 어떻게 활성화해야 합니까?
답변1
Docker에 대한 의견과 내 경험에 따르면 각 RUN
줄은 별도의 셸 환경에서 실행되므로 한 줄에 환경을 가져오면 RUN
해당 환경을 다른 명령에서 사용할 수 없습니다 RUN
.
RUN source scl_source enable devtoolset-7 && cd /home/admin/${APP_NAME}/nginx-base/cplusplus && make version && make
이전 명령 대신 이 행을 사용하면 RUN
해당 명령에 대해 현재 환경이 설정됩니다 make
.
답변2
해결 방법:
SHELL ["sh", "-c", "source scl_source enable $(scl -l) && sh -c \"$0\" \"$@\""]
이는 모든 후속 RUN 쉘을 대체합니다.