Egloos | Log-in
F/OSS study
F/OSS study
[gcc] GCC 빌드 과정 분석 (1)
gcc : 4.4.0


gcc의 빌드 과정은 크게 두 단계로 나뉜다.
먼저 컴파일러 자체를 새로 빌드하는 bootstrap 과정이 있고
두 번째는 새로 빌드한 컴파일러를 이용하여 runtime library들을 빌드하는 과정이다.

bootstrap 과정은 (기본 설정으로) 3 단계를 거치는데
(기존 컴파일러의 동작이 의심스럽다면 make bootstrap4 명령을 통해
4 단계 bootstrap 과정을 거치도록 빌드할 수도 있다.)
stage1에서는 기존에 사용 중인 컴파일러를 이용하여 gcc를 빌드하는 데
이 때는 (별다른 설정이 없다면) C 언어 front-end 만을 빌드한다.

# Only build the C compiler for stage1, because that is the only one that
# we can guarantee will build with the native compiler, and also it is the
# only thing useful for building stage2. STAGE1_CFLAGS (via CFLAGS),
# MAKEINFO and MAKEINFOFLAGS are explicitly passed here to make them
# overrideable (for a bootstrap build stage1 also builds gcc.info).

STAGE1_CHECKING=--enable-checking=yes,types
STAGE1_LANGUAGES=c

stage2와 stage3는 각각 이전 stage의 C 컴파일러를 이용하여 gcc를 빌드하는 데
이것은 컴파일러가 제대로 동작하는지 확인하기 위해 동일한 작업을 반복하는 것이다.
stage3가 끝다면 stage2의 object 파일과 stage3의 모든(?) object 파일을 비교하여
다른 점이 없는지 확인한다.
(stage3를 건너뛰고 싶다면 make bootstrap2 명령으로 빌드를 실행하면 된다.)

bootstrap 단계가 끝나면 host 및 target system에 필요한 tool/library 들을 빌드하는 과정으로
host에서 필요한 것(e.g. autoconf, make, binutils)들은 지금 단계에서 할 일이 없는 것 같고
(이들은 별도의 패키지로 존재하며 gcc 빌드 전에 이미 시스템에서 이용가능해야 한다.)
libgcc, libstdc++-v3, libmudflap, libssp 등과 같은 runtime library 들을 빌드한다.

bootstrap 단계는 제법 오래 걸리기 때문에, 필요하다면 (하지만 권장하지는 않는다)
configure 시에 --disable-bootstrap 옵션을 주어 gcc 빌드 시 bootstrap 과정을 거치지 않고
바로 runtime library 만을 빌드하도록 할 수도 있다.

configure 후에 그냥 make를 실행하면 bootstrap과 library를 빌드한다.
별다른 설정이 없다면 이는 make bootstrap 명령을 실행한 것과 동일하다.
(아래에서 보다시피 stage_final을 적절히 만들면 bootstrap 단계를 조정할 수 있다.)

all:
    [ -f stage_final ] || echo stage3 > stage_final
    @r=`${PWD_COMMAND}`; export r; \
    s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
    $(MAKE) $(RECURSE_FLAGS_TO_PASS) `cat stage_final`-bubble   # <-- bootstrap
    @: $(MAKE); $(unstage)
    @r=`${PWD_COMMAND}`; export r; \
    s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
    if [ -f stage_last ]; then \
      $(MAKE) $(TARGET_FLAGS_TO_PASS) all-host all-target; \    # <-- runtime library
    else \
      $(MAKE) $(RECURSE_FLAGS_TO_PASS) all-host all-target; \
    fi

실제로 Makefile에서 bootstrap 과정을 다루는 부분은 bubble 부분이다.
stage1, 2, 3에서 이 부분은 거의 유사하므로 stage3 만을 살펴보자.

stage3-bubble:: stage2-bubble
    @r=`${PWD_COMMAND}`; export r; \
    s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
    if test -f stage3-lean || test -f stage2-lean  ; then \
      echo Skipping rebuild of stage3 ; \
    else \
      $(MAKE) stage3-start; \
      if $(LEAN); then \
        rm -rf stage1-* ; \
        $(STAMP) stage1-lean ; \
      fi; \
      $(MAKE) $(RECURSE_FLAGS_TO_PASS) all-stage3; \
    fi
    $(MAKE) $(RECURSE_FLAGS_TO_PASS) compare

먼저 r과 s 변수를 각각 현재 디렉터리 (root?)와 소스 디렉터리로 설정하고
stage3-start를 시작한다.
stageX-start는 all-stageX에서 빌드할 디렉터리들을 준비하는 역할을 한다.
stage3-start에서는 (예를 들어 libcpp 디렉터리에 대해)
기존의 libcpp 디렉터리의 이름을 stage2-libcpp로 바꾸고 (stage)
stage3-libcpp 디렉터리를 libcpp로 이름을 바꾼다. (unstage)

