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

【Linux】Makefile

Makefile常用用法介绍。

部分图片和经验来源于网络,还有正点原子的Linux驱动开发教程,若有侵权麻烦联系我删除,主要是做笔记的时候忘记写来源了,做完笔记很久才写博客。

 专栏目录:记录自己的嵌入式学习之路-CSDN博客


1    简单定义

        Makefile是一个包含了一系列指令的文件,这些指令定义了如何编译和链接程序。Makefile被make命令使用,make是一个构建自动化工具,它根据Makefile中定义的规则来决定哪些文件需要重新编译。


2    基本结构

        一个基本的Makefile包含以下部分:

        (1)    目标(Targets):通常是文件名,表示要生成的文件。

        (2)    依赖(Dependencies):目标文件依赖的文件列表。

        (3)    命令(Commands):生成目标文件需要执行的命令序列。

        

这个Makefile做了以下几件事:

  • 定义了一个名为all的伪目标,它依赖于hello目标。
  • hello目标依赖于hello.o文件,并且定义了如何从hello.o生成hello可执行文件。
  • hello.o目标依赖于hello.c源文件,并且定义了如何从hello.c编译生成hello.o对象文件。

编译时使用make all命令,这个命令告诉make去查找Makefile,并执行all目标下的指令。make会检查文件的修改时间,如果hello.o或hello.c被修改过,它会重新编译这些文件。


3    MAKEFILE中的变量

3.1    变量的赋值

(1)    = 赋值

        = 赋值相当地址赋值,每次拿出来的值都以最新的值为准,如下图打印的值应该为zuozhongkai。

        

(2)    := 赋值

        := 赋值就是正常的赋值,以赋值时候的值为准,如下图的结果就是zzk。

        

(3)    ?= 赋值

        curname ?= zuozhongkai

        上述代码的意思就是,如果变量curname前面没有被赋值,那么此变量就是“zuozhongkai”,如果前面已经赋过值了,那么就使用前面赋的值。

(4)    += 追加赋值

3.2    变量的引用

        在Makefile中,变量通过$(变量名)来引用。

        

3.3    自动化变量

        

3.4    CC变量

        CC变量存储编译器的名称,值通常为gcc。

        

3.5    CFLAGS变量

        CFLAGS变量用于存储编译选项。

        


4    模式规则

        目标中的“%”表示对文件名的匹配,“%”表示长度任意的非空字符串,比如“%.c”就是所有的以.c结尾的文件,类似与通配符,a.%.c就表示以a.开头,以.c结束的所有文件。

        当“%”出现在目标中的时候,目标中“%”所代表的值决定了依赖中的“%”值。

        模式规则基本都要配合自动化变量才能够使用。因为文件名一直在变化。


5    伪目标

        若有非编译的命令,如clean、all等,最好将其声明为伪目标,语法如下:

        .PHONY : clean

        使用伪目标可以避免文件中有同名文件时出现的问题:当目录中有一个文件就叫clean,那么如果没有声明伪目标,clean下的命令就因为clean没有依赖文件变化而不运行。加了伪目标就可以保证clean一定运行。


6    条件语句

        Makefile中的条件语句有ifeq、ifneq、ifdef、ifndef。其中ifeq用来比较两值是否相等,有n的就是比较其是否不相等。

        


7    Kbuild

        Kbuild是Linux内核的官方构建系统,它基于GNU Make。Kbuild通过预定义一系列的变量和目标,使得内核的编译和模块的构建变得简单。

7.1    核心变量

(1)    obj-y:用于定义编译进内核的目标文件(.o文件)。如果一个文件被添加到obj-y,它将被编译并链接到最终的内核映像中。

(2)    obj-m:用于定义编译成模块的目标文件。这些文件将被编译成.ko文件,可以作为模块加载到内核中。

(3)    <user_prog>-y或<user_prog>-objs:表示<user_prog>的依赖为后面的内容。如:

obj-m := led.o
led-y := hello.o leddriver.o

上面的语句表示最终要编译led.ko这个模块,而这个模块由hello.c和leddriver.c两个编译出来。实际上led.c反而是不需要存在的。

注:要想其编译一些别的文件夹下的源文件,可以加上路径,例如:

MODULE_NAME := ../../out/adc
KERN_DIR := /home/<user_name>/Source/kernel_source_emmc_flash
obj-m := $(MODULE_NAME).o
$(MODULE_NAME)-objs := adc_driver.o ../Utilities/utility.o

7.2    make过程中的常用参数

        -C <path>:表示在编译前先将当前工作目录改到path路径,一般path都是内核源码的路径。我的理解是相当于跳转到内核源码里面,引用它里面的Makefile。

        M=<path>:这个表示要编译的模块的源码,就是说告诉make,我要编译的模块的源码是path。若不给出O=<path>,那么默认编译得到的.o/.ko文件将被放到M指定的模块源码路径中。

        O=<path>:指定输出文件的路径。

        module:make命令后加上module表示将Makefile文件中obj-m的部分编译了,同时编译那些依赖于obj-m的obj-y文件,不依赖于obj-m的不编译,应该是这样。要是直接执行make,不加module的话只会编译obj-y的目标文件。

        ARCH=<arch>:指定目标平台的架构,arch为arm时说明目标架构为arm。

        CROSS_COMPILE:交叉编译器的前缀,指定了使用哪些交叉编译器工具链。

