Ошибка Makefile "Файл существует", когда make -j2 - PullRequest
1 голос
/ 16 марта 2012

Всякий раз, когда я использую просто "make" для компиляции, мой 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 $@ $(LDFLAGS)

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

debug: $(TARGETD)

$(TARGETD): $(OBJECTS)
    $(CC) -w -D LINUX $(INCLUDE) $^ -o $@ $(LDFLAGS)

%.o: $(SRCDIR)/%.cpp
    $(CC) -c -g $< $(CFLAGS)-o $@



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

Может кто-нибудь сказать мне, почему оба процессора используются с -j2 заставляет эту ошибку появляться и как ее исправить?Спасибо за любую помощь.

Ответы [ 2 ]

3 голосов
/ 16 марта 2012

Не создавайте такие каталоги; это состояние гонки, которое должно произойти. Позвольте Make обработать разрешение для вас:

 $(OBJECTS): | $(OBJDIR)

 $(OBJDIR):
         mkdir $(OBJDIR)

Это взято непосредственно из примера предпосылки только для заказа в руководстве по изготовлению.

0 голосов
/ 16 марта 2012

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

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

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

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

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

...