2012-03-15 2 views
1

Всякий раз, когда я использую только «make» для компиляции, мой Makefile отлично работает. Но когда я использую «сделать -j2», я получаю ошибку, чтоОшибка Makefile «Файл существует», когда make -j2

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

Это Makefile -

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 делает эту ошибку появляется и как его исправить? Спасибо за любую помощь.

ответ

3

Не создавайте такие каталоги; это состояние гонки, ожидающее случиться. Пусть Сделать обрабатывать разрешения зависимостей для вас:

$(OBJECTS): | $(OBJDIR) 

$(OBJDIR): 
     mkdir $(OBJDIR) 

Это взято непосредственно из order-only prerequisite example в руководстве Make.

+0

Это действительно работает, но каждый раз, когда я скомпилирую файл, я получаю «объекты mkdir mkdir: невозможно создать каталог' objects ': File exists ». Как мне обойти это? – Sterling

+0

@Sterling: Вы не должны получать это сообщение. Можете ли вы создать минимальный тестовый сценарий? (т. е. гораздо более простой make-файл). –

+0

О, это потому, что у меня был mkdir в двух целях. Спасибо за вашу помощь! – Sterling

0

Использование mkdir -p. Это идемпотент (без проблем, если выполняется дважды с тем же аргументом или даже параллельно). И делает все каталоги, если вы указываете имя пути с несколькими компонентами.

Посмотрите на мой Makefile здесь: http://www.kylheku.com/cgit/txr/tree/Makefile

Несколько экземпляров mkdir -p. Конечно, я вижу несколько заданий mkdir -p, когда я запускаю make -j, но это не проблема.

Другая идея - добавить - в команду mkdir. (Как и то, что используется с rm в clean целевых правилах). Но это игнорирует подлинную ошибку, а не только EEXIST.

P.S. логика вроде if directory does not exist, then mkdir ... не будет работать, потому что у нее есть состояние гонки. Каталог может не существовать в момент оценки if, но затем к моменту оценки mkdir он внезапно существует. Параллельно, вы должны беспокоиться о гонках, потому что писать правила для параллельного make - это форма параллельного программирования.

+0

Кроме того, в прошлом в Makefiles я сделал это, рассматривая каталог как явную зависимость с правилом для его создания. Это будет правильно распараллеливаться: 'make' будет создавать каталог, а затем отправлять параллельные правила, зависящие от него. – Kaz

Смежные вопросы