Makefile的编写

GCC编译

在Linux系统中,对于单个或者少量文件项目我们经常使用GCC编译,GCC 编译代码主要有两种方式:一次编译和分步编译。

GCC常用编译选项

-E仅预处理,不编译gcc -E main.c -o main.i
-S编译到汇编语言,不汇编gcc -S main.c -o main.s
-c编译和汇编,不链接gcc -c main.c -o main.o
-o指定输出文件名称gcc main.c -o program
-Wall开启常见编译警告gcc -Wall main.c
-g生成调试信息(用于 GDB)gcc -g main.c -o debug
-O2开启二级优化(提高性能)gcc -O2 main.c
-I 路径指定头文件搜索路径gcc -I ./include main.c
-l 库名链接指定库文件gcc main.c -lm
-L 路径指定库文件搜索路径gcc main.c -L ./lib -lmylib

1.一次编译

基本命令

gcc [选项] 源文件.c -o 可执行文件

# 编译单个 C 文件
gcc main.c -o program

# 编译多个 C 文件
gcc main.c utils.c math.c -o program

# 添加编译选项(如优化、调试信息)
gcc -Wall -O2 -g main.c utils.c -o program

使用过程:

2.分步编译

1.预处理:处理 #include、#define 等指令,生成 .i 文件

gcc -E main.c -o main.i

2.编译:将 .i 文件转换为汇编代码 .s

gcc -S main.i -o main.s

3.汇编:将汇编代码 .s 转换为目标文件 .o

gcc -c main.s -o main.o

4.链接:将多个 .o 文件和库文件合并为可执行文件

gcc main.o utils.o -o program

使用过程:

make工具和makefile文件

介绍

为什么要使用makefile:

自动化编译:避免手动输入复杂的编译命令尤其是对于大型项目有超多.c文件。
增量编译:只重新编译修改过的文件,提高效率。
跨平台兼容:在不同系统上保持一致的编译规则。

make 工具

简介:工程管理器,顾名思义,就是管理较多文件
功能:根据文件依赖关系自动编译程序,避免重复编译未修改的文件。
核心逻辑:
检查目标文件是否存在。
检查依赖文件是否比目标文件新。
若依赖更新或目标不存在,则执行命令重新生成目标。

安装make

sudo apt install make

Makefile 文件

Makefile是一个定义了关于项目编译和链接等规则的文件,它在Linux系统下的C/C++项目编译中起到了自动化编译的作用。Makefile文件中包含了编译器和链接器的参数选项,并且描述了所有源文件之间的关系,如源代码文件需要的特定的包含文件,可执行文件要求包含的目标文件模块及库等。创建程序(make程序)首先读取makefile文件,然后激活编译器、汇编器、资源编译器和链接器以便产生最后的输出,通常是可执行文件。

编写makefile

Makefile 基本原理

1. 文件依赖关系

Makefile 的核心是定义文件间的依赖关系,并基于文件修改时间决定哪些部分需要重新编译:

目标:通常是要生成的文件(如可执行文件、库文件)或操作名称(如 clean)。
依赖:生成目标所需的文件或其他目标。
规则:定义如何从依赖生成目标的命令。

2. 工作流程

当执行 make 命令时:

读取 Makefile:默认读取当前目录下的 Makefile 或 makefile 文件。
确定目标:如果未指定目标,默认使用第一个目标(通常是 all)。
检查依赖:递归检查目标的所有依赖是否需要更新。
如果依赖文件不存在或已过期(修改时间比目标新),则执行对应的命令重新生成。
如果依赖是其他目标,会先处理该目标。
执行命令:仅当依赖更新或目标不存在时执行命令。

基本规则

目标: 依赖1 依赖2 ...
<Tab>命令1
<Tab>命令2

app: main.o utils.o
    gcc main.o utils.o -o app

使用过程:

1.一次编译

2.分步编译

删除文件

此时我们要删除.i .s .o和add文件,我们可以用rm指令一个一个删除,我们也可以在makefile里再加一个目标文件

此时在shell命令行执行make clean指令

即可删除对应文件

但是如果当前目录下的文件里有名字为clean的文件则不能使用

此时我们需要使用PHONY目标

PHONY的作用:

1.避免和同名文件冲突

2.改善性能

变量的创建和使用

创建变量的目的

1.提升代码可维护性
借助变量能够避免在 Makefile 里重复书写相同的内容。要是后续需要对某个值进行修改,仅需改动变量的定义之处即可。
2.实现代码复用
可以把常用的值或者命令定义成变量,在多个地方重复使用。
3.便于条件编译
通过变量可以灵活控制编译过程,比如针对不同的环境或者目标进行编译。

1.预定义变量
Makefile 内置了一些系统变量:

CC:默认的 C 编译器(通常是cc)
CXX:默认的 C++ 编译器(通常是g++)
RM:默认的删除命令,只能删除文件不能删除目录(通常是rm -f)

CFLAGS    C 编译器的选项(如-Wall -O2)
CXXFLAGS    C++ 编译器的选项
CPPFLAGS    C/C++ 预处理器的选项(如-I/include)
FFLAGS    Fortran 编译器的选项
LDFLAGS    链接器的选项(如-L/lib)
LIBS    链接时需要的库(如-lm -lpthread)
ARFLAGS    创建静态库时的选项(如rcs)

此时我们可用cc编译器来生成add和add.o文件,用RM来删除文件

用变量代替参数-c

2.自定义变量

自己定义的变量

此时cc不是cc编译器,还是gcc编译器

3.自动变量

几个常见的自动变量

$*     不包含扩展名的目标文件名称    
$+    所有的依赖文件,以空格分开,并以出现的先后为序,可能包    
含重复的依赖文件
$<    第一个依赖文件的名称
$?    所有时间戳比目标文件晚的的依赖文件,并以空格分开    
$@  目标文件的完整名称
$^    所有不重复的目标依赖文件,以空格分开
$%   如果目标是归档成员,则该变量表示目标的归档成员名称


  此时我们创建三个文件

我们怎么把这三个.c文件编译生成一个可执行文件呢

如果不用自动变量的话:

使用自动变量:

至此可以应付一些简单的项目了,makefile高级使用的笔记内容后面再补充吧~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值