JHB의 프로그래밍 삽질기

GNU Make 강좌 #8 - make 수행 시에 나타나는 에러들 본문

PROGRAMMING/Linux

GNU Make 강좌 #8 - make 수행 시에 나타나는 에러들

roter 2010.04.05 21:27

8. make 수행 시에 나타나는 에러들

make를 수행하게 되면 이상한 에러에 당황을 하게 되는 경우가 많아, 도대체 어디가 틀렸는지 감을 못잡는 경우가 허다하다. 그런데 make 매뉴얼에도 에러에 대한 종류와 그 대처 방안에 대해서는 거의 언급이 없는 관계로 이 부분은 필자의 경험에 의거해서 작성한다. (에러의 원인, 대처 방안이 모두 다 틀렸을 수도 있다는 것을 염두에 두기 바랍니다.)

  1. Makefile:17: *** missing separator. Stop.

    Makefile을 작성할 때 명령어(command)부분은 모두 TAB 문자로 시작해야 한다고 첫 번째 장부터 강조하였다. 위의 에러는 TAB 문자를 쓰지 않았기 때문에 make가 명령어인지 아닌지를 구별 못하는 경우이다.

    대처: 17번째 줄(근처)에서 명령어가 TAB 문자로 시작하게 바꾼다.

  2. make: *** No rule to make target `io.h', needed by `read.o'. Stop.

    위의 에러는 의존 관계에서 문제가 발생했기 때문이다. 즉 read.c가 io.h에 의존한다고 정의되어 있는데, io.h를 찾을 수 없다는 에러이다.

    대처: 의존 관계에서 정의된 io.h가 실제로 존재하는지 조사해 본다. 없다면 그 이유를 한번 생각해 본다. make dep를 다시 실행시켜서 의존 관계를 다시 생성시켜 주는 것도 하나의 방법이다.

  3. Makefile:10: *** commands commence before first target. Stop.

    위의 에러는 '첫 번째 타겟이 나오기 전에 명령어가 시작되었다'는 애매한 에러 메시지이다. 필자가 경험한 이 에러의 원인은 주로 긴 문장을 여러 라인에 표시를 하기 위해서 '\'를 사용할 때, 이를 잘못 사용했기 때문인 것 같다. 즉 '\'부분은 라인의 가장 끝문자가 되어야 하는데 실수로 '\'뒤에 스페이스를 몇 개 집어넣으면 여지없이 위의 에러가 발생한다.

    대처: 10번째 줄(근처)에서 '\'문자가 있거든 이 문자가 라인의 가장 끝문자가 되도록 한다. 즉 '\'문자 다음에 나오는 글자(스페이스가 대부분) 는 모조리 없애 버린다.

  4. make를 수행시키면 의도했던 실행 파일은 안생기고 이상한 행동만 한다. 가령 make clean 했을 때와 같은 행동을 보인다.

    make는 천재가 아니라는 점을 생각해야 한다. make는 Makefile의 내용을 읽다가 첫 번째 타겟으로 보이는 것을 자신이 생성시켜야 할 결과 파일이라고 생각한다. 따라서 clean 부분을 Makefile의 첫번째 타겟으로 정해 버리면 위와 같은 결과가 나타나게 된다.

    대처: 예제 7.1에서 all 이라는 필요 없는 타겟을 하나 만들어 두었다. 이것은 make가 all 을 첫 번째 타겟으로 인식시키기 위함이었다. 따라서 자신이 생성시키고 싶은 결과 파일을 첫 번째 타겟이 되게 하던지, 아니면 예제 7.1처럼 all과 같은 더미 타겟(dummy target)을 하나 만들어 둔다. 그리고 make clean, make dep 같은 부분은 Makefile의 끝부분에 만들어 두는 것이 안전하다.

  5. 이미 컴파일했던 파일을 고치지 않았는데도 다시 컴파일한다.

    이 행동은 make가 의존 관계를 모르기 때문이다. 즉 사용자가 의존 관계를 설정해 주지 않았다는 말이 된다. 따라서 make는 무조건 모든 파일을 컴파일해서 실행 파일을 만드는 일이 자신이 할 일이라고 생각하게 된다.

    대처: 목적 파일, 소스 파일, 헤더 파일들의 의존 관계를 설정해 주어야 한다. gccmakedep *.c 라고 하면 Makefile의 뒷부분에 자동적으로 의존 관계를 만들어 준다. 그외의 다른 파일들에 대해서는 사용자가 적절하게 의존 관계를 설정해 주어야 한다.

    main.o : main.c io.h
    read.o : read.c io.h
    write.o : write.c io.h
    

    위의 예제는 첫 번째 장에서도 제시했던 건데... TARGET : DEPENDENCY의 형식으로 의존 관계를 작성한 것이다. (make에게 의존 관계를 알려주는 방법이죠)

  6. 그 외의 경우에 대해서는 각자가 한번 원인과 결과를 알아보기 바란다. 그리고 팁의 형식으로 글을 올린다면 다른 사람에게도 많은 도움이 될 것이다. 일단 make에서 에러를 내기 시작하면 초보자는 원인조차 모르는 경우가 많기 때문이다.

강좌를 마치면서

이번 make 강좌는 make 유틸리티에 대한 전반적인 이해와 간단한 Makefile 작성을 목적으로 하였습니다. make에 관한 모든 것을 다 소개하지는 않았습니다. (개인적인 능력의 한계 !!) make를 아주 잘 쓰기 위해서는 make 자체에 대한 지식보다는 유닉스(리눅스)의 샐 프로그램과 고난이도(?)의 명령어까지 알고 있어야 하기 때문이죠. 해커가 되려면 이런 지식을 많이 알고 있어야 합니다. 한가지 아쉬운 게 imake에 대해서 설명을 못한 것입니다. imake에 대해서는 make 중급코스란 이름으로 언젠가 강좌를 해보도록 하죠. imake는 Makefile을 생성시켜 준다고 생각하세요)

지금 make 다음의 강좌로 뭘해야 할지 고민 중입니다. 우선 X 강좌를 하시는 분(아직은 조용하네요)의 강좌의 이해를 높이기 위해서 X의 개념을 2회 정도의 강좌로 할 생각입니다. X 가 왜 X 이고 어떤 특징을 가지고 있는지 한번 살펴보기로 하죠.

0 Comments
댓글쓰기 폼