Makefile快速入门1

Makefile 编写教程

一、Makefile 核心概念
  1. 基本组成要素
    Makefile 由 目标(Target)依赖(Dependencies) 和 命令(Commands) 三部分组成,格式为:
    target: dependencies
        command  # 必须用 Tab 缩进
    
    • 目标:要生成的文件或操作名称(如可执行文件、伪目标)。
    • 依赖:生成目标所需的文件或其他目标。
    • 命令:生成目标的 Shell 指令(如编译命令)。
  2. 工作流程
    • 执行 make 时,默认查找第一个目标(或通过 make target 指定目标)。
    • 检查依赖是否更新(通过文件时间戳),若依赖比目标新,则执行关联命令。
    • 递归处理依赖的依赖,直至生成最终目标。
二、基础实战:最小化示例
  1. 单文件编译
    假设项目结构如下:
    project/
    ├── main.c
    └── Makefile
    
    Makefile 内容
    main: main.c
        gcc -o main main.c
     
    .PHONY: clean  # 声明伪目标
    clean:
        rm -f main
    • 操作演示
      make      # 编译程序
      ./main    # 运行输出
      make clean # 清理生成的文件
      
  2. 多文件编译
    项目结构:
    project/
    ├── main.c
    ├── utils.c
    └── utils.h
    
    Makefile 内容
    # 基础配置
    # 定义最终生成的可执行文件名称
    TARGET = app
     
    # 指定使用的编译器(这里使用 GNU C 编译器)
    CC = gcc
     
    # 编译选项:
    # -Wall: 启用所有警告信息
    # -O2: 启用二级优化
    # -I.: 添加当前目录到头文件搜索路径
    CFLAGS = -Wall -O2 -I.  # -I. 显式指定当前目录为头文件搜索路径
     
    # 使用 wildcard 函数自动获取当前目录下所有 .c 文件
    SRCS = $(wildcard *.c)
     
    # 将 .c 文件名替换为 .o 文件名(即生成对应的目标文件列表)
    OBJS = $(SRCS:.c=.o)
     
    # 将 .o 文件名替换为 .d 文件名(即生成对应的依赖文件列表)
    DEPS = $(OBJS:.o=.d)  # 自动生成依赖文件
     
    # 主目标:构建最终的可执行文件
    # 依赖所有目标文件 $(OBJS)
    $(TARGET): $(OBJS)
    	# 使用 gcc 链接所有目标文件,生成可执行文件
    	$(CC) $(CFLAGS) -o $@ $^
    	# $@ 表示目标文件(即 $(TARGET))
    	# $^ 表示所有依赖文件(即 $(OBJS))
     
    # 编译规则:如何从 .c 文件生成 .o 文件
    %.o: %.c
    	# 使用 gcc 编译 .c 文件:
    	# -MMD: 生成依赖关系文件(.d),但不包含系统头文件
    	# -MP: 为每个依赖生成一个空目标,避免删除头文件时出错
    	# -c: 只编译不链接
    	# $<: 表示第一个依赖文件(即当前的 .c 文件)
    	# $@: 表示目标文件(即当前的 .o 文件)
    	$(CC) $(CFLAGS) -MMD -MP -c $< -o $@
     
    # 包含自动生成的依赖关系
    # -include 表示如果文件不存在也不报错
    -include $(DEPS)
     
    # 伪目标声明(这些目标不对应实际文件)
    .PHONY: clean all
     
    # 默认目标(执行 make 时默认构建 all)
    all: $(TARGET)  # 默认目标
     
    # 清理目标:删除所有生成的文件
    clean:
    	# 删除所有目标文件、依赖文件和最终的可执行文件
    	rm -f $(OBJS) $(DEPS) $(TARGET)
    • 关键语法解析
      • wildcard:获取匹配模式的文件列表(如 *.c)。
      • $(SRCS:.c=.o):字符串替换,将 .c 替换为 .o
      • $@:当前目标名;$^:所有依赖文件;$<:第一个依赖文件。
三、多文件编译与多目录管理
  1. 项目结构

    project/
    ├── src/
    │   ├── main.c
    │   └── utils.c
    ├── include/
    │   └── utils.h
    └── Makefile
    

  2. Makefile 实现

    SRCDIR = src        # 源码目录
    INCDIR = include    # 头文件目录
    BUILDDIR = build    # 编译输出目录
    SRCS = $(wildcard $(SRCDIR)/*.c)  # 自动获取 src/ 下所有 .c 文件
    OBJS = $(patsubst $(SRCDIR)/%.c,$(BUILDDIR)/%.o,$(SRCS))  # 生成 build/ 下的 .o 路径
     
    $(BUILDDIR)/%.o: $(SRCDIR)/%.c
        @mkdir -p $(@D)  # 自动创建 build/ 目录(包括子目录)
        $(CC) $(CFLAGS) -I$(INCDIR) -c $< -o $@
     
    TARGET = app
    $(TARGET): $(OBJS)
        $(CC) $(CFLAGS) -o $@ $^
     
    .PHONY: clean
    clean:
        rm -rf $(BUILDDIR) $(TARGET)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值