c++ - 特定于目录结构的 Makefile
问题描述
我正在尝试使用 makefile 编译我的项目。我是makefile的新手,所以请原谅我的无知。我遇到的问题是我希望输出命令构建所有 .o 文件,但是如果我这样运行它,它将不会构建 .o 文件,而是会尝试编译所有 .o 文件/obj 目录。
我将如何编译输出规则中的所有 .o 文件规则?
The directory structure for this project is:
recipe_book
|-GFX (source directory)
|-PageManager (source directory)
|-Pages (source directory)
|-main (source directory)
|-obj (.o files directory)
|-out (application output)
这是我的Makefile:
#COMPILER_FLAGS specifies the additional compilation options we're using
# -w suppresses all warnings
COMPILER_FLAGS = -w -g
#LINKER_FLAGS specifies the libraries we're linking against
LINKER_FLAGS = -lSDL2 -lSDL2_image
G++ = g++ -std=c++17 $(LINKER_FLAGS) $(COMPILER_FLAGS)
#Source Directories:
GFX := GFX
PAGE_MANAGER := PageManager
PAGES := Pages
#Object Directory:
OBJ := obj
# Complile the objects into the executable
output: main/main.cpp main/main.hpp $(OBJ)/*.o
$(G++) main/main.cpp $(OBJ)/*.o -o out/recipe_book.out
#make all object files
#'.' turns them into macros?
#GFX
$(OBJ)/%.o: $(GFX)/%.cpp $(GFX)/%.hpp
$(G++) -I$(GFX) -c $< -o $@
#PageManager
$(OBJ)/%.o: $(PAGE_MANAGER)/%.cpp $(PAGE_MANAGER)/%.hpp
$(G++) -I$(PAGE_MANAGER) -c $< -o $@
#Pages
$(OBJ)/%.o: $(PAGES)/%.cpp $(PAGES)/%.hpp
$(G++) -I$(PAGES) -c $< -o $@
clean:
rm out/*.out obj/*.o
解决方案
这一行:
output: main/main.cpp main/main.hpp $(OBJ)/*.o
无法按书面方式正常工作。这是做什么的?它告诉 make,目标output
(顺便说一句,您从未真正创建过:此规则创建一个完全不同的文件out/recipe_book.out
,但暂时将其放在一边)取决于文件main/main.cpp
,main/main.hpp
和 glob 表达式的扩展obj/*.o
。因此,make 查找与 glob 表达式匹配的文件,即所有已存在obj/*.o
的目标文件。
如果所有目标文件都已经存在,那么它们都将被链接。如果您还没有创建任何目标文件,那么它们都不会被找到(就像您运行ls obj/*.o
没有找到文件一样),因此它们都不会被链接。
您必须在此处列出要链接的明确目标文件集。您不能使用 glob 表达式来查找它们。
您可以使用 glob 表达式查找始终(可能)存在的源文件,然后将它们转换为目标文件。也许是这样的:
SOURCES := $(wildcard $(GFX)/*.cpp $(PAGE_MANAGER)/*.cpp $(PAGES)/*.cpp)
OBJECTS := $(addprefix $(OBJ)/,$(patsubst %.cpp,%.o,$(notdir $(SOURCES))))
output: main/main.cpp main/main.hpp $(OBJECTS)
(顺便说一句,你真的应该使用这个目标的真实文件名而不是output
:在make中,所有非假目标应该总是有他们创建的实际文件的名称)。
推荐阅读
- java - 如何将缓冲写入器加入我的随机猜谜游戏?
- numpy - NumPy - 如何广播不同形状的数组
- puppet - Puppet:从失败的运行中恢复
- android - 关于辞职 apk 的建议
- javascript - 保持侧边栏面板在重定向时展开
- spring - Cloud Foundry (PCF) 中的 Spring Boot 禁用 Whitelabel 错误页面
- c# - 合并 linq 语句或离开
- tensorflow - 具有恒定大小批次的 tf.data.Dataset
- python-3.x - 文件上传烧瓶的单元测试用例
- javascript - 在 ReactJS 中进行 ajax 调用的设计原则(在哪里放置 ajax 调用)