004 【编译神器】Makefile:最常用编译方法详解

一种常用于编译的脚本语言,可以更好更方便地管理项目的代码编译。在文件中定义一系列的规则来指定哪些文件先编译,一旦写好后,只需要一个 make 命令就可以编译

一、Makefile 三要素

  • 一般在 makefile 文件中会使用 gcc 命令对源代码进行编译
  • makefile 的编写规则:
目标:依赖
	命令
// 目标:要生成的目标文件
// 依赖:目标文件由哪些文件生成
// 命令:执行该命令由依赖文件生成目标

二、Makefile 工作原理

Makefile 的 工作原理 可以概括为两步:

  1. 检查依赖是否 存在
  2. 检查是否需要 更新
  • 可以用以下伪代码来进行表述
// 检查依赖是否存在
if(依赖存在)
	//执行规则中的命令生成依赖文件的目标文件
	if(目标的修改时间 > 依赖的修改时间)
		不更新目标文件
	else
		更新目标文件
else
	向下搜索,查找是否有生成该依赖文件的规则
	if(没有规则能生成该依赖文件)
		ERROR!

三、Makefile 基本使用方法

我们以经典的 TCP 通讯为例来说明,当我们编写了 TCP 的服务端和客户端两个程序后,要进行编译的话需要运行两次 gcc 指令,比较繁琐,尤其是当我们项目工程具有更多的源文件时,使用 makefile 实现一键编译,将非常的方便。

  • makefile编写,生成 TCP_Server、TCP_Client 两个可执行文件。
all:TCP_Server TCP_Client
TCP_Server:tcp_server.c
	gcc tcp_server.c -o TCP_Server
TCP_Client:tcp_client.c
	gcc tcp_client.c -o TCP_Client

编写完成后,我们只需在当前目录下运行 make all 即可同时编译生成 TCP_Server、TCP_Client 两个目标文件。具体的 Makefile 变量、指令、参数将在下文展开。

  • 运行可执行文件(以 TCP 程序为例)
./TCP_Server 192.168.0.109 1234
./TCP_Client 192.168.0.109 1234

四、Makefile 变量

1、变量类型
  1. 自定义变量
var = abc     // 变量定义
  1. 系统变量
CC = gcc-3.4                     // 指定编译器的类型
CPPFLAGS = -I./                  // 指定预处理的选项 
CFLAGS = -Wall -O2               // 指定编译器选项(例如调试信息、优化等)
LDFLAGS = -L                     // 指定链接器选项
SRC_FILES = main.c foo.c bar.c   // 指定源文件列表
  1. 自动变量
$@ 表示规则中的目标 
$^ 表示规则中的所有条件, 组成一个列表, 以空格隔开, 如果这个列表中有重复的项则消除重复项 
$< 表示规则中的第一个条件 
$? 第一变化的依赖
2、赋值方式

makefile 的赋值方式有简单赋值、递归赋值、条件赋值、追加赋值。本文只介绍最为常用的赋值方式,即递归赋值 =。(其余赋值方式可参考文章:Makefile基础教程(变量的介绍和使用)_makefile 使用变量 编译-CSDN博客

x = abc         // 定义变量并赋值 
bar = $(x)      // 使用变量, $(变量名)

五、Makefile 工程应用

1、编译操作

makefile 在工程上的应用示例如下:

  1. 编译 main.c 、 fun1.c 、 func2.c 生成对应的目标文件 main.o、func1.o、func2.0
  2. 链接所有的目标文件,生成最后的可执行文件
  • 基础写法
CC := gcc
TARGET := hello

# 生成可执行文件
TARGET : hello.o func.o
	$(CC) -o TARGET hello.o func.o

# 生成目标文件
hello.o : hello.c
	$(CC) -c -o hello.o hello.c
func.o : func.c
	$(CC) -c -o func.o func.c

all : TARGET

gcc 编译器参数大全可参考:20个最常用的GCC编译器参数

常用参数

-o    指定输出文件名
-c    只编译源代码,生成目标文件,但不会生成最终可执行文件
  • 进阶写法
TARGET = hello
object = hello.o func1.o func2.o
CC = gcc
CFLAGS = -Wall -O2

TARGET : $(object)
	$(CC) -o $@ $^     # 规则中的目标 规则中的依赖
	
%.o : %.c 
	$(CC) -o $@ -c $<  # 规则中的目标 规则中的第一个条件
2、清理操作

清除目标文件,在 makefile 中使用 rm 指令删除文件,然后在终端中输入 make clean= 清除生成的目标文件

  • 基础写法
# 清除所有 .o 后缀文件及可执行文件
clean :
	rm *.o TARGET

参数: rm -f 强制执行删除操作。

  • 进阶写法
clean: -rm -f $(target) $(object)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_小猪沉塘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值