You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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也为空,链接时$^无内容。
    修正步骤:

    1. 将源文件匹配规则改为C++后缀:
      SRC := $(wildcard $(SRC_DIR)/*.cpp)
      
    2. 同步修改目标文件编译规则,将.c改为.cpp:
      $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR)
              $(CXX) -c $(CXXFLAGS) $< -o $@
      

    (若你的源文件确实是.c,请检查source目录下是否存在.c文件,或wildcard路径是否正确)

  • 可选:清理无效依赖配置:
    目前-include $(OBJ:.o=.d)用于自动生成依赖,但OBJ为空时该行不会生效。等源文件匹配正常后,若需要自动依赖可保留,否则可暂时注释。

内容的提问来源于stack exchange,提问作者Xellophane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 15:20:32