Makefile 에러 정리
프로그래밍 2011. 10. 26. 19:11 |make
에 의해서 생성될 수 있는 가장 일반적인 에러들의 리스트이며 그것들이 의미하는 바와 그것들을 고치는 방법에 대한 정보이다.때때로 make
에러들은, 특별히 명령 스크립트 라인에서 -
접두사가 있을 때나 명령 라인 옵션으로써-k
가 있을 때, 치명적인 것이 아니다. 치명적인 에러들은 ***
문자열이 그 앞에 붙는다.
에러 메시지들은 모두 프로그램(보통 `make')의 이름이 앞에 붙거나, 에러가 makefile 안에 있는 것이라면 문제를 담고 있는 파일과 라인넘버가 앞에 붙는다.
아래 테이블에서 이런 공통 접두사들이 빠져있다.
- `[foo] Error NN'
- `[foo] signal description'
- 이런 에러들은 실제로
make
에러들이 전혀 아니다. 그들은make
가 명령 스크립트의 일부로써 호출한 프로그램이,make
가 실패로 해석하는 0이 아닌 에러 코드 (`Error NN') 를 리턴하거나 다른 이상한 스타일로(어떤 종류의 시그널과 함께) 종료하였다는 것을 의미한다.***
가 메시지에 붙어 있지 않으면 서브프로세스가 실패했지만 makefile 의 그 규칙이 특수 문자-
를 앞에 달고 있어서make
가 그 에러를 무시한 것이다. - `missing separator. Stop.'
- 이것은
make
의 일반적인 "Huh?" 에러 메시지이다. 이것은make
가 makefile 의 이 라이을 파싱하면서 완벽하게 성공하지 못했다는 것을 의미한다. 이것은 기본적으로 "문법 에러(syntax error)" 를 의미한다. 이런 메시지가 나오는 가장 일반적인 이유들 중의 하나는 여러분이 (또는 많은 MS-Windows 에디터들의 경우와 비슷하게, 여러분의 에디터가) TAB 문자 대신에 공백들로 명령 스크립트들을 들여쓰기하려고 하는 것이다. 명령 스크립트에 있는 모든 라인은 반드시 TAB 문자로 시작하는 것을 기억하자. 8개의 공백은 의미가 없다. - `commands commence before first target. Stop.'
- `missing rule before commands. Stop.'
- 이것은 makefile 에서 처음으로 나오는 것이 명령 스크립트의 일부분인 것처럼 보인다는 것을 의미한다: 이것은 TAB 문자로 시작하고 합법적인
make
명령(변수 할당과 같은)처럼 보이지 않는다. 명령 스크립트들은 항상 어떤 타겟과 연결되어 있어야 한다. 두번째 형태는 그 라인이 첫번째 공백문자가 아닌 문자로써 세미콜론을 가진다면 생성된다;make
는 이것을, 어떤 규칙의 "target: dependency" 섹션을 그냥 떠났다는 것으로 해석한다. - `No rule to make target `xxx'.'
- `No rule to make target `xxx', needed by `yyy'.'
- 이것은
make
가 타겟을 빌드할 필요가 있다고 판단했지만 makefile 안에서 그렇게 하는 것에 대한, 명시적 또는 묵시적(디폴트 규칙 데이터베이스를 포함해서) 규칙들(instructions)도 찾을 수 없다는 것을 의미한다. 그 파일이 빌드되기를 원한다면 그 타겟이 빌드되는 방법을 설명하는 규칙을 추가할 필요가 있다. 이 문제의 다른 가능성은 makefile 을 오자(그 파일 이름이 잘못되었다)했거나 소스 트리가 잘못된 경우이다(그 파일이 빌드될 것으로 생각된 것이 아니고 단지 종속물이다). - `No targets specified and no makefile found. Stop.'
- `No targets. Stop.'
- 전자는 명령행에서 빌드될 타겟을 하나도 제공하지 않았고
make
가 읽어들일 makefile 들을 찾을수 없다는 것을 의미한다. 후자는 어떤 makefile 들이 찾아졌으나 디폴트 타겟이 없고 어떤 것도 명령행에서 주어지지 않았다는 것을 의미한다. 이들 경우에 GNUmake
는 아무것도 하지 않는다. - `Makefile `xxx' was not found.'
- `Included makefile `xxx' was not found.'
- 명령행에서 주어진 makefile (첫번째 형태) 또는 포함된 makefile (두번째 형태) 가 없다.
- `warning: overriding commands for target `xxx''
- `warning: ignoring old commands for target `xxx''
- GNU
make
는 타겟 하나에 대해서 단 한번만 명령들이 지정되는 것을 허락한다(더블-콜론 규칙들을 제외하고). 이미 명령들을 가지도록 정의된 타겟에 대해서 명령들을 다시 주면 이 경고가 발행되고 두번째 명령들은 첫번째 것을 오버라이드할 것이다. - `Circular xxx <- yyy dependency dropped.'
make
가 종속성 그래프에서 루프를 발견했다는 것을 의미한다: 타겟 xxx 의 종속물 yyy, 그리고 이것의 종속물들 등등 을 추적한 후 그들중 하나가 xxx 에 다시 종속한다는 의미이다.- `Recursive variable `xxx' references itself (eventually). Stop.'
- 이것은 확장될 때 자기자신(xxx)을 참조할 일반 (재귀적인)
make
변수 xxx 를 정의했다는 것을 의미한다. 이것은 허용되지 않는다; 단순-확장 변수 (:=
) 를 사용하든지 아니면 추가 연산자 (+=
) 를 사용하자. - `Unterminated variable reference. Stop.'
- 이것은, 변수나 함수 참조에서 적절하게 닫는 괄호나 중괄호를 제공하는 것을 잊었다는 것을 의미한다.
- `insufficient arguments to function `xxx'. Stop.'
- 이것은 이 함수에 대해서 필요한 개수의 매개변수들을 제공하지 않았다는 것을 의미한다. 매개변수들의 설명에 대해서는 그 함수의 문서를 보자.
- `missing target pattern. Stop.'
- `multiple target patterns. Stop.'
- `target pattern contains no `%'. Stop.'
- 이들은 잘못된 정적 패턴 규칙들에 대해서 생성된다. 첫번째는 규칙의 타겟 섹션에 어떤 패턴도 없다는 것을 의미하고, 두번째는 타겟 섹션에 다수의 패턴들이 있다는 것을 의미하며, 세번째는 타겟이 패턴 문자 (
%
) 를 담고 있지 않다는 것을 의미한다.
Makefile:17: *** missing separator. Stop.
Makefile
을 작성할 때 명령어(command)부분은 모두 TAB 문자로 시작해야 한다고 첫 번째 장부터 강조하였다. 위의 에러는 TAB 문자를 쓰지 않았기 때문에 make가 명령어인지 아닌지를 구별 못하는 경우이다.
대처: 17번째 줄(근처)에서 명령어가 TAB 문자로 시작하게 바꾼다.
make: *** No rule to make target `io.h', needed by `read.o'. Stop.
위의 에러는 의존 관계에서 문제가 발생했기 때문이다. 즉 read.c가 io.h에 의존한다고 정의되어 있는데, io.h를 찾을 수 없다는 에러이다.
대처: 의존 관계에서 정의된 io.h가 실제로 존재하는지 조사해 본다. 없다면 그 이유를 한번 생각해 본다. make dep를 다시 실행시켜서 의존 관계를 다시 생성시켜 주는 것도 하나의 방법이다.
Makefile:10: *** commands commence before first target. Stop.
위 의 에러는 '첫 번째 타겟이 나오기 전에 명령어가 시작되었다'는 애매한 에러 메시지이다. 필자가 경험한 이 에러의 원인은 주로 긴 문장을 여러 라인에 표시를 하기 위해서 '\'를 사용할 때, 이를 잘못 사용했기 때문인 것 같다. 즉 '\'부분은 라인의 가장 끝문자가 되어야 하는데 실수로 '\'뒤에 스페이스를 몇 개 집어넣으면 여지없이 위의 에러가 발생한다.
대처: 10번째 줄(근처)에서 '\'문자가 있거든 이 문자가 라인의 가장 끝문자가 되도록 한다. 즉 '\'문자 다음에 나오는 글자(스페이스가 대부분) 는 모조리 없애 버린다.
make를 수행시키면 의도했던 실행 파일은 안생기고 이상한 행동만 한다. 가령 make clean 했을 때와 같은 행동을 보인다.
make는 천재가 아니라는 점을 생각해야 한다. make는 Makefile
의 내용을 읽다가 첫 번째 타겟으로 보이는 것을 자신이 생성시켜야 할 결과 파일이라고 생각한다. 따라서 clean 부분을 Makefile
의 첫번째 타겟으로 정해 버리면 위와 같은 결과가 나타나게 된다.
대처: 예제 7.1에서 all 이라는 필요 없는 타겟을 하나 만들어 두었다. 이것은 make가 all 을 첫 번째 타겟으로 인식시키기 위함이었다. 따라서 자신이 생성시키고 싶은 결과 파일을 첫 번째 타겟이 되게 하던지, 아니면 예제 7.1처럼 all과 같은 더미 타겟(dummy target)을 하나 만들어 둔다. 그리고 make clean, make dep 같은 부분은 Makefile
의 끝부분에 만들어 두는 것이 안전하다.
이미 컴파일했던 파일을 고치지 않았는데도 다시 컴파일한다.
이 행동은 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에게 의존 관계를 알려주는 방법이죠)
- 그 외의 경우에 대해서는 각자가 한번 원인과 결과를 알아보기 바란다. 그리고 팁의 형식으로 글을 올린다면 다른 사람에게도 많은 도움이 될 것이다. 일단 make에서 에러를 내기 시작하면 초보자는 원인조차 모르는 경우가 많기 때문이다.
강좌를 마치면서
이번 make 강좌는 make 유틸리티에 대한 전반적인 이해와 간단한 Makefile
작성을 목적으로 하였습니다. make에 관한 모든 것을 다 소개하지는 않았습니다. (개인적인 능력의 한계 !!) make를 아주 잘 쓰기 위해서는 make 자체에 대한 지식보다는 유닉스(리눅스)의 샐 프로그램과 고난이도(?)의 명령어까지 알고 있어야 하기 때문이죠. 해커가 되려면 이런 지식을 많이 알고 있어야 합니다. 한가지 아쉬운 게 imake에 대해서 설명을 못한 것입니다. imake에 대해서는 make 중급코스란 이름으로 언젠가 강좌를 해보도록 하죠. imake는 Makefile
을 생성시켜 준다고 생각하세요)
지 금 make 다음의 강좌로 뭘해야 할지 고민 중입니다. 우선 X 강좌를 하시는 분(아직은 조용하네요)의 강좌의 이해를 높이기 위해서 X의 개념을 2회 정도의 강좌로 할 생각입니다. X 가 왜 X 이고 어떤 특징을 가지고 있는지 한번 살펴보기로 하죠.
출처: http://www.4ellene.net/tt/1030
'프로그래밍' 카테고리의 다른 글
다양한 형식의 printf문 정렬 방법 (0) | 2012.09.02 |
---|---|
이클립스 에러 Conversion to Dalvik format failed: Unable to execute dex: null, unable to execute dex java heap space (0) | 2011.11.11 |
cross platform static library merge (0) | 2011.08.23 |
내부적으로 정의된 매크로 리스트 [출처] 내부적으로 정의된 매크로 리스트|작성자 딱총구리 (0) | 2011.08.09 |
linux thread 생성 개수? (0) | 2011.08.08 |