Makefile找不到对象文件

时间:2015-07-21 22:55:05

标签: c++ makefile directory object-files

我希望在子目录中创建我的目标文件,而不是Makefile所在的位置。所以,我看到了这个answer,我无法适用于我的案例,所以我尝试了这个:

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

我得到了:

gsamaras@pythagoras:~/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位于同一目录中)和一个headers目录,其中所有头文件都存在。

修改

我修改了前两行,如下:

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
...

问题在于目标文件仍然在主目录中生成!

1 个答案:

答案 0 :(得分: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 $@

请注意,$@是与要创建的目标文件对应的automatic variable。因此,在上述情况下,它将是obj/IO.o-o指定输出文件名。

此外,虽然它与您的问题无关,但是将所有构建工件放入单独的目录中的一个好处是清理更容易:

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

另外,作为最后一点,如果您希望进行并行构建,则会遇到问题,因为您的目标文件依赖于构建目录。有几种解决方案,包括在每次编译器调用之前调用mkdir -p objs或将目录设置为dependency that is only built if it does not exist