【问题标题】:Error: "Mixed implicit and static pattern rules" in my Makefile错误:我的 Makefile 中的“混合隐式和静态模式规则”
【发布时间】:2015-05-01 10:11:54
【问题描述】:

我有一个工作 Makefile 用于小型 C++ 应用程序,在一个文件夹中只有几个源代码文件,该文件夹也是输出文件夹。现在我试图分离源文件和目标文件并遇到了问题。这就是我的makefile现在的样子,我将在下面详细说明问题所在。

CC = gcc
CXX = g++
RM = del

TARGET = plox.exe

CFLAGS = -Wall -ggdb -O3 $(INCLUDE)
CXXFLAGS = -std=c++11 -Wall -ggdb -O3 $(INCLUDE)
LDFLAGS = $(LIB) -lglfw3 -lopengl32 -lglu32 -lgdi32

INCLUDE = -I$(GLFW_INC) -I$(GLAD_INC)
LIB = -L$(GLFW_LIB)

SRC_DIR = src
BUILD_DIR = build

GLFW_DIR = d:/external/glfw-3.1
GLFW_INC = $(GLFW)/include
GLFW_LIB = $(GLFW)/lib64

GLAD = d:/external/glad-c
GLAD_INC = $(GLAD)/include

CXX_SOURCES = $(SRC_DIR)/%.cpp
CXX_OBJS = $(addprefix $(BUILD_DIR)/, $(CXX_SOURCES:.cpp=.o))
OBJS = $(CXX_OBJS) $(BUILD_DIR)/glad.o

all: $(TARGET)

$(TARGET): $(OBJS)
    $(CXX) -o $@ $^ $(LDFLAGS)

$(CXX_OBJS): %.o: $(SRC_DIR)%.cpp
    $(CXX) $(CXXFLAGS) -c -o $@ $<

$(BUILD_DIR)/glad.o: src/glad.c
    $(CC) -c $(CFLAGS) -c -o $(BUILD_DIR)/glad.o $(SRC_DIR)/glad.c

.PHONY: clean

clean:
    $(RM) $(TARGET) $(OBJS)

问题出在一行:

$(CXX_OBJS): %.o: $(SRC_DIR)/%.cpp

在我进行更改之前,它看起来像这样:

$(CXX_OBJS): %.o: %.cpp

一位朋友帮助给了我一个模板,但我从来不知道那行的真正作用。在another thread 我了解到这是一个静态模式规则,所以我想这就是我犯错误的地方。但是现在写下来,我认为错误可能已经更早了。我在定义$(CXX_OBJS) 时可能犯了一个错误。难道该列表中的对象的形式是build/src/test.o 而不是build/test.o

但是如何修复addprefix 行以产生正确的输出?标题中的错误来自哪里;我在哪里混合这些?我认为这可能与静态模式规则中的 $(SRC_DIR) 有关,因为我可能误解了它的工作原理,但忽略它并不会使错误消失。此外(假设CXX_OBJS 稍后可以正常工作),如果静态模式规则检查列表$(CXX_OBJS) 中的每个文件是否与%.o 匹配,然后依赖于以.cpp 结尾的同一文件,那么这也是不正确的,因为 build 文件夹前缀。

总而言之,我对如何正确处理文件夹前缀感到非常困惑,非常感谢任何建议!

【问题讨论】:

  • 为什么需要分离对象和源文件?
  • @Steephen Hum,实际上这是一个好问题。我在考虑一个“好的”项目结构,也许在分离东西方面走得太远了。但尽管如此,我认为我可以从中学到一些东西:)

标签: c++ windows c++11 makefile


【解决方案1】:

除了MadScientist's correct answer之外,我的Makefile中还有一个由重命名变量引入的错误:mingw32-make找不到-lglfw3部分,因为我在GLFW_INC的定义中使用了$(GLFW)GLFW_LIB,但没有定义它。我想改用$(GLFW_DIR)

【讨论】:

    【解决方案2】:

    在静态模式规则中,第一部分(目标)中的单词必须是真实文件。它们都不能包含模式 (%)。你有:

    CXX_SOURCES = $(SRC_DIR)/%.cpp
    CXX_OBJS = $(addprefix $(BUILD_DIR)/, $(CXX_SOURCES:.cpp=.o))
    $(CXX_OBJS): %.o: $(SRC_DIR)%.cpp
    

    所以CXX_OBJS$(BUILD_DIR)/$(SRC_DIR)/%.o,其中包含一个模式,所以这是非法的。

    我真的不知道你想用CXX_SOURCES 做什么。也许你想要:

    CXX_SOURCES := $(wildcard $(SRC_DIR)/*.cpp)
    

    改为?

    【讨论】:

    • 我不得不查找wildcard,实际上,我错误地解释了% 的内容,而wildcard 正是我想要的。 CXX_SOURCES 现在只有没有 $(SRC_DIR) 前缀的文件是否正确?因为否则我认为它仍然会出现在CXX_OBJS 中。在wildcard 更改后,它现在在$(TARGET): $(OBJS) 下方的行中与mingw32-make: *** [plox.exe] Error 1 一起崩溃。
    • 也许如果你给出了一个你想要编译的真实文件路径名的明确示例以及你想要的输出,那么你会更容易理解你想要做什么。至于消息,那不是错误。那只是告诉你一些失败的事情。您必须查看该消息之前并找到 first 错误消息:这是有趣的错误消息,而不是最后一个错误消息。
    • 这是一个愚蠢的错误,因为我重命名了旧 makefile 的变量。有关详细信息,请参阅我的答案,谢谢,现在可以使用! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    相关资源
    最近更新 更多