如何解决如何重写我的 makefile 以便我可以重组我的项目目录?
我一直在开发一款完全用 C++ 编写的小游戏,使用 SDL 来处理图形和音频。到目前为止,我的所有源文件和头文件都与我的可执行文件位于同一目录中,但我想将它们移动到 ./src 和 ./include 文件夹中。
但是,我真的很纠结于 makefile 语法以及如何告诉编译器在哪里可以找到源文件和头文件。
如何告诉 makefile 在子目录中查找源/头文件/对象?我的 makefile 有什么改进/错误吗?
这是我当前的 makefile:
OBJS = main.o Window.o Entity.o Player.o Tile.o BoundingBox.o\
MapReader.o Button.o Zombie.o Projectile.o Pathfinder.o
CPP = g++
CPPFLAGS = -c -g
LDFLAGS = -lmingw32 -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer -mwindows
ZombieAttack: $(OBJS)
$(CPP) -o ZombieAttack $(OBJS) $(LDFLAGS)
main.o: main.cpp
$(CPP) $(CPPFLAGS) main.cpp
Window.o: Window.cpp
$(CPP) $(CPPFLAGS) Window.cpp
Entity.o: Entity.cpp
$(CPP) $(CPPFLAGS) Entity.cpp
Player.o: Player.cpp
$(CPP) $(CPPFLAGS) Player.cpp
Tile.o: Tile.cpp
$(CPP) $(CPPFLAGS) Tile.cpp
BoundingBox.o: BoundingBox.cpp
$(CPP) $(CPPFLAGS) BoundingBox.cpp
MapReader.o: MapReader.cpp
$(CPP) $(CPPFLAGS) MapReader.cpp
Button.o: Button.cpp
$(CPP) $(CPPFLAGS) Button.cpp
Zombie.o: Zombie.cpp
$(CPP) $(CPPFLAGS) Zombie.cpp
Projectile.o: Projectile.cpp
$(CPP) $(CPPFLAGS) Projectile.cpp
Pathfinder.o: Pathfinder.cpp
$(CPP) $(CPPFLAGS) Pathfinder.cpp
clean:
del *.o
我使用 mingw 进行编译和 mingw32-make
解决方法
如果您希望二进制文件位于最高级别目录中,而 .h / .cpp 文件位于其子目录中,您可以简单地使用目标目录/文件名作为您希望访问的文件的前缀
例如:
MapReader.o: MapReader.cpp
$(CPP) $(CPPFLAGS) MapReader.cpp
变成
MapReader.o: src/MapReader.cpp
$(CPP) $(CPPFLAGS) src/MapReader.cpp
,
一般来说,最好在发布到 SO 之前尝试自己解决问题。然后,当您遇到无法解决的问题时,您应该具体询问该问题,而不是像这样的广泛问题。
然而,马上就要过年了!!
首先,make 和编译器不是一回事。教 make 去哪里找你的文件是不够的,你还必须教编译器去哪里找你的文件。如果您要将头文件放在源文件之外的其他目录中,那么您必须为编译器提供选项,告诉它在哪里可以找到这些头文件。只是告诉 make 在哪里可以找到它们对编译器没有任何帮助。
第二,除非你真的有迫切的需要,否则你应该使用 standard variables 来表示 C++ 编译器(CXX
而不是 CPP
)和它的标志({{1} } 不是 CXXFLAGS
)。您也不应该将选择输出类型 (CPPFLAGS
) 的选项放入通用标志变量中:这应该进入规则。最后,您应该确保保持对链接器标志的 -c
和链接库的 LDFLAGS
之间的区别。在这里,您将所有要链接的库放入 LDLIBS
。
第三,您可以尽可能使用 automatic variables 来减少重复。
第四,您可以通过使用 pattern rule 极大地简化您的 makefile。事实上,GNU make 提供了可以正确构建 C++ 文件的 default pattern rules,如果您使用上述正确的变量,那么您甚至不必定义自己的变量。
这是您的原始 makefile 的一个版本,修复了上述变量并使用内置规则来减少重复:
LDFLAGS
如果所有文件都在同一个目录中,那么这个 makefile 应该像你原来的 makefile 一样执行。
现在,如果您想移动一些东西,那么您首先需要通过向编译行添加一个 OBJS = main.o Window.o Entity.o Player.o Tile.o BoundingBox.o \
MapReader.o Button.o Zombie.o Projectile.o Pathfinder.o
CXX = g++
CXXFLAGS = -g
LDFLAGS = -mwindows
LDLIBS = -lmingw32 -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer
ZombieAttack: $(OBJS)
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
clean:
del *.o
选项来向编译器解释在哪里可以找到您的头文件。如果您的标题现在位于 -I
子目录中,您可以这样做:
include
现在,如果您愿意将目标文件与源文件放在同一目录中,那么您可以更改上面的 makefile 以告诉 make 在哪里构建它们,如下所示:
CXXFLAGS = -g -Iinclude
那,连同上面的变化,应该允许它工作。
如果你想把目标文件放在其他目录而不是源文件,那么你将不能再使用 make 的内置规则,因为 make 不知道你想把东西放在哪里,所以你将有编写自己的模式规则。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。