我尝试过多次尝试将.o
文件移动到我的obj
文件夹,但无论我做什么,它都无法正常工作。
从提供的makefile判断,将.o
文件移动到指定文件夹的最佳方法是什么?
BIN = bin/
OBJ = obj/
TARGET = opengl_03
DEPS = main.o displayinit.o initializer.o algorithms.o matrix3f.o window.o vertex3.o
CC = g++
CFLAGS = -g
LIBS = -lglut -lGLEW -lGL
INCLUDEPATH = -L/usr/include/ -L/usr/lib/ -L/usr/lib/x86_64-linux-gnu/
$(TARGET) : $(DEPS)
$(CC) $(CFLAGS) -o $(BIN)$(TARGET) $(DEPS) $(LIBS) $(INCLUDEPATH)
displayinit.o : displayinit.cpp displayinit.h
$(CC) $(LIBS) $(INCLUDEPATH) -c displayinit.cpp && mv displayinit.o $(OBJ)displayinit.o
initializer.o : initializer.cpp initializer.h
$(CC) $(LIBS) $(INCLUDEPATH) -c initializer.cpp $(OBJ)
algorithms.o : algorithms.cpp algorithms.h
$(CC) -c algorithms.cpp $(OBJ)
matrix3f.o : matrix3f.cpp matrix3f.h
$(CC) $(LIBS) $(INCLUDEPATH) -c matrix3f.cpp $(OBJ)
vertex3.o : vertex3.cpp vertex3.h
$(CC) $(LIBS) $(INCLUDEPATH) -c vertex3.cpp $(OBJ)
window.o : window.cpp window.h
$(CC) $(LIBS) $(INCLUDEPATH) -c window.cpp $(OBJ)
main.o : main.cpp
$(CC) $(LIBS) $(INCLUDEPATH) -c main.cpp $(OBJ)
答案 0 :(得分:18)
要指定对象的创建位置,请使用-o
window.o : window.cpp window.h
$(CC) $(LIBS) $(INCLUDEPATH) -c window.cpp -o $(OBJ)/$@
以下是您可以做的事情:
指定目标文件的目录
OBJDIR = objdir
通过将.cpp
替换为.cpp
并添加前缀{{1},从所有.o
文件列表中创建需要编译的目标文件列表对它:
$(OBJDIR)/
所以你的$(OBJ)看起来像是:OBJ = $(addprefix $(OBJDIR)/, $(patsubst %.cpp, %.o, $(wildcard *.cpp)))
等等
添加目标以创建目录(如果该目录不存在):
objdir/window.o objdir/main.o
在制作主要目标之前制作目录:
$(OBJDIR):
mkdir $(OBJDIR)
从当前目录中的all: $(OBJDIR) myapp
文件中编译.o
中所有$(OBJDIR)
个目标文件的规则:
.cpp
这将导致类似:
$(OBJDIR)/%.o: %.cpp
$(GCC) $(CPPFLAGS) -c $< -o $@
您的主要目标不变:
g++ -c main.cpp -o objdir/main.o
这看起来像是:
$(TARGET): $(OBJ)
$(GCC) $(LDFLAGS) -o $@ $^
为了完整性,将g++ -o myapp objdir/window.o objdir/main.o
目标添加到清理对象中:
clean
定义clean:
@rm -f $(TARGET) $(wildcard *.o)
@rm -rf $(OBJDIR)
个目标,例如即使存在具有相同名称的目录或文件,也会进行这些操作:
.PHONY
所以看起来应该是这样的:
.PHONY: all clean
如果你有OBJDIR = objdir
OBJ = $(addprefix $(OBJDIR)/, $(patsubst %.cpp, %.o, $(wildcard *.cpp)))
TARGET = my app
.PHONY: all clean
all: $(OBJDIR) $(TARGET)
$(OBJDIR):
mkdir $(OBJDIR)
$(OBJDIR)/%.o: %.cpp
$(GCC) $(CPPFLAGS) -c $< -o $@
$(TARGET): $(OBJ)
$(GCC) $(LDFLAGS) -o $@ $^
clean:
@rm -f $(TARGET) $(wildcard *.o)
@rm -rf $(OBJDIR)
和main.cpp
这样的文件,这就是a.cpp
会做的事情:
make
如果您想了解有关上述任何内容的更多详细信息,请查看GNU make doc page
答案 1 :(得分:4)
在回应评论时,还有一些提示:
这部分非常重复:
displayinit.o : displayinit.cpp displayinit.h
$(CC) $(LIBS) $(INCLUDEPATH) -c displayinit.cpp && mv displayinit.o $(OBJ)displayinit.o
initializer.o : initializer.cpp initializer.h
$(CC) $(LIBS) $(INCLUDEPATH) -c initializer.cpp $(OBJ)
algorithms.o : algorithms.cpp algorithms.h
$(CC) -c algorithms.cpp $(OBJ)
# ...
您可以将其替换为两部分:
1)更通用的规则,如:
%.o: %.cpp
$(CC) -c $(LIBS) $(INCLUDEPATH) $< -o $@
$<
和$@
是自动变量,$@
扩展为当前构建目标的名称,$<
是第一个依赖项({ {1}}将是“所有依赖项”,还有更多此类变量 - 请参阅Make manual)。
2)任何额外的deps(即标题):
$^
注意:对于每个displayinit.o: displayinit.h
matrix3f.o: matrix3f.h
main.o: main.h window.h displayinit.h
#etc
文件,其依赖项应包含:
.o
(依赖性来自一般规则),.cpp
个文件中包含的所有.h
个文件(稍后需要添加)。请注意,您在原始makefile中省略了后一部分。这有一天会给你带来一些问题。
基本上每次在任何文件中添加.cpp
时,都需要修改makefile以反映#include
/ .cpp
和{{1}之间的新依赖关系}文件。这非常麻烦,但幸运的是有自动解决方案。这里有两种C / C ++方法:
.o
/ .h
)。gcc
。无论哪种方式,您都需要在makefile中动态包含这组依赖项。这需要一些技巧,但一旦你拥有它,你永远不必担心依赖。有一个google的“C ++ makefile依赖”,应该有足够的资源。
Here's关于Make的最新文档。
答案 2 :(得分:0)
以下为我工作:
g++ test.cpp -c -o obj/test.o
因此,在您的情况下,您将进行以下修改:
displayinit.o : displayinit.cpp displayinit.h
$(CC) $(LIBS) $(INCLUDEPATH) -c displayinit.cpp -o displayinit.o $(OBJ)displayinit.o
此外,对于最终编译,您需要从obj文件夹中选取.o文件,因此请将DEPS
修改为bin/<xyz>.o
。或者,您可以在最终构建之前cd obj
:
$(TARGET) : $(DEPS)
cd $(OBJ)
$(CC) $(CFLAGS) -o ../$(BIN)$(TARGET) $(DEPS) $(LIBS) $(INCLUDEPATH)
答案 3 :(得分:0)
在第一个目标中,添加命令以将文件移动到所需的目录。
$(TARGET) : $(DEPS)
$(CC) $(CFLAGS) -o $(BIN)$(TARGET) $(DEPS) $(LIBS) $(INCLUDEPATH)
mv *.o obj/