2015-07-21 66 views
1

我想要在子目錄中創建目標文件,而不是在Makefile所在的位置創建目標文件。所以,我看到這個answer,我不能適用於我的情況,所以我想這:Makefile沒有找到目標文件

OBJS = main.o IO.o alloc.o communication.o 
OBJSDIR = obj 
SOURCE = main.cpp src/IO.cpp src/alloc.cpp src/communication.cpp 
HEADER = headers/IO.h headers/alloc.h headers/communication.h 
OUT  =  test 
CXX  = ../../mpich-install/bin/mpic++ 
CXXFLAGS = -I../../intel/mkl/include -Wl,--start-group -Wl,--end-group -lpthread -lm -ldl -Wall 
LDFLAGS =  ../../intel/mkl/lib/intel64/libmkl_scalapack_lp64.a  -Wl,--start-group  ../../intel/mkl/lib/intel64/libmkl_intel_lp64.a ../../intel/mkl/lib/intel64/libmkl_core.a ../../intel/mkl/lib/intel64/libmkl_sequential.a -Wl,--end-group ../../intel/mkl/lib/intel64/libmkl_blacs_intelmpi_lp64.a -lpthread  -lm  -ldl 

all: $(OBJSDIR) $(OUT) 

$(OBJSDIR): 
    mkdir $(OBJSDIR) 

$(OUT): $(OBJS) 
    $(CXX) $(OBJS) -o $(OUT) $(CXXFLAGS) $(LDFLAGS) 
# make -f Makefile clean 

# create/compile the individual files >>separately<< 
$(OBJSDIR)/main.o: main.cpp 
    $(CXX) -c main.cpp $(CXXFLAGS) 

$(OBJSDIR)/IO.o: src/IO.cpp 
    $(CXX) -c src/IO.cpp $(CXXFLAGS) 

$(OBJSDIR)/alloc.o: src/alloc.cpp 
    $(CXX) -c src/alloc.cpp $(CXXFLAGS) 

$(OBJSDIR)/communication.o: src/communication.cpp 
    $(CXX) -c src/communication.cpp $(CXXFLAGS) 

.PHONY: clean 
clean: 
    rm -rf *.o 

和我得到:

[email protected]:~/konstantis/cholesky$ make 
../../mpich-install/bin/mpic++ -I../../intel/mkl/include  -Wl,--start-group  -Wl,--end-group  -lpthread  -lm  -ldl -Wall -c -o main.o main.cpp 
make: *** No rule to make target 'IO.o', needed by 'test'. Stop. 

我有一個src文件夾,所有的.cpp文件(除main.cpp外,與Makefile位於同一目錄中)和一個頭文件目錄(所有頭文件都存在)。


編輯

我修改了前兩行,因爲這樣的:

OBJSDIR = obj 
OBJS = $(OBJSDIR)/main.o $(OBJSDIR)/IO.o $(OBJSDIR)/alloc.o $(OBJSDIR)/communication.o 

和我得到:

g++: error: obj/main.o: No such file or directory 
... 

問題在於到一個事實,即對象文件仍然在主目錄中生成!

+0

你已經教過如何構建'$(OBJSDIR)/ IO.o'而不是'IO.o'。所以你的先決條件需要列出'$(OBJSDIR)/ IO.o'而不是'IO.o'。您的'.o'文件的規則也不會生成正確的輸出文件。他們將生成'src/*。o'文件來匹配他們的輸入文件。 (這是你提到的'-o'標誌是爲了。) –

+0

嗯,檢查我的編輯@EtanReisner。好的,我看到你的編輯,但我仍然無法弄清楚。 :/ – gsamaras

回答

1

你想改變,從調用編譯器的線路:

$(OBJSDIR)/IO.o: src/IO.cpp 
    $(CXX) -c src/IO.cpp $(CXXFLAGS) 

到:

$(OBJSDIR)/IO.o: src/IO.cpp 
    $(CXX) -c src/IO.cpp $(CXXFLAGS) -o [email protected] 

注意[email protected]是對應於正在創建的目標文件的automatic variable。所以在上述情況下,它將是obj/IO.o-o指定輸出文件名。

而且同時它無關你的問題的有關放置所有生成工件到一個單獨的目錄清潔漂亮的事情之一是要容易得多:

clean: 
    rm -rf $(OBJSDIR) $(OUT) 

此外,作爲最後要注意,如果你曾經希望做一個並行構建你會遇到一個問題,因爲你的目標文件依賴於構建目錄。有幾個解決方案可以在每次調用編譯器之前調用mkdir -p objs或將目錄設置爲dependency that is only built if it does not exist

相關問題