all-stage3는 다음과 같은 의존성을 가지고 있다.
  • all-stage3-gcc
  • all-stage3-intl
  • all-stage3-libcpp
  • all-stage3-libdecnumber
  • all-stage3-libiberty
  • all-stage3-zlib
  • all-stage3-target-libgcc
각각은 디렉터리 이름에 매핑되며 내부의 동작은 다음 기회에 살펴볼 것이다.
(이들은 필요에 따라 maybe-all-build-XXX 부분을 수행한다 - 아래 참조)

all-stage3가 끝나면 compare 부분을 수행한다.
이는 cmp 명령을 이용하여 gcc 디렉터리 내의 모든 object 파일을 byte-by-byte로 비교한다.
아래는 compare 부분의 일부이다.

do-compare = cmp --ignore-initial=16 $$f1 $$f2

compare:
    ...
    cd stage3-gcc; \
    files=`find . -name "*$(objext)" -print` ; \
    cd .. ; \
    for file in $${files} ; do \
      f1=$$r/stage2-gcc/$$file; f2=$$r/stage3-gcc/$$file; \
      $(do-compare) > /dev/null 2>&1; \
    ...

이렇게 bootstrap 단계(stage3-bubble)가 끝나면 unstage 명령을 수행하여
디렉터리 이름을 온전히 복구한다.
(stage와 unstage 명령은 직접 호출하지 않고 아래와 같은 형태로 호출된다.)

# While making host and target tools, symlinks to the final stage must be
# there, so $(unstage) should be run at various points.  To avoid excessive
# recursive invocations of make, we "inline" them using a variable.  These
# must be referenced as ": $(MAKE) ; $(unstage)" rather than "$(unstage)"
# to avoid warnings from the GNU Make job server.

unstage = if [ -f stage_last ]; then [ -f stage_current ] || $(MAKE) `cat stage_last`-start || exit 1; else :; fi
stage = if [ -f stage_current ]; then $(MAKE) `cat stage_current`-end || exit 1; else :; fi
current_stage = "`cat stage_current 2> /dev/null`"

.PHONY: unstage stage
unstage:
    @: $(MAKE); $(unstage)
stage:
    @: $(MAKE); $(stage)

그리고는 all-host와 all-target 부분을 빌드한다.
all-host와 all-target은 각각 maybe-all-XXX, maybe-all-target-XXX에 대한 의존성을 가지는데
maybe로 시작하는 부분은 설정에 따라 rule이 존재할 수도 있고 없을 수도 있는데
all-host에서 참조하는 것은 모두 rule이 존재하지 않으며 all-target에 대한 것은 다음과 같다.
(이 중 rule이 존재하지 않는 것은 (X) 표로 표시하였다.)

all-target: maybe-all-target-libstdc++-v3
all-target: maybe-all-target-libmudflap
all-target: maybe-all-target-libssp
all-target: maybe-all-target-newlib       (X)
all-target: maybe-all-target-libgcc
all-target: maybe-all-target-libgfortran
all-target: maybe-all-target-libobjc
all-target: maybe-all-target-libtermcap   (X)
all-target: maybe-all-target-winsup       (X)
all-target: maybe-all-target-libgloss     (X)
all-target: maybe-all-target-libiberty
all-target: maybe-all-target-gperf        (X)
all-target: maybe-all-target-examples     (X)
all-target: maybe-all-target-libffi
all-target: maybe-all-target-libjava
all-target: maybe-all-target-zlib
all-target: maybe-all-target-boehm-gc
all-target: maybe-all-target-qthreads     (X)
all-target: maybe-all-target-rda          (X)
all-target: maybe-all-target-libada       (X)
all-target: maybe-all-target-libgomp

by namhyung | 2009/07/28 03:39 | System | 트랙백(1) | 덧글(0)
트랙백 주소 : http://studyfoss.egloos.com/tb/5060048
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from tomato_house at 2010/02/09 17:08

제목 : [gcc] GCC 빌드 과정 분석 (1)
[gcc] GCC 빌드 과정 분석 (1)...more

:         :

:

비공개 덧글

◀ 이전 페이지 다음 페이지 ▶

카테고리
General
Application
System
Kernel
Book
Tips
태그
algorithm computer-architecture awk vcs SMP C memory blktrace x86 sed binutils scm block-layer git build kernel glibc patch synchronization documentation gcc perf elf compiler CARM script linux emacs CAaQA3 bash
전체보기
이글루 파인더

최근 등록된 덧글
1번은 call-stack 금방 확인이 ..
by 혁 at 11/13
해당 문법에 대한 자세한 가이드 같..
by ㅇㄷㅎ at 11/07
perf에 대한 설명 감사드립니다! ..
by flavono123 at 10/24
최근 등록된 트랙백
Tod's Ferrari Homme
by Tods Pas Cher,Kodak did ..
Mocassin Femme
by Mocassins Homme, I got so..
natural garcinia cambogia
by
rss

skin by jiinny


X