2012-03-15 8 views
1

"make"だけでコンパイルすると、Makefileが正常に動作します。Makefile Error make -j2のときに "File exists"

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とプロセッサの両方を使用すると、このエラーになり、なぜ誰も私を伝えることができ - 私は「-j2作る」を使用する場合でも、私は

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

これはMakefileをするエラーが発生します表示され、それを修正する方法?何か助けてくれてありがとう。

答えて

3

このようなディレクトリは作成しないでください。それは起こるのを待っている競争条件です。あなたのための依存関係の解決を処理つくろう:これはメイクマニュアルにorder-only prerequisite exampleから直接取得され

$(OBJECTS): | $(OBJDIR) 

$(OBJDIR): 
     mkdir $(OBJDIR) 

+0

これはうまくいきますが、ファイルをコンパイルするたびに「mkdirオブジェクト」が得られます mkdir:ディレクトリ 'オブジェクト'を作成できません:ファイルが存在します。これをどうやって回避するのですか? – Sterling

+0

@スターリング:あなたはそのメッセージを受け取るべきではありません。最小のテストケースを作成できますか? (より簡単なメイクファイル)。 –

+0

ああ、私は2つのターゲットでmkdirを持っていたからです。ご協力いただきありがとうございます! – Sterling

0

mkdir -pを使用してください。それは等冪である(同じ引数で2回実行された場合、または並行して実行されても何の問題もない)。 複数のコンポーネントでパス名を指定すると、すべてのディレクトリが作成されます。ここに私のMakefileで

ルック:mkdir -phttp://www.kylheku.com/cgit/txr/tree/Makefile

複数のインスタンス。もちろん、私はmake -jを実行すると複数のmkdir -pジョブが発行されているのが見えますが、それは問題ではありません。

別の考え方は、-をmkdirコマンドに追加することです。 (rmcleanのターゲットルールで使用されているものとまったく同じです)。しかし、それは真のエラーを無視するだけでなく、EEXIST

P.S. if directory does not exist, then mkdir ...のようなロジックは、競合状態があるため動作しません。 ifが評価された時点でディレクトリが存在しない可能性がありますが、mkdirが評価されるまでに突然存在します。並列makeでは、並列makeのルールを記述することが並行プログラミングの一種であるため、レースについて心配する必要があります。

+0

また、Makefilesではこれまで、ディレクトリを明示的な依存関係として扱い、ルールを作成しました。これは正しく並列化されます: 'make'はディレクトリを構築し、次にそれに依存する並列ルールをディスパッチします。 – Kaz

関連する問題