其实ARCHCROSS_COMPILE两个都可以直接在Makefile中直接指定,而不是在使用make命令的时候指定。

其实,无论是O=、M=、ARCH=还是CROSS_COMPILE=,本质上只是在命令行中指定Makefile文件中指定变量的值而已,和在Makefile文件中修改区别不大,但是Makefile可以通过ifeq ("$(origin O)", "command line")来判断这个值是否来自于命令行的指定。


8    Makefile技巧

8.1    无视错误继续执行

        若某些命令哪怕错误也要继续执行下面的任务,就在这个命令前加上“-”,如:

all:-make cleanecho “无论前面是否执行成功都会输出这行”

8.2    利用命令的输出

        $(shell <cmd>)

        这样得出来的就是命令的输出值,就像$(shell pwd)得到的就是执行pwd的结果,即当前路径。

8.3    三元if函数

        $(if <condition>, <then-part>, <else-part>)

8.4    替换函数

        $(patsubst <pattern>,<replacement>,<text>)

        此函数用于在 text中查找符合 pattern的部分,如果匹配的话就用 replacement替换掉。pattern是可以包含通配符“%”,如果 replacement 中也包含通配符“%”,那么 replacement 中的这个“%”将是 pattern中的那个“%”所代表的字符串。

        【注意】:千万不要在任何,后面加空格,会被视为内容的一部分。

8.5    数值的硬拼接

        CUR_DIR := $(shell pwd)/..

        相当于给路径加了个/..,需要注意的是/前面千万不能有空格,不然就相当于拼接多了一个空格。

8.6    数值的项目增加

        PHONY += AAA

        PHONY += BBB

        就是将不同的项目合起来在一起,最后PHONY的值就是“AAA BBB”

8.7    项目Make编译的常见清理命令

(1)    make clean

        这个目标通常用于删除大多数生成的文件,但保留一些基础文件,以便可以快速重新构建项目,特别是外部模块。

        通常保留的文件包括配置脚本生成的配置文件,因为重新生成这些文件可能需要用户输入或复杂的检测过程。

        make clean 旨在减少构建准备时间,同时避免删除需要额外工作才能重新生成的文件。

(2)    make mrproper

        这个目标删除当前配置的所有生成文件,包括make clean保留的文件。

        mrproper 通常删除所有由配置过程生成的文件,如配置日志和 config.h 文件,这意味着你需要重新运行配置脚本来重新生成这些文件。

        这个目标用于确保构建过程从完全干净的状态开始,没有任何旧的构建生成的文件。

(3)    make distclean

        这个目标除了执行make mrproper的操作外,还会删除额外的文件,如编辑器备份文件、补丁应用后的遗留文件等。

        distclean 旨在确保分发包(tarball)中的文件在提取后,构建环境与原始开发者的构建环境完全一致。

这个目标用于维护一个干净的源代码树,准备进行版本控制更新或分发源代码。


9    其他注意事项

        命令列表中的每条命令必须以TAB键开始,不能使用空格!


10   其他注意事项

        一些优秀的Makefile相关博客:

linux内核模块编译makefile - 裸睡的猪 - 博客园https://www.cnblogs.com/ggzhangxiaochao/p/13358941.htmlmake命令的参数选项(执行make时可以添加哪些选项)_make 参数-CSDN博客https://blog.csdn.net/oqqHuTu12345678/article/details/125630342

http://www.xdnf.cn/news/245377.html

相关文章:

  • 小结:ipsec-ike
  • 例数据中关键指标对应的SQL查询模板
  • mysql数据库备份与恢复方法
  • Java学习手册:Spring 事务管理
  • 面试的各种类型
  • Linux日常使用与运维的AI工具全景调研:效率革命的终极指南
  • (A题|支路车流量推测问题)2025年第二十二届五一数学建模竞赛(五一杯/五一赛)解题思路|完整代码论文集合
  • 【Dify系列教程重置精品版】第五章:Dify配置Ollama
  • C++漫溯键值的长河:map set
  • ES6-Set-Map对象小记
  • 业务流程BPM能力框架体系及华为中兴流程变革案例P83(83页PPT)(文末有下载方式)
  • 信息系统项目管理师-软考高级(软考高项)​​​​​​​​​​​2025最新(六)
  • 初识 Java
  • OpenGL-ES 学习(12) ---- VBO EBO VAO
  • 网络分析/
  • 前端如何转后端
  • 【Docker】Dockerfile 使用
  • 【AI大模型学习路线】第一阶段之大模型开发基础——第二章(大模型的训练与应用)大模型发展史?大模型预训练、微调到应用的过程?
  • 【小米拥抱开源】小米开源 MiMo 家族,探索 Reasoning 的可能性
  • Chromium 134 编译指南 - Android 篇:获取源码(五)
  • 为 Unity 项目添加自定义 USB HID 设备支持 (适用于 PC 和 Android/VR)-任何手柄、无人机手柄、摇杆、方向盘
  • 聊一聊接口测试如何处理鉴权
  • terraform中statefile文件的实现原理及作用
  • 模型开发之前的核心工作
  • 数据结构学习之顺序表
  • 基于开源链动2+1模式AI智能名片S2B2C商城小程序的个性化与小众化消费社群构建研究
  • KDD 2025 | (8月轮)时空数据(Spatial-temporal)论文总结
  • 如何用AI生成生成个人简历
  • 浅析 MegEngine 对 DTR 的实现与改进
  • 【docker学习笔记】如何删除镜像启动默认命令