【问题标题】:Generate object files from source files located in multiple folders从位于多个文件夹中的源文件生成目标文件
【发布时间】:2021-08-14 22:25:07
【问题描述】:

我想生成依赖于目标文件 (OBJS = $(wildcard $(BUILD_DIR)/*.o) 的可执行文件 (TARGET = $(BUILD_DIR)/MySDLProgram),这些目标文件依赖于位于 src/applicationsrc/engine 中的源文件。我应该如何进行?

我不断收到此错误:

Note that Makefile not found the object files

这是我的 Makefile:

#CC specifies which compiler we're using
CC = g++

# Directories
SRC_DIR = src
BUILD_DIR = build

TARGET = $(BUILD_DIR)/MySDLProgram

# Source files
SRC_DIRS = src/engine src/application
SRCS = $(foreach dir, $(SRC_DIRS), $(wildcard $(dir)/*.cpp))

OBJS = $(wildcard $(BUILD_DIR)/*.o)

# INCLUDE_PATHS specifies the additional include paths we'll need
INCLUDE_PATHS = -Iheader

# COMPILER_FLAGS specifies the additional compilation options we're using
#   -w suppresses all warnings
#   -Wl,-subsystem,windows gets rid of the console window
# COMPILER_FLAGS = -w -Wl,-subsystem,windows
COMPILER_FLAGS = -g -O0 -Wall -std=c++11

#LINKER_FLAGS specifies the libraries we're linking against
LINKER_FLAGS = -lmingw32 -lSDL2main -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lSDL2

.PHONY: all

all: $(TARGET)

$(TARGET): $(OBJS)
    $(CC) $(INCLUDE_PATHS) $(COMPILER_FLAGS) $(LINKER_FLAGS) $^ -o $@

$(BUILD_DIR)/%.o: $(foreach dir, $(SRC_DIRS), $(dir))/%.cpp | $(BUILD_DIR)
    $(CC) $(INCLUDE_PATHS) $(COMPILER_FLAGS) $(LINKER_FLAGS) $< -o $@

$(BUILD_DIR):
    mkdir -p $@

exec: $(BIN)
    $(BIN).exe

clean:
    @$(RM) -rv $(BUILD_DIR)/*

这些是我要运行的命令:

$ g++ -Iheader -g -O0 -Wall -std=c++11 -lmingw32 -lSDL2main -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lSDL2 src/engine/Game.cpp -c -o build/Game.o

$ g++ -Iheader -g -O0 -Wall -std=c++11 -lmingw32 -lSDL2main -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lSDL2 src/engine/Music.cpp -c -o build/Music.o

$ g++ -Iheader -g -O0 -Wall -std=c++11 -lmingw32 -lSDL2main -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lSDL2 src/engine/State.cpp -c -o build/State.o

$ g++ -Iheader -g -O0 -Wall -std=c++11 -lmingw32 -lSDL2main -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lSDL2 src/engine/Sprite.cpp -c -o build/Sprite.o

$ g++ -Iheader -g -O0 -Wall -std=c++11 -lmingw32 -lSDL2main -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lSDL2 src/application/Main.cpp -c -o build/Main.o

$ g++ -g -O0 -Wall -std=c++11 -lmingw32 -lSDL2main -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lSDL2 build/Main.o build/Game.o build/Music.o build/Sprite.o build/State.o

我使用的是 MSYS2 环境。

【问题讨论】:

    标签: makefile g++ msys2


    【解决方案1】:

    这行不通:

    $(BUILD_DIR)/%.o: $(foreach dir, $(SRC_DIRS), $(dir))/%.cpp | $(BUILD_DIR)
    

    解析变量后,这会扩展为什么?你得到这个:

    build/%.o: src/engine src/application/%.cpp | build
                        ^^
    

    这显然不是你想要的。即使你修正你的定义来做你可能期望的事情:

    $(BUILD_DIR)/%.o: $(foreach dir, $(SRC_DIRS), $(dir)/%.cpp) | $(BUILD_DIR)
                                                        ^^^^^^^
    

    给出:

    build/%.o: src/engine/%.cpp src/application/%.cpp | build
    

    这意味着什么?这意味着为了匹配此模式规则,每个build/XXX.o 文件必须找到(或能够构建)匹配的src/engine/XXX.cpp AND 匹配的src/application/XXX.cpp。基本上每个目标文件都有两个源文件作为先决条件。

    由于您的文件都不符合该条件,因此该规则永远无法匹配,因此 make 将无法找到构建目标 build/XXX.o 的方法。

    你必须在这里写两个不同的规则,每个目录一个:

    $(BUILD_DIR)/%.o: src/engine/%.cpp | $(BUILD_DIR)
            ...
    $(BUILD_DIR)/%.o: src/application/%.cpp | $(BUILD_DIR)
            ...
    

    您也可以使用VPATH 让make 去查看各个目录,如下所示:

    VPATH = $(SRC_DIRS)
    
    $(BUILD_DIR)/%.o: %.cpp | $(BUILD_DIR)
            ...
    

    【讨论】:

    猜你喜欢
    • 2022-11-12
    • 2017-03-31
    • 2013-10-19
    • 1970-01-01
    • 2012-06-15
    • 1970-01-01
    • 2016-03-03
    • 1970-01-01
    • 2014-08-22
    相关资源
    最近更新 更多