我希望在子目录中创建我的目标文件,而不是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
...
问题在于目标文件仍然在主目录中生成!
答案 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。