源文件与头文件在子目录时的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:
- You're not compiling
foo.cat all — your current rule only handlessrc/main.cto generatebuild/main.o, but completely ignoressrc/modules/module1/foo.c. The linker needs all relevant object files to resolve function references, so missingfoo.omeans it can't findfoo_function's definition. - Your compile command lacks the
-cflag — Without-c, GCC will try to turn your.cfile directly into an executable instead of an object file (.o). That meansbuild/main.ois 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
findcommand grabs every.cfile undersrc, so you won't have to update the Makefile when adding new modules. - Generate all object file paths: The
OBJSvariable maps every source file to its corresponding build location, includingbuild/modules/module1/foo.o. - Proper compile command: The
-cflag ensures GCC produces object files instead of executables, which is essential for the linking step. - Auto-create subdirectories:
mkdir -pensures the build directory structure matches your source structure, avoiding "no such file or directory" errors. - Link all objects: The
maintarget now links every compiled object file, sofoo_function's definition fromfoo.ois 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
相关产品推荐
相关产品推荐

