블로그 이미지
하루, 글. 그림. 영상매체. 표현을 도와주는 기기들. 도전 중. 동화다아아
    동화다아아

    카테고리

    분류 전체보기 (176)
    잡담 (1)
    IT 기기-리뷰&뉴스 (7)
    리뷰 - 도서 (1)
    리뷰 - 영상 (0)
    리뷰 - 그림/음악 (1)
    내장형 하드웨어 (163)
    Total
    Today
    Yesterday
     

    컴파일 과정

    소스( .c) → 전처리 (.i) → 컴파일(.s) → 어셈블러(.o or .obj) → 링크/링킹 → 실행파일 (.exe)

    ※ 밑줄 부분은 컴파일 과정에서 중간 파일이 생겼다가 지워진다.


    중간 파일을 삭제하지 않고 보여주는 방법.

    # gcc -v [--save-temps] -o test2 first.c


    -v → 컴파일 과정을 화면에 출력한다.

    --save-temps → 컴파일 과정에서 생성되는 중간 파일인 전처리 파일(*.i)과 어셈블리 파일(*.s)를 지우지 않고 현재 디렉토리에 저장한다. 컴파일 과정의 에러를 분석할 때 사용.

    출력화면


     gcc -v [--save-temps] -o test2 first.c 명령으로 컴파일 한 후 출력해본 화면.


    해당 디렉토리에 .i .s .o 의 파일과 실행파일이 생성되었다.


    gcc 실행파일 생성 과정.

    c 파일명을 abc.c  라고 가정하면 $gcc -o abc  abc.c 를 실행해서 abc  라는 실행 파일을 만드는 과정은 아래와 같다.

    (cc1(컴파일러) 과 collect2(링커) 가 존재하는 위치는 gcc 버전마다 조금씩 다르다.)


    1. 전처리  (abc.i  파일 생성)

     $cpp abc.c abc.i


    2. 컴파일 (abc.s  어셈블러 파일 생성)

     $/usr/lib/gcc/i486-linux-gnu/4.0.2/cc1 abc.i


    3. 목적코드 생성( abc.o 오브젝트 파일 생성)

     $as -V -Qy -o abc.o abc.s


    4. 링킹 (ELF)

    /usr/lib/gcc/i486-linux-gnu/4.0.2/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o abc /usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../lib/crt1.o /usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.0.2/crtbegin.o -L/usr/lib/gcc/i486-linux-gnu/4.0.2 -L/usr/lib/gcc/i486-linux-gnu/4.0.2 -L/usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../lib -L/usr/lib/gcc/i486-linux-gnu/4.0.2/../../.. -L/lib/../lib -L/usr/lib/../lib abc.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i486-linux-gnu/4.0.2/crtend.o /usr/lib/gcc/i486-linux-gnu/4.0.2/../../../../lib/crtn.o



    링킹은 조금 복잡하다. 여기서 -dynamic-linker 는 동적 링킹으로 라이브러리를 로드한다는 의미이며 crt 라고 붙은 오브젝트 파일은 리눅스 시스템에서 파일을 실행할때 초기화와 종료시에 실행되는 것들이 들어 있다. -L 옵션은 그 뒤에 있는 경로를 라이브러리 경로로 사용하겠다는 의미 -lxx 옵션은 libxx.x 라는 라이브러리를 읽어들이겠다는 의미가 된다.



    기본 옵션


    gcc -W -Wall -O2 -o test test.c


    -Wall → 모든 모호한 코딩에 대해서 경고를 보내는 옵션

    -W → 합법적이지만 모호한 코딩에 대해서 경고를 보내는 옵션

    -W -Wall → 아주 사소한 모호성에 대해서도 경고

    -O2 → 최적화 레벨을 2로 설정 (거의 대부분의 최적화를 시도)

    o test → 컴파일된 파일명을 test로 하라는 의미


    gcc 옵션

    gcc -E test.c


    -E → 전처리 과정의 결과를 화면에 보이는 옵션. 전처리 과정 중에 발생한 오류를 검증할 때 사용하면 좋다.

    ※ 더 강력한 옵션: --save-temps → 생성되는 test.i 파일을 읽어보는 것이 더 좋은 방법.


    gcc -S test.c

    -S → cc1으로 전처리된 파일을 어셈블리 파일로 컴파일까지만 수행하고 멈춘다. test.s 파일이 만들어진다.

    gcc -c test.c

    -c → as에 의한 어셈블까지만 수행하고 링크는 하지 않음. test.o 까지만 만들어진다.

    gcc -v test.c

    -v → 컴파일 과정을 화면에 출력한다.

    --save-temps → 컴파일 과정에서 생성되는 중간 파일인 전처리 파일(*.i)과 어셈블리 파일(*.s)를 지우지 않고 현재 디렉토리에 저장한다. 컴파일 과정의 에러를 분석할 때 사용.



    c 수업 두 번째

    #include <stdio.h>


    int main()

    {

            printf("1000\n");

            printf("%x\n",1000);

            printf("%o\n",1000);

            printf("%x\n",1000);


            return 0;

    }


    시그윈에서

    gcc -o test1.exe main.c

    ./test1를 실행하면

     

    숫자 1000을 입력하면 그대로 출력된다.

    &d를 사용하면 10진수로 표시 - 1000

    %o를 사용하면 8진수로 표시  - 1750으로 표시된다.

    %x를 사용하면 16진수로 표시 - 3e8로 표시된다.



    컴파일 과정 확인

    소스(□.c) → 전처리(□.i) → 컴파일(□.s) → 어셈블리(□.o or .obj) → 실행파일(□.exe)


    예제


    첫 번째 빨간 사각형 안은 전처리 과정 중 에러가 발생한 것이다.

    main.c:1:2 에서 1:2는 첫째줄과 둘째줄에서 에러가 발생했다는 뜻이고

    invalid preprocessing directive #nclude 는 지시어가 명령한 #nclude가 전처리 과정중에 잘못되었다는 뜻이다.

    directive는 컴퓨터 용어로 지시어(지시자)라는 뜻이 있다. 즉, 전처리기에 명령을 내린다.


    두 번째 빨간 사각형 안은 컴파일 단계에서 에러가 발생한 것이다.

    main.c:3: error: parse error before "main" 이라는 것은 main함수 앞에서 에러구문이 발생했다는 뜻.


    세 번째 빨간 사각형 안 역시 컴파일 단계에서 에러가 발생했다.

    main.c:3: error: parse erroe before ')' token 은 역시 main()에서 (이 빠져서 나온 에러가 표시된 것으로 token이란 기호에 의미가 부여되니 것들을 말한다 할 수 있다. 예를 들면 ;,(,{, 철수가, 집에, 등등 기호에 의미가 부여되어 있을 때 이것을 토큰이라 할 수 있다.)


    ※ 항상 에러의 해결은 에러 발생의 첫줄부터 시작한다. 첫 번째 에러로 인해 나머지 에러들이 발생한 것일 수가 있기 때문이다. 세 번째 빨간 사각형의 경우에서도 ‘(’를 빼먹었을 뿐이지만 뒤에 있는 모든 C 구문이 에러가 났다.


    - 컴파일러 단계(Parser)에서 에러의 85% 이상이 발생한다.

    - 나머지는 전처리 단계에서 10% 정도 링크/링킹 단계에서 5%정도의 에러가 발생.


    참고 -토큰 (token)-


    어휘(Token)

            프로그램을 구성하고 있는 문법적으로 의미 있는 최소 단위

            문장 “if (i<100) sum+=i;” 은 10개의 토큰으로 이루어짐 
             -> if, (, i, <, 100, ), sum, +=, i, ;

          Mobile C 언어의 토큰

     

    [참고]

    gcc 컴파일 옵션(http://ssulsamo.egloos.com/5247105)

    리눅스 gcc 실행파일 만들기 과정

    (http://blog.naver.com/ohpowel?Redirect=Log&logNo=80024570104)



    Posted by 동화다아아
    , |

    최근에 달린 댓글

    최근에 받은 트랙백

    글 보관함