Linux----Makefile基础

打印 上一主题 下一主题

主题 911|帖子 911|积分 2733


Makefile 是自动化构建工具 make 的设置文件,用于界说编译规则和依赖关系,实现高效增量编译。
初识makefile


1. 什么是 make?



  • 界说
    make 是一个命令行工具(可执行程序),用于解析并执行 Makefile 中界说的编译规则,实现自动化构建。
  • 路径
    通常安装在 /usr/bin/make(Linux/Unix 系统)。
  • 功能
    根据 Makefile 中的规则,判断哪些文件必要重新编译,并执行相应的命令。

2. 什么是 Makefile?



  • 界说
    一个文本文件,由开发者编写,用于描述程序的编译规则依赖关系构建步调
  • 作用

    • 指导 make 命令如何编译和链接程序。
    • 记录源文件、目标文件、可执行文件之间的依赖关系。

  • 默认查找规则
    执行 make 命令时,默认在当前目次按次序查找 GNUmakefile → makefile → Makefile。

3. 使用 Makefile 的优势

优势说明简化编译命令只需输入 make 即可自动完成复杂编译步调,无需手动输入长命令。进步编译效率仅重新编译修改过的文件及其依赖项,大幅减少重复编译时间。维护代码关系清晰管理多文件项目标依赖关系(如 .c、.h、.o 文件间的关联)。跨平台支持规则文件通用,可在不同平台(如 Linux 和 Windows 的开发情况)中移植。
4. make 工具的核心价值



  • 本质
    GNU make 是一种代码维护工具,专注于自动化构建和依赖管理。
  • 解决题目

    • 大量代码的依赖维护

      • 项目巨大时,手工维护编译命令复杂且易错。
      • Makefile 明白界说依赖关系,自动化编译流程。

    • 减少重复编译时间

      • 通过时间戳和依赖分析,仅重新编译修改过的文件。
      • 避免全量编译,节省开发时间。



5. make 的跨平台特性

平台使用方式Linux/Unix需手动编写 Makefile 文件。Windows通常由 IDE(如 Visual Studio)自动天生 Makefile 或等效脚本。
6. 示例:Makefile 的作用场景

假设项目包罗以下文件:


  • main.c(依赖 utils.h)
  • utils.c(依赖 utils.h)
1. 基本布局

  1. # 注释以 # 开头
  2. 目标(target): 依赖(dependencies)
  3.     [Tab]命令(command)
复制代码
部分说明目标要天生的文件名或伪目标(如 clean)依赖目标所需的文件或其他目标命令天生目标的 Shell 命令(必须用 Tab 缩进)
2. 示例:单文件编译

  1. # 编译 main.c 生成可执行文件 app
  2. app: main.c
  3.     gcc main.c -o app
  4. # 伪目标:清理生成的文件
  5. .PHONY: clean
  6. clean:
  7.     rm -f app
复制代码

3. 多文件编译与变量

  1. # 定义变量
  2. CC = gcc
  3. CFLAGS = -Wall -O2
  4. TARGET = app
  5. SRCS = main.c utils.c
  6. OBJS =   \)(SRCS:.c=.o)
  7. # 默认目标
  8. \(  (TARGET):   \)(OBJS)
  9.     \(  (CC)   \)(CFLAGS) -o \(  @   \)^
  10. # 隐式规则:将 .c 文件编译为 .o 文件
  11. %.o: %.c
  12.     \(  (CC)   \)(CFLAGS) -c \(  < -o   \)@
  13. # 清理
  14. .PHONY: clean
  15. clean:
  16.     rm -f \(  (TARGET)   \)(OBJS)
复制代码

4. 自动变量

变量说明\( @当前目标名(如 app)\)<第一个依赖文件名(如 main.c)\( ^全部依赖文件名(去重)\)?比目标更新的依赖文件列表\( *匹配通配符 % 的部分(如 %.c: %.o 中的 main)
5. 函数与条件判断

  1. # 查找所有 .c 文件
  2. SRCS =   \)(wildcard *.c)
  3. # 替换后缀生成 .o 文件
  4. OBJS = \(  (patsubst %.c,%.o,  \)(SRCS))
  5. # 条件判断
  6. ifeq (\(  (DEBUG),1)
  7.     CFLAGS += -g
  8. else
  9.     CFLAGS += -O2
  10. endif
复制代码

6. 伪目标与依赖链

  1. .PHONY: all clean rebuild
  2. # 默认目标
  3. all: app
  4. # 强制重建所有文件
  5. rebuild: clean all
  6. # 多目标定义
  7. obj1 obj2: common.h
  8.     echo "Building   \)@"
复制代码

7. 头文件依赖自动天生

  1. # 生成 .d 依赖文件
  2. %.d: %.c
  3.     \(  (CC) -M   \)< -o \(  @
  4. # 包含所有 .d 文件
  5. -include   \)(SRCS:.c=.d)
复制代码

8. 常用命令选项

命令说明make编译默认目标(第一个目标或名为 all 的目标)make target编译指定目标(如 make clean)make -n模拟执行命令(不实际运行)make -j4并行编译(4线程加快)
9. 完整示例

  1. CC = gcc
  2. CFLAGS = -Wall -Iinclude
  3. LDFLAGS = -lm
  4. TARGET = myapp
  5. SRC_DIR = src
  6. OBJ_DIR = obj
  7. SRCS = \(  (wildcard   \)(SRC_DIR)/*.c)
  8. OBJS = \(  (patsubst   \)(SRC_DIR)/%.c,\(  (OBJ_DIR)/%.o,  \)(SRCS))
  9. # 主目标
  10. \(  (TARGET):   \)(OBJS)
  11.     \(  (CC)   \)^ -o \(  @   \)(LDFLAGS)
  12. # 编译 .c 到 .o
  13. \(  (OBJ_DIR)/%.o:   \)(SRC_DIR)/%.c
  14.     @mkdir -p \(  (OBJ_DIR)
  15.       \)(CC) \(  (CFLAGS) -c   \)< -o \(  @
  16. # 清理
  17. .PHONY: clean
  18. clean:
  19.     rm -rf   \)(TARGET) \(  (OBJ_DIR)
复制代码

10. 最佳实践


  • 目次分离:源码(src/)、头文件(include/)、对象文件(obj/)分开存放。
  • 增量编译:合理设置依赖关系,避免全量编译。
  • 变量管理:会合界说编译器、标志、路径等。
  • 错误处置惩罚:在命令前加 - 忽略错误(如 -rm -f file)。
  • 跨平台:避免使用 Shell 特有语法,或用 \)(SHELL) 指定表明器。

11. 常见错误



  • Tab 与空格混用:命令必须用 Tab 缩进。
  • 依赖缺失:未列出头文件导致修改后不重新编译。
  • 路径错误:未精确处置惩罚相对/绝对路径。
  • 变量覆盖:命令行参数优先级高于 Makefile 中的界说。
12.增补






免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

西河刘卡车医

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表