最详细的Makefile教程

本文介绍了Makefile的基本结构,包括目标、依赖关系、规则和命令,以及如何使用它们管理软件项目中的编译过程。还展示了如何处理复杂的项目结构和使用通配符和内置变量来简化Makefile编写。
摘要由CSDN通过智能技术生成

Makefile 是一个用于管理软件项目中编译、链接和其他任务的工具。它使用 Make 工具来自动化构建过程,确保只有修改过的文件才会重新编译。以下是一个简单但详细的 Makefile 教程,帮助你入门。

1. Makefile 的基础结构

一个基本的 Makefile 包含规则(rules)、目标(targets)、依赖关系(dependencies)和命令(commands)。以下是一个简单的例子:

# 注释以 '#' 开头

# 定义变量
CC = gcc
CFLAGS = -Wall

# 第一个目标是默认目标
all: my_program

# 目标和依赖关系
my_program: main.o utils.o
    $(CC) $(CFLAGS) -o my_program main.o utils.o

# 编译规则
main.o: main.c
    $(CC) $(CFLAGS) -c main.c

utils.o: utils.c
    $(CC) $(CFLAGS) -c utils.c

# 清理规则
clean:
    rm -f my_program *.o

在这个例子中:

  • my_program 是目标,依赖于 main.outils.o
  • main.outils.o 分别是目标,依赖于对应的源文件和头文件。
  • 每个目标都有相应的规则,指定了如何生成它们的命令。

你可以通过执行 make my_program 来构建可执行文件 my_program。如果某个文件发生了更改,Make 工具会自动检测并重新构建相关的文件。

2. Makefile 中的关键概念

  • 目标(target): 是构建过程中的输出文件,可以是可执行文件、库文件等。 (my_program: main.o utils.o 中my_program就是依赖)
  • 依赖关系(dependencies): 是目标生成所依赖的文件或其他目标。(my_program: main.o utils.o 中main.o util.o就是依赖)
  • 规则(rule): 定义了如何生成目标的规则。(my_program: main.o utils.o 中my_program 是由main.o和util.o生成)。
  • 命令(command): 是实际执行的操作,通常是编译、链接等命令。(如$(CC) $(CFLAGS) -o my_program main.o utils.o 就是命令)
  • 变量(variable): 是用于存储值的名称,可以简化 Makefile。(如CC ,CFLAGS)

3.复杂的makefile

编写一个非常复杂的 Makefile 涉及到一个实际的项目,而一个完整的项目的 Makefile 往往更为庞大。以下是一个简化的示例,展示了如何使用上述所有的知识来构建一个具有多个源文件、目录结构和不同规则的项目。请注意,实际项目可能需要更多的规则和变量以满足复杂的构建需求。

假设有如下项目结构

project/
|-- src/
|   |-- main.c
|   |-- utils.c
|   |-- main.h
|   |-- utils.h
|-- lib/
|   |-- math/
|       |-- add.c
|       |-- subtract.c
|       |-- add.h
|       |-- subtract.h
|-- build/
|-- bin/

以下是一个复杂的 Makefile 示例:

# 定义变量
CC = gcc
CFLAGS = -Wall
SRC_DIR = src
LIB_DIR = lib
BUILD_DIR = build
BIN_DIR = bin

# 通配符匹配源文件
SRCS := $(wildcard $(SRC_DIR)/*.c)
OBJS := $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(SRCS))
LIB_SRCS := $(wildcard $(LIB_DIR)/*/*.c)
LIB_OBJS := $(patsubst $(LIB_DIR)/%.c, $(BUILD_DIR)/%.o, $(LIB_SRCS))

# 默认目标:构建可执行文件 my_program
all: $(BIN_DIR)/my_program

# 构建可执行文件规则
$(BIN_DIR)/my_program: $(OBJS) $(LIB_OBJS)
    $(CC) $(CFLAGS) -o $@ $^

# 通配符规则:编译所有源文件到目标文件
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
    $(CC) $(CFLAGS) -c $< -o $@

# 通配符规则:编译所有库源文件到目标文件
$(BUILD_DIR)/%.o: $(LIB_DIR)/%.c
    $(CC) $(CFLAGS) -c $< -o $@

