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

基于子目录的C项目Makefile编写:生成test并存目标文件至obj

Perfect, I’ve put together a clean, maintainable Makefile tailored to your project structure. Let’s break this down step by step so you understand how it works, and you can tweak it later if needed.

First, let’s confirm your project layout matches what I’m building for:

  • ./include/: Stores a.h, b.h, c.h
  • ./src/: Stores main.c, a.c, b.c, c.c
  • ./obj/: Will hold all compiled .o target files
  • Final executable: test

Basic Functional Makefile

Save this as Makefile in your project root directory:

# Define compiler and core flags
CC = gcc
# Enable warnings + point compiler to your include directory
CFLAGS = -Wall -Wextra -Iinclude
# Directory paths for organization
OBJ_DIR = obj
SRC_DIR = src
# Auto-detect all .c files in src/
SRCS = $(wildcard $(SRC_DIR)/*.c)
# Convert src/*.c paths to obj/*.o (e.g., src/main.c → obj/main.o)
OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRCS))
# Name of your final executable
TARGET = test

# Default target: run when you just type `make`
all: $(TARGET)

# Link all object files to build the executable
$(TARGET): $(OBJS)
	$(CC) $(CFLAGS) $^ -o $@

# Compile individual .c files to .o files in obj/
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
	$(CC) $(CFLAGS) -c $< -o $@

# Create obj/ directory if it doesn't exist (order-only prerequisite)
$(OBJ_DIR):
	mkdir -p $(OBJ_DIR)

# Clean up all build artifacts
clean:
	rm -rf $(OBJ_DIR) $(TARGET)

# Mark these as "phony" (not actual files, so Make doesn't get confused)
.PHONY: all clean

Key Explanations:

  • Variables: Using variables makes it easy to update your compiler, flags, or directories later without rewriting the whole file. $(wildcard) grabs all .c files in src/, and $(patsubst) maps them to the correct .o paths in obj/.
  • Order-only prerequisite (| $(OBJ_DIR)): Ensures the obj/ directory exists before compiling, but won’t recompile everything if the directory’s timestamp changes.
  • Automatic variables:
    • $^: All prerequisites (all .o files for the executable)
    • $<: The first prerequisite (the .c file being compiled)
    • $@: The target file (either the .o file or the final executable)
  • clean: Deletes the obj/ directory and test executable to start fresh.

Advanced Version (Auto-Detect Header Dependencies)

If you want Make to automatically recompile files when you update a header (e.g., a.h), use this version which adds auto-dependency generation:

# Define compiler and flags (add -MMD -MP for auto-dependencies)
CC = gcc
CFLAGS = -Wall -Wextra -Iinclude -MMD -MP
OBJ_DIR = obj
SRC_DIR = src
SRCS = $(wildcard $(SRC_DIR)/*.c)
OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRCS))
# Auto-generated dependency files (one per .o file)
DEPS = $(OBJS:.o=.d)
TARGET = test

all: $(TARGET)

$(TARGET): $(OBJS)
	$(CC) $(CFLAGS) $^ -o $@

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
	$(CC) $(CFLAGS) -c $< -o $@

$(OBJ_DIR):
	mkdir -p $(OBJ_DIR)

# Include auto-generated dependency files
-include $(DEPS)

clean:
	rm -rf $(OBJ_DIR) $(TARGET)

.PHONY: all clean

What’s New?

  • -MMD -MP: Tells gcc to generate a .d file for each .o file, which lists all header dependencies for that source file.
  • -include $(DEPS): Makes Make read these .d files, so it knows to recompile the right source files when you update a header.

How to Use

  1. Save the Makefile in your project root.
  2. Run make in your terminal: it will build the test executable and store all .o files in obj/.
  3. Run make clean to delete all build files and start over.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:14:46