5.10. GCC-9.2.0 - 2단계

GCC 패키지는 C, C++ 컴파일러가 들어있는 GNU 컴파일러 컬렉션을 포함하고 있다.

예상 빌드 시간: 13 SBU
필요 디스크 공간: 3.7 GB

5.10.1. GCC 설치

우리의 첫 번째 GCC 빌드는 내부 시스템 헤더 몇 개 설치했다. 이 중 하나인 limits.h에는, 보통 해당 시스템의 limits.h 헤더, 즉 /tools/include/limits.h가 포함된다. 그러나 GCC의 첫 빌드 때는 /tools/include/limits.h가 존재하지 않았으므로, GCC가 설치한 내부 헤더는 일부에 불과한 독립적 파일이며 시스템 헤더의 확장 기능이 들어있지 않다. 이는 임시 libc를 빌드하는 데는 적합했지만, 지금 GCC를 빌드하는 데는 전체 내부 헤더가 필요하다. 일반적인 상황에서 GCC 빌드 시스템이 수행하는 것과 동일한 명령을 사용해서 내부 헤더의 전체 버전을 만든다:

cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
  `dirname $($LFS_TGT-gcc -print-libgcc-file-name)`/include-fixed/limits.h

다시 한 번, /tools에 설치된 것을 사용하도록 GCC의 기본 동적 링커 위치를 변경하라.

for file in gcc/config/{linux,i386/linux{,64}}.h
do
  cp -uv $file{,.orig}
  sed -e 's@/lib\(64\)\?\(32\)\?/ld@/tools&@g' \
      -e 's@/usr@/tools@g' $file.orig > $file
  echo '
#undef STANDARD_STARTFILE_PREFIX_1
#undef STANDARD_STARTFILE_PREFIX_2
#define STANDARD_STARTFILE_PREFIX_1 "/tools/lib/"
#define STANDARD_STARTFILE_PREFIX_2 ""' >> $file
  touch $file.orig
done

x86_64에서 빌드하는 경우, 64비트 라이브러리의 기본 디렉토리 이름을 lib로 변경하라:

case $(uname -m) in
  x86_64)
    sed -e '/m64=/s/lib64/lib/' \
        -i.orig gcc/config/i386/t-linux64
  ;;
esac

GCC의 첫 번째 빌드와 마찬가지로 GMP, MPFR 및 MPC 패키지가 필요하다. tarbal의 압축을 풀고 필요한 디렉토리 이름으로 변경하라:

tar -xf ../mpfr-4.0.2.tar.xz
mv -v mpfr-4.0.2 mpfr
tar -xf ../gmp-6.2.0.tar.xz
mv -v gmp-6.2.0 gmp
tar -xf ../mpc-1.1.0.tar.gz
mv -v mpc-1.1.0 mpc

이제 Glibc-2.31에서 나온 문제를 해결한다:

sed -e '1161 s|^|//|' \
    -i libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc

다시 별도의 빌드 디렉토리를 생성한다:

mkdir -v build
cd       build

GCC 빌드를 시작하기 전에, 기본 최적화 플래그를 덮어쓰는 환경 변수들을 반드시 해제하라.

GCC 컴파일을 준비한다:

CC=$LFS_TGT-gcc                                    \
CXX=$LFS_TGT-g++                                   \
AR=$LFS_TGT-ar                                     \
RANLIB=$LFS_TGT-ranlib                             \
../configure                                       \
    --prefix=/tools                                \
    --with-local-prefix=/tools                     \
    --with-native-system-header-dir=/tools/include \
    --enable-languages=c,c++                       \
    --disable-libstdcxx-pch                        \
    --disable-multilib                             \
    --disable-bootstrap                            \
    --disable-libgomp

Configure 옵션들의 의미:

--enable-languages=c,c++

C와 C++ 컴파일러가 모두 빌드되도록 한다.

--disable-libstdcxx-pch

libstdc++를 위해 사전 컴파일된 헤더(PCH)를 빌드하지 않도록 한다. 디스크 공간을 많이 차지하며, 우리에게 쓸모가 없다.

--disable-bootstrap

네이티브 GCC 빌드는 "부트스트랩" 빌드가 기본값이다. 이것은 단순히 GCC를 컴파일하는 것이 아니라 여러번 컴파일한다. 1차 컴파일 결과를 활용해 2차 빌드를 한 뒤, 3차 컴파일을 한다. 두 번째와 세 번째 반복을 거쳐 제스스로 완전히 복제가 가능한 지 비교한다. 이를 통해 정확하게 컴파일됐는지의 여부도 알 수 있다. 그러나 LFS 빌드 과정은 매번 부트스트랩할 필요 없이 견고한 컴파일러를 제공할 것이다.

패키지를 컴파일한다:

make

패키지를 설치한다:

make install

마무리 작업으로 심볼릭 링크를 만든다. 많은 프로그램들과 스크립트들은 gcc대신 cc를 실행함으로써 GNU C 컴파일러가 항상 설치되어있지 않은 모든 종류의 UNIX 시스템에서도 사용할 수 있게 범용성을 유지한다. cc를 사용하면 시스템 관리자가 어떤 C 컴파일러를 설치할 지 자유롭게 결정하도록 할 수 있다:

ln -sv gcc /tools/bin/cc
[경고]

경고

여기서 잠깐 멈추고 새로운 툴체인의 기본 기능(컴파일 및 링크)이 기대한 대로 잘 작동하는지 확인하는 것이 우선이다. 다음 명령으로 온전성 검사를 수행하라:

echo 'int main(){}' > dummy.c
cc dummy.c
readelf -l a.out | grep ': /tools'

모든 것이 제대로 작동하면 오류가 없어야 하며 마지막 명령의 출력은 다음과 같을 것이다:

[Requesting program interpreter: /tools/lib64/ld-linux-x86-64.so.2]

32비트 시스템에서는 동적 링커가 /tools/lib/ld-linux.so.2임을 참고하라.

만약 출력이 위와 같이 표시되지 않거나 출력이 전혀 없다면, 무언가 잘못된 것이다. 이전 단계로 돌아가 어디서 문제가 생겼는지 파악하고 수정하라. 이 문제는 계속 진행하기 전에 반드시 해결해야 한다. 먼저 cc 대신 gcc를 사용하여 온전성 검사를 다시 실행하라. 만약 잘 된다면, /tools/bin/cc가 누락된 것이다. 앞서 언급한 심볼릭 링크를 생성하라. 그런 다음 PATH가 올바른지 확인하라. echo $PATH를 실행했을 때 결과 맨 앞에 /tools/bin가 나오면 올바른 것이다. PATH가 잘못됐다면 lfs 유저로 로그인하지 않았거나 4.4절. “환경 구축.”에서 문제가 발생했다는 의미이다.

모두 잘 됐다면, 테스트 파일을 정리하라:

rm -v dummy.c a.out

이 패키지에 대한 자세한 정보는 6.25.2절. “GCC의 내용.”에서 찾을 수 있다.