2012-03-15 2 views
1

"make"를 사용하여 컴파일 할 때마다 Makefile이 정상적으로 작동합니다. -j2와 프로세서를 모두 사용하는 이유메이크 파일 오류 "파일 존재"make -j2

INCLUDE = -I/usr/include/X11 -I/usr/local/include -I/usr/local/include/FL/images -I/usr/include/freetype2 

CC=g++ 
CFLAGS=-w -D LINUX -O3 -fpermissive 
OBJDIR=objects 
SRCDIR=src 

LDFLAGS= -L/usr/X11R6/lib$(LIBSELECT) -lpthread -lfltk -lXext -lXft -lfontconfig -lXinerama -lpthread -ldl -lm -lX11 

SOURCES_RAW= robot_driver_agent.cpp robot_driver_position.cpp robot_driver_priorityqueue.cpp main.cpp robot_driver_tree.cpp robot_driver_stack.cpp robot_driver_grid.cpp robot_driver_path.cpp grid_analyzer.cpp tcpserver.cpp tcpclient.cpp servercontrol.cpp clientcontrol.cpp robot.cpp udpserver.cpp udpclient.cpp owncontrol.cpp guiwindow.cpp rs232.cpp 

TARGET:= go 
TARGETD:= go_d 

OBJECTS:=$(SOURCES_RAW:.cpp=.o) 
OBJECTS:=$(patsubst %.o, $(OBJDIR)/%.o, $(OBJECTS)) 

SOURCES:=$(SOURCES_RAW) 
SOURCES:=$(patsubst %.cpp, $(SRCDIR)/%.cpp, $(SOURCES)) 

all: $(TARGET) 

$(TARGET): $(OBJECTS) 
    $(CC) -w -D LINUX $(INCLUDE) $^ -o [email protected] $(LDFLAGS) 

$(OBJDIR)/%.o: src/%.cpp 
    test -d $(OBJDIR) || mkdir $(OBJDIR) 
    $(CC) -g -c $< $(CFLAGS) -o [email protected] 

debug: $(TARGETD) 

$(TARGETD): $(OBJECTS) 
    $(CC) -w -D LINUX $(INCLUDE) $^ -o [email protected] $(LDFLAGS) 

%.o: $(SRCDIR)/%.cpp 
    $(CC) -c -g $< $(CFLAGS)-o [email protected] 



.PHONY : clean 
clean: 
    rm -f $(OBJDIR)/*.o 
    rm -f $(TARGET) $(TARGETD) 

사람이 말해 줄 수이 오류를 만든다 - 나는 "-j2하게"사용할 때, 나는

mkdir: cannot create directory `objects': File exists 
make: *** [objects/robot_driver_agent.o] Error 1 

이것은 메이크라는 오류가 나타나고 그것을 고치는 방법? 어떤 도움을 주셔서 감사합니다.

답변

3

그런 디렉토리를 만들지 마십시오. 그것은 일어나기를 기다리고있는 경쟁 조건입니다. 당신을 위해 의존성 확인을 처리 만들자 : 이것은 만들기 설명서의 order-only prerequisite example에서 직접 촬영

$(OBJECTS): | $(OBJDIR) 

$(OBJDIR): 
     mkdir $(OBJDIR) 

.

+0

이것은 작동하지만, 파일을 컴파일 할 때마다 "mkdir objects"가 나타납니다. mkdir :'objects '디렉토리를 만들 수 없습니다 : 파일이 있습니다. " 이 문제를 어떻게 해결할 수 있습니까? – Sterling

+0

@ 스털링 : 당신은 그 메시지를 받아서는 안됩니다. 최소한의 테스트 케이스를 만들 수 있습니까? (즉 훨씬 간단한 메이크 파일). –

+0

오, 왜냐하면 나는 두 개의 표적에서 mkdir을 가졌기 때문입니다. 당신의 도움을 주셔서 감사합니다! – Sterling

0

mkdir -p을 사용하십시오. 멱등수입니다 (동일한 인수로 두 번 실행하거나 병렬로 실행해도 문제가 없습니다). 여러 구성 요소가있는 경로 이름을 지정하면 모든 디렉토리가 만들어집니다. mkdir -phttp://www.kylheku.com/cgit/txr/tree/Makefile

여러 인스턴스 : 여기 내 메이크에서

봐. 물론 make -j를 실행할 때 복수 mkdir -p 작업이 실행되는 것을 볼 수는 있지만 문제는 아닙니다.

또 다른 아이디어는 -을 mkdir 명령에 추가하는 것입니다. (rmclean 대상 규칙에서 사용되는 것과 같습니다. 그러나 이것은 EEXIST뿐만 아니라 진정한 오류를 무시합니다.

P. if directory does not exist, then mkdir ...과 같은 논리는 경쟁 조건이 있기 때문에 작동하지 않습니다. if이 평가 될 때 디렉토리가 존재하지 않을 수 있지만 mkdir이 평가 될 때 갑자기 존재합니다. 병렬 작성에서는 병렬 작성 규칙이 동시 프로그래밍의 한 형태이기 때문에 경주에 대해 걱정해야합니다.

+0

또한, Makefiles 과거에는 디렉토리를 명시 적 종속성으로 처리하여이를 작성했습니다. 이것은 올바르게 병렬화됩니다 :'make'는 디렉토리를 생성 한 다음 그것에 의존하는 병렬 규칙을 디스패치합니다. – Kaz