2010-03-11 4 views
4

eval documentation에서 논의하는 것처럼 Makefile에 대한 일반 빌드 템플릿을 만들려고합니다.GNU Make 3.80 평가 버그에 대한 대안

나는 GNU Make 3.80에서 알려진 버그를 경험했다. $ (eval)이 193자를 넘는 행을 평가할 때 Make는 "Virtual Memory Exhausted"오류와 충돌합니다.

문제의 원인이되는 코드는 다음과 같습니다.

SRC_DIR = ./src/ 

PROG_NAME = test 

define PROGRAM_template 
    $(1)_SRC_DIR = $$(SRC_DIR)$(1)/ 
    $(1)_SRC_FILES = $$(wildcard $$($(1)_SRC_DIR)*.c) 
    $(1)_OBJ_FILES = $$($(1)_SRC_FILES):.c=.o) 

    $$($(1)_OBJ_FILES) : $$($(1)_SRC_FILES) # This is the problem line 
endef 

$(eval $(call PROGRAM_template,$(PROG_NAME))) 

나는이 Makefile을 실행하면, 내가 얻을

gmake: *** virtual memory exhausted. Stop. 

예상 출력은 ./src/test/의 모든 .c 인 파일 (묵시적 규칙을 통해) .o 인 파일로 컴파일받을 것입니다 .

문제는 $$ ($ (1) _SRC_FILES)와 $$ ($ (1) _OBJ_FILES)가 193자를 넘는 것입니다 (충분한 원본 파일이있는 경우).

2 개의 .c 파일 만있는 디렉토리에서 make 파일을 실행 해 보았지만 제대로 작동합니다. SRC 디렉토리에 .c 파일이 여러 개있는 경우에만 오류가 발생합니다.

GNU Make 3.81이이 버그를 수정한다는 것을 알고 있습니다. 불행히도 필자는 현재 작업중인 시스템에 최신 버전을 설치할 수있는 권한이나 능력이 없습니다. 나는 3.80과 붙어있다.

그럼 해결 방법이 있습니까? 어쩌면 $$ ($ (1) _SRC_FILES)을 나눠서 각 종속성을 개별적으로 평가할 것입니까?

+0

나는이 문제를 3.81 버전에서도 경험했다. (우분투 10.10) – lurscher

+0

당신이 어떻게했는지에 대한 해결 방법이있다면. – searchengine27

+0

또한 참조 할 수 있도록 버그 보고서 또는 ID가 있습니까? – searchengine27

답변

5

롤은 아마도 그것은 단지 로컬 경우에도 3.81을 설치에서 당신을 방지 거기에 아무것도 할 수 없다,

ifneq (3.81,$(shell (echo $(MAKE_VERSION); echo 3.81) | sort | head -n1)) 

make-3.81/make: 
     wget -nc http://ftp.gnu.org/pub/gnu/make/make-3.81.tar.gz 
     gzip -cd make-3.81.tar.gz | tar xvf - 
     cd make-3.81 && ./configure --prefix=$$(pwd) 
     $(MAKE) -C make-3.81 make 

%: make-3.81/make 
     make-3.81/make [email protected] 

else 

# rest of your makefile 

endif 

진지하게 해킹.

+1

사실, 컴퓨터가 인터넷에 연결되어 있지 않아 해킹이 제대로 작동하지 않습니다. 또한 컴퓨터에 소프트웨어를 설치하는 것은 회사 정책에 위배됩니다. 로컬에서도. 나는 그것이 의미가 있다는 것을 말하지 않고있다, 나는 단지 그것의 규칙을 말하고있다. 나는 정말로 3.81을 설치할 수 없다. – bengineerd

+0

@bengineerd, ok,하지만 바보 같은 정책이 정답을 downvote하는 가장 좋은 이유는 무엇입니까? –

+1

소스 트리에 새 버전을 포함하십시오. –

3

아마 아무도 더 이상 필요가 없지만 include의 영리한 사용은 이러한 종류의 한계를 극복 할 수 있다고 생각합니다. 템플릿 매크로의 핵심 구현하는 PROGRAM_template.mk 만들기

define PROGRAM_template 
__template_arg := $(1) 
include PROGRAM_template.mk 
endef 

:

같은 뭔가 define PROGRAM_template 교체 물론

$(__template_arg)_SRC_DIR = $(SRC_DIR)$(__template_arg)/ 
$(__template_arg)_SRC_FILES = $(wildcard $($(__template_arg)_SRC_DIR)*.c) 
$(__template_arg)_OBJ_FILES = $($(__template_arg)_SRC_FILES:.c=.o) 

$($(__template_arg)_OBJ_FILES) : $($(__template_arg)_SRC_FILES) 
__template_arg := 

을,이 전역 변수의 비트 추한 (사용 전달하는 것입니다 매크로가 무엇인지에 대한 논의). 나는 첫 번째 대답을 더 좋아한다. :-)