当前位置: 首页 > news >正文

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.cgcc tcp_server.c -o TCP_Server
TCP_Client:tcp_client.cgcc 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.call : TARGET

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

常用参数

-o    指定输出文件名
-c    只编译源代码,生成目标文件,但不会生成最终可执行文件
  • 进阶写法
TARGET = hello
object = hello.o func1.o func2.o
CC = gcc
CFLAGS = -Wall -O2TARGET : $(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)

http://www.mrgr.cn/news/25473.html

相关文章:

  • Linux - iptables防火墙
  • 【警告 C6031:返回值被忽略:scanf】
  • Linux计算文件权限的mode和umask
  • bug是什么意思
  • MySQL学习(函数整理)
  • go 笔记
  • 【复杂系统系列(中级)】Kolmogorov复杂度——信息的无序度量【通俗理解】
  • [001-02-001]. 第07-02节:线程的创建与使用
  • 《C++初始化列表陷阱:谨慎前行,避免潜在风险》
  • 【数字集成电路与系统设计】Chisel/Scala简介与Verilog介绍
  • 【数字集成电路与系统设计】基本的组合逻辑电路
  • AI大模型全栈工程师课程笔记 - RAG 检索增强生成
  • 树莓派安装 OpenCV 教程
  • Coggle数据科学 | 小白学 RAG:Milvus 介绍与使用教程
  • 6、多线程
  • Android Studio报错: Could not find pub.devrel:easypermissions:0.3.0, 改用linux编译
  • 机器CPU突然升高的原因是什么?
  • [数据集][目标检测]脊椎检测数据集VOC+YOLO格式1137张1类别
  • 计算机网络 ---- OSI参考模型TCP/IP模型
  • rtems 5.3 qemu realview_pbx_a9 环境搭建:生成 rtems arm 工具链