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

源文件与头文件在子目录时的Makefile编写及链接错误解决

Let's break down what's going wrong here and fix it step by step:

First, your Makefile has two critical issues causing the "undefined reference" error:

  1. You're not compiling foo.c at all — your current rule only handles src/main.c to generate build/main.o, but completely ignores src/modules/module1/foo.c. The linker needs all relevant object files to resolve function references, so missing foo.o means it can't find foo_function's definition.
  2. Your compile command lacks the -c flag — Without -c, GCC will try to turn your .c file directly into an executable instead of an object file (.o). That means build/main.o is actually a full executable, not the intermediate object file the linker expects, breaking the entire build flow.

On top of that, your header file path is incorrect: your headers live in build/include, but -I include/ tells GCC to look in a non-existent top-level include folder. You didn't hit a header error yet, but fixing this will prevent future issues.

Here's the corrected Makefile with key changes explained:

CC = gcc
CFLAGS = -std=gnu11 -O3 -Wall -Wextra -Wpedantic -Wstrict-aliasing
LDFLAGS = -lpthread
BLD = build
SRC = src
# Fix header path to point to the actual include directory under build
INC = $(BLD)/include

# Automatically collect all .c files under src — no need to manually add modules
SRCS := $(shell find $(SRC) -name "*.c")
# Convert each src/xxx.c path to build/xxx.o to get all required object files
OBJS := $(SRCS:$(SRC)/%.c=$(BLD)/%.o)

define cc-command
# Add -c flag: compile only, don't link — produces a proper object file
$(CC) $(CFLAGS) -I $(INC) -c $< -o $@
endef

all: main
# Now main depends on ALL object files (including foo.o and main.o)
main: $(OBJS)
	$(CC) -o $@ $^ $(LDFLAGS)

# Compile each .c to its corresponding build subdirectory, create directories first
$(BLD)/%.o: $(SRC)/%.c
	@mkdir -p $(dir $@)  # Silently create required subdirectories
	$(cc-command)

# Optional: Clean up built files easily
clean:
	rm -rf $(BLD) main

Key Fixes Explained:

  • Auto-collect source files: The find command grabs every .c file under src, so you won't have to update the Makefile when adding new modules.
  • Generate all object file paths: The OBJS variable maps every source file to its corresponding build location, including build/modules/module1/foo.o.
  • Proper compile command: The -c flag ensures GCC produces object files instead of executables, which is essential for the linking step.
  • Auto-create subdirectories: mkdir -p ensures the build directory structure matches your source structure, avoiding "no such file or directory" errors.
  • Link all objects: The main target now links every compiled object file, so foo_function's definition from foo.o is included in the final executable.

You don't need to write separate rules for each module — this generic setup handles all your source files cleanly. Run make now, and the undefined reference error should be gone.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 17:22:43