# 清理规则
clean:
    rm -rf $(BUILD_DIR)/* $(BIN_DIR)/*

# 输出详细信息
info:
    @echo "Source files: $(SRCS)"
    @echo "Object files: $(OBJS)"
    @echo "Library source files: $(LIB_SRCS)"
    @echo "Library object files: $(LIB_OBJS)"

因为这个makefile包含了通配符,和内置变量,看起来有点困难,但是基本的规则,目标和依赖没有变化。

  • 通配符:

   *:匹配任意长度的字符,但不包括路径分隔符(如 /)。

# 匹配所有以 .c 结尾的源文件 
*.c: $(CC) $(CFLAGS) -c $< -o $@

    %:匹配任意长度的字符,包括路径分隔符。

# 匹配所有以 .o 结尾的目标文件,对应的源文件是同名的 .c 文件

 %.o: %.c $(CC) $(CFLAGS) -c $< -o $@

 ?:匹配任意单个字符。

# 匹配所有以 a、b 或 c 开头,接着是一个字符,然后是 .c 结尾的源文件

[abc]?.c: $(CC) $(CFLAGS) -c $< -o $@

[]:匹配括号内的任意一个字符。

# 匹配所有以 a、b 或 c 开头,接着是 .c 结尾的源文件

[abc]*.c: $(CC) $(CFLAGS) -c $< -o $@
内置变量:

在 Makefile 中,有一些内置的自动变量用于方便地引用特定信息。以下是一些常用的内置变量:

   $@ 表示规则中的目标文件名

my_target: dependency
    command $@

    $< 表示规则中的第一个依赖文件名

my_target: dependency
    command $<

   $^ 表示规则中的所有依赖文件列表。

my_target: dependency1 dependency2
    command $^

    $? 表示规则中所有比目标文件更新的依赖文件列表

my_target: dependency1 dependency2
    command $?

    $(@D)$(@F) 分别表示目标文件所在的目录和文件名

my_target: dependency
    command $(@D)/$(@F)

这些内置变量使得在 Makefile 中引用文件名、目录名等信息更加方便。使用它们可以避免在规则中硬编码文件名,使得 Makefile 更加灵活和易维护。需要注意的是,这些变量只有在规则的执行过程中才会被正确赋值。

下面逐行解释每一部分:

  1. CC = gcc:定义变量 CC 为编译器的命令,使用 GCC。

  2. CFLAGS = -Wall:定义变量 CFLAGS 为编译选项,包括开启所有警告。

  3. SRC_DIR = src:定义变量 SRC_DIR 为源代码目录。

  4. LIB_DIR = lib:定义变量 LIB_DIR 为库目录。

  5. BUILD_DIR = build:定义变量 BUILD_DIR 为构建目录,用于存放生成的目标文件。

  6. BIN_DIR = bin:定义变量 BIN_DIR 为输出二进制文件目录,用于存放生成的可执行文件。

  7. SRCS := $(wildcard $(SRC_DIR)/*.c):使用通配符匹配源文件,生成源文件列表 SRCS。(wildcard 是一个函数,用于展开通配符,获取符合通配符模式的文件列表。)

  8. OBJS := $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(SRCS)):使用模式替换,生成对应的目标文件列表 OBJS。(patsubst 是 Makefile 中的一个函数,用于执行模式替换(pattern substitution))

  9. LIB_SRCS := $(wildcard $(LIB_DIR)/*/*.c):使用通配符匹配库源文件,生成库源文件列表 LIB_SRCS

  10. LIB_OBJS := $(patsubst $(LIB_DIR)/%.c, $(BUILD_DIR)/%.o, $(LIB_SRCS)):使用模式替换,生成对应的库目标文件列表 LIB_OBJS

  11. all: $(BIN_DIR)/my_program:定义默认目标 all,构建可执行文件 my_program

  12. $(BIN_DIR)/my_program: $(OBJS) $(LIB_OBJS):构建可执行文件规则,依赖于所有源文件和库文件的目标文件。

  13. $(CC) $(CFLAGS) -o $@ $^:构建可执行文件命令,使用变量引用。

  14. $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c:通配符规则,编译所有源文件到目标文件。

  15. $(CC) $(CFLAGS) -c $< -o $@:通配符规则的命令,使用自动变量 $<$@

  16. $(BUILD_DIR)/%.o: $(LIB_DIR)/%.c:通配符规则,编译所有库源文件到目标文件。

  17. $(CC) $(CFLAGS) -c $< -o $@:通配符规则的命令,使用自动变量 $<$@

  18. clean: rm -rf $(BUILD_DIR)/* $(BIN_DIR)/*:定义清理规则,删除构建目录和输出目录下的所有文件。

  19. info: @echo "Source files: $(SRCS)" ...:输出详细信息规则,显示源文件、目标文件等详细信息。使用 @echo 避免输出规则本身。

这个 Makefile 结合了之前提到的变量、通配符、自动变量等概念,用于构建包含多个源文件和库文件的项目。

  • 37
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 陈皓的makefile教程pdf是一本关于makefile的实用工具书,它详细介绍了makefile的基本语法、规则和常见用法,涵盖了多种操作系统的编译环境和工具链,适用于各类软件开发的实际需求。 该教程的优点在于它提供了很多实用的示例和详细的讲解,使读者能够很快地理解并掌握makefile的编写方法,并且可以根据自己的需求进行灵活的配置和扩展。同时,教程也讲解了一些高级技巧和优化方法,让读者了解和熟练运用makefile来提高程序的编译效率和可维护性。 针对初学者,该教程从基础入手,介绍了makefile的起源和作用,十分易于理解。然后逐步深入到常用的命令、变量、条件判断、函数等详细讲解,并提供大量的实例来演示不同的编译方式和场景。对于有经验的开发者,该教程也提供了很多有用的技巧和经验分享,可以使其更好地利用makefile进行项目管理和优化。 总体来说,陈皓的makefile教程pdf是一本值得推荐的宝典,它可以帮助读者快速学习makefile的编写方法,并提供大量的实用技巧和经验分享,从而提高软件开发的效率和质量。 ### 回答2: 陈皓的makefile教程是一份极为详尽和实用的教程,它适合想要初步学习和使用makefile的程序员和系统管理员。该教程包含了很多有关makefile的基本概念和语法的解释,并提供了实用的例子和模板来帮助学习者快速上手。 陈皓的教程以实践为重,内容非常具体,详细讲解了makefile的各种常见用法,如变量、条件语句、循环语句等等,帮助学习者可以很好地掌握makefile的应用。同时,教程还包含了一些高级使用技巧,如自动化依赖关系、多目标构建、命令行参数等等,使学习者可以更加深入地使用makefile。 此外,陈皓的教程还提供了很多有用的工具和库,这些工具和库可以协助使用makefile实现更加高级的目标。尤其是对互联网公司的程序员而言,使用陈皓的教程可以快速学会如何构建和发布复杂的应用程序,降低代码管理和部署的成本和工作量,提高工作效率。 总之,陈皓的makefile教程pdf是一份非常好用的资源,对程序员来说是一份不可多得的学习资料,它能够为初学者提供深入浅出的指导,同时也适用于有经验的Makefile用户。 ### 回答3: 陈皓是一位知名的计算机程序员和教育家,他在网络上分享了许多优质的教程和资料,其中就包括了makefile教程的PDF文件。makefile是一种代码构建工具,可以帮助开发者在编写大型项目时更加高效地管理代码,将源文件编译成可执行文件。陈皓的makefile教程PDF详尽地介绍了makefile的使用方法、语法结构和示例代码,帮助读者深入理解makefile的原理和实现方式。这份教程不仅适合初学者学习,也可以供经验丰富的开发者参考进一步提高技能。在PDF文件中,陈皓以简洁明了的语言和大量的案例说明了如何正确编写makefile,特别是在软件开发中需要考虑的各种问题和实践经验。如果你正在学习或掌握makefile的使用,这份教程是非常推荐的学习资料。陈皓的教程PDF可以在互联网上免费获取,学习者可以自主下载或者在线阅读。相信通过学习这份教程后,你一定能更好地掌握makefile的技术,并在日常开发中得到应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值