为何GNU Make未填充$^变量?编译链接报错排查
问题与解决方案
问题
手动执行g++ source/* -lSDL2 -o bin/fly_fishing可正常编译项目,但运行make时出现链接错误,提示undefined reference to main,本质是链接阶段$^变量未填充任何目标文件。错误输出如下:
mkdir -p bin g++ -lSDL2 -o bin/fly_fishing /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/Scrt1.o: in function `_start': (.text+0x17): undefined reference to `main' collect2: error: ld returned 1 exit status make: *** [Makefile:20: bin/fly_fishing] Error 1
使用的Makefile内容:
SRC_DIR := source OBJ_DIR := objects BIN_DIR := bin EXE := $(BIN_DIR)/fly_fishing SRC := $(wildcard $(SRC_DIR)/*.c) OBJ := $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) CXXFLAGS := -Wall #CFLAGS := -Wall LDLIBS := -lSDL2a LDFLAGS := .PHONY: all clean all: $(EXE) $(EXE): $(OBJ) | $(BIN_DIR) $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR) $(CXX) -c $(CXXFLAGS) $(CFLAGS) $< -o $@ $(BIN_DIR) $(OBJ_DIR): mkdir -p $@ clean: @$(RM) -rv $(BIN_DIR) $(OBJ_DIR) -include $(OBJ:.o=.d)
解决方案
导致$^为空的核心原因是未匹配到有效源文件,加上库链接参数错误,具体修正点如下:
修正SDL库链接参数:
Makefile中LDLIBS写的是-lSDL2a,与手动编译时的正确参数-lSDL2不符,修改为:LDLIBS := -lSDL2匹配正确的源文件后缀:
你用g++手动编译,说明源文件大概率是C++后缀(.cpp),但Makefile里用$(wildcard $(SRC_DIR)/*.c)仅匹配C语言的.c文件,导致SRC为空,进而OBJ也为空,链接时$^无内容。
修正步骤:- 将源文件匹配规则改为C++后缀:
SRC := $(wildcard $(SRC_DIR)/*.cpp) - 同步修改目标文件编译规则,将
.c改为.cpp:$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR) $(CXX) -c $(CXXFLAGS) $< -o $@
(若你的源文件确实是
.c,请检查source目录下是否存在.c文件,或wildcard路径是否正确)- 将源文件匹配规则改为C++后缀:
可选:清理无效依赖配置:
目前-include $(OBJ:.o=.d)用于自动生成依赖,但OBJ为空时该行不会生效。等源文件匹配正常后,若需要自动依赖可保留,否则可暂时注释。
内容的提问来源于stack exchange,提问作者Xellophane
相关产品推荐
相关产品推荐

