make -j2时Makefile错误“文件存在”

时间:2012-03-15 22:58:04

标签: compiler-errors makefile

每当我使用“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 个答案:

答案 0 :(得分:3)

不要创建那样的目录;这是一场等待发生的竞争条件。让Make为您处理依赖项解析:

 $(OBJECTS): | $(OBJDIR)

 $(OBJDIR):
         mkdir $(OBJDIR)

这可以直接从Make手册中的order-only prerequisite example获取。

答案 1 :(得分:0)

使用mkdir -p。它是幂等的(如果使用相同的参数执行两次,甚至并行执行,则没有问题)。 如果您提供包含多个组件的路径名,它会生成所有目录。

在这里查看我的Makefile:http://www.kylheku.com/cgit/txr/tree/Makefile

mkdir -p的几个实例。当然,我确实看到在运行make -j时发出了多个mkdir -p个作业,但这不是问题。

另一个想法是在mkdir命令上添加-。 (就像rm目标规则中clean使用的内容一样。但这忽略了一个真正的错误,而不仅仅是EEXIST

P.S。像if directory does not exist, then mkdir ...这样的逻辑不起作用,因为它有竞争条件。在评估if时,该目录可能不存在,但是在评估mkdir时,它突然存在。在并行make中,你必须担心竞争,因为为并行make编写规则是一种并发编程的形式。