参考视频:Linux 的make自动化编译和通用makefile_哔哩哔哩_bilibili

编译Android或Linux源码时,我们会发现串口输入命令make后就会开始自动编译。

make命令通过一个称为makefile的文件来完成并自动维护编译工作。输入make指令后将自动寻找当前目录下的makefile(或Makefile)文件并解析它完成编译工作,故我们需要重点理解makefile文件的语法。

目录

一、C文件单编命令

二、makefile基本语法

三、make是如何工作的

四、编写一个简单的makefile文件

五、makefile使用伪目标

六、make自动化变量

七、make自动推导

八、makefile中常见函数

九、使用变量修改自动推导的gcc编译命令

十、通用makefile的其他写法


一、C文件单编命令

命令:gcc [options] [filenames]

其中options就是编译器所需要的参数,filenames给出相关的文件名称。

-c,只编译,不链接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。

-o output_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。

-g,产生符号调试工具(GNU的gdb)所必要的符号资讯,要想对源代码进行调试,我们就必须加入这个选项。

-O,对程序进行优化编译、链接,采用这个选项,整个源代码会在编译、链接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是,编译、链接的速度就相应地要慢一些。

-O2,比-O更好的优化编译、链接,当然整个编译、链接过程会更慢。

-Idirname,将dirname所指出的目录加入到程序头文件目录列表中,是在预编译过程中使用的参数。C程序中的头文件包含两种情况∶

A)#include <myinc.h>

B)#include “myinc.h”

其中,A类使用尖括号(< >),B类使用双引号(“ ”)。对于A类,预处理程序cpp在系统预设包含文件目录(如/usr/include)中搜寻相应的文件,而B类,预处理程序在目标文件的文件夹内搜索相应文件。

-v gcc执行时执行的详细过程,gcc及其相关程序的版本号

举例:

gcc -c main.c -o main.o        //编译main.c生成可执行文件main.o

gcc main.o add.o subtract.o -o main        //将多个文件生成一个目标可执行文件main

二、makefile基本语法

举例:

三、make是如何工作的

1、make会在当前目录下找名字叫“Makefile"或“makefile”

2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“main”这个文件,并把这个文件作为最终的目标文件。

3、如果main文件不存在,或是main所依赖的后面的.o文件的文件修改时间要比main这个文件新,那么,他就会执行后面所定义的命令来生成main这个文件。

4、如果main所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。

5、当然,你的C文件和H文件是存在的啦,于是make会生成.o文件,然后再用.o文件make的终极任务,也就是执行文件main了。

注:如果DEPENDENCIES中有一个或多个文件更新的话COMMAND就要执行,这就是Makefile最核心的内容。

四、编写一个简单的makefile文件

释义:

1、最终生成的可执行目标文件:main

2、生成main所需要的其他文件:main.o stu.o

3、编译main.o所需要的文件:main.c stu.h

4、编译stu.o所需要的文件:stu.c stu.h

五、makefile使用伪目标

  • make命令不带参数时从第一目标文件开始执行,将依次执行生成第一目标文件所需要的目标文件。
  • make命令可以带参数,参数为makefile的任意目标文件,可单独执行生成该目标文件所需的指令。
  • make命令的参数可以是伪目标文件,伪目标文件指执行该目标文件的指令不生成该目标文件,仅用于执行单个指令使用。

举例:

释义:

  1. .PHONY作用是声明clean是伪目标。
  2. 输入make clean将执行命令:rm -f main.o stu.o main
  3. 不声明clean为伪目标(即没有.PHONY:clean这行)是可以的,但是当目录下有clean文件时可能会出现问题,make会报如下错误:

  • 其他常用伪目标:

六、make自动化变量

使用变量及自动化变量可优化makefile文件为:

七、make自动推导

  • GNU的make很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.0]文件后都写上类似的命令,因为,我们的make会自动识别,并自己推导命令。
  • 只要make看到一个[.0]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,那么whatever.c,就会是whatever.o的依赖文件。并gcc -c whatever.c也会被推导出来。

使用make自动推导可优化makefile文件为:

使用变量object继续优化为:

八、makefile中常见函数

使用函数查找所有[.c]文件并替换为[.o]文件可进一步优化makefile文件:

当查找的文件在多级子目录下呢?可以使用find命令查找到:

九、使用变量修改自动推导的gcc编译命令

以上优化后想要去掉编译指令:gcc $^ -0 $@ -llist

可以重定义CC变量,修改后为:

十、通用makefile的其他写法

释义:

shell ls -d */ 可以列出所有二级目录

SUBDIR记录二级目录名;ROOTOBJ记录所有一级目录下的[.o]文件;SUBOBJ记录所有二级目录下的[.o]文件

.c.o: 表示将所有[.c]编译成[.o],其指令直接看执行结果理解:

@D:目标目录;@F:目标文件;<F:第一依赖文件名

Logo

一站式 AI 云服务平台

更多推荐