• [C언어] 컴파일 과정에 관한 탐구

    2022. 3. 31.

    by. 안녕진

    상황

    수업시간에 배운 내용 중, Linking과정에서 프로그램에 사용된 외부 라이브러리들의 object file을 연결한다고 배웠다.
    Linking 과정에서만 실제 object file을 연결하므로, Assembly 단계까지는 실제 함수의 몸체가 없어도 prototype만 존재하면 오류가 발생하지 않는다고 한다.
    정말 그럴까 한 번 실험해봤다.

    + 컴파일 과정에 관해 전반적으로 공부해봤다.

     

    과정

    1. myFunc()라는 prototype만 선언된 함수를 사용한 코드를 작성하여

    2. 각 compilation process마다의 출력 파일을 살펴보며 학습할 예정이다.

     

    Preprocessing 과정 (output : preprocessed.i)

    myFunc라는 prototype만 선언된 함수를 사용했다.

     

    위 코드에서 첫 번째 컴파일 과정인 Preprocessing을 하기 위해, 
    gcc 명령에 옵션을 넣고 Preprocessing만 실행했다.

    gcc -E source.c -o preprocessed.i

    preprocessed.i 파일을 열어보면 아래와 같다.

    #include <stdio.h> 부분(preprocessor directive)이 바뀌었고,
    795라인부터 확인하면 실제 소스 코드에서 작성되었던 comment도 사라졌다는 것을 알 수 있다.

     

    stdio.h파일이 뭔지 모르니까, 한 번 찾아봤다.

    cat /usr/include/stdio.h > stdio_h_file

    이렇게 해서 나온 파일과 preprocessed.i 파일에 추가된 부분을 비교해봤다.

     

    stdio.h 파일
    preprocessed.i 파일에 삽입된 stdio.h 부분

    주석이 달린 것 빼고는 똑같아 보인다.

     

    > Preprocessing 과정에서 #으로 시작하는 preprocessor directive를 해석(대체)

    > 주석 삭제

    등의 역할을 한다는 것을 볼 수 있었다.

     

    Compile 과정 (output : assemblyCodeFromSource.s)

    gcc -S source.c -o assemblyCodeFromSource.s

    위와 같이 Compile 단계까지만 진행하면 (Assembly, Linking X)

    아래와 같은 어셈블리어로 작성된 파일이 생긴다.

    assemblyCodeFromSource.s 파일

    어셈블리 공부할 때 봤던 코드들이 나열되어 있는 것을 볼 수 있다.

    "what is compile process???"등 프로그램에 사용된 문자열들이 들어가 있는 것도 보인다.

     

    Assembly 과정 (output : objectFile.o)

    gcc -c source.c -o objectFile.o

    위와 같은 명령을 실행하면 source파일의 object file이 생긴다.

    object file은 assembly 과정을 통해 생기는 파일로, 
    compile 과정에서 생긴 assembly code를 binary code로 변환시킨 것이다.

     

    그냥 읽으려 하면 오류가 발생해서, xxd라는 명령을 사용해 읽어봤다.

    xxd objectFile.o > objectFile

    뭔가 엄청나게 많이 써있는데 what is compile process 같은 글자가 보이는 것으로 보아, 
    저 부분에 뭔가 문자열이 사용되었구나 라는 정도만 알 수 있었다..

     

    Linking 과정 (output : a.out)

    이제 가장 궁금했던 Linking이다.

    4가지 과정을 모두 포함하는 과정이니 그냥 기본적인 컴파일 명령을 하면 된다.

    gcc source.c

    myFunc가 필요하다며 진행되지 않는다.

     

    결론

    4개의 컴파일 과정(Preprocessing, Compile, Assembly, Linking)의 역할을 알아봤다.

    프로그램에 사용된 외부함수들은 Linking 과정에서만 실제로 어떠한 mapping하는 과정을 거친다는 것을 알 수 있었다.

    따라서, Assembly 과정까지는 함수의 실체가 없고 prototype만 선언되어도 문제가 없다는 것을 배웠다.

    댓글