栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Makefile 随记

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Makefile 随记

Makefile 随记

文章目录

Makefile 随记

introduction-引言基础使用变量赋值及通配符常用函数

$(wildcard <指定格式>) 查找匹配格式$(patsubst %.c,%.o,main.c obj.c) 替换(notdir ./dir/main.c) 去除路径信息-I./inc 指定同文件$(addsuffix SUFFIX,NAMES...) 批量追加后缀include 包含其它文件$(foreach var,list,operate) 循环遍历+操作$(call operate,param1,param2,...) 自定义函数 内核Makefile

introduction-引言

本文为本人学习Linux中Makefile时所记录的笔记,该笔记参考的B站或微信公众号有:韦东山、野火、正点原子、一口Linux、简说linux等。
Makefile文件是Linux环境下用记录并配置文件间依赖关系和编译规则的文件,一般该文件命名为Makefile,配置好后,在终端输入make命令便默认执行名为Makefile的文件,若要执行别名的文件则在终端中输入make -f <文件名>。

基础使用

makefile代码的三要素为:目标文件、依赖文件、命令。

例1

#注释文本
test:main.o obj.o
	gcc main.o obj.o -o test
main.o:main.c
	gcc main.c -o main.o
obj.o:obj.c
	gcc obj.c -o obj.o
.PHONY:clear
clear:
	@rm -rf test

例1中从第一行开始,test为要生成的目标文件,main.o、obj.o为生成目标文件所需要的依赖文件,gcc main.o obj.o -o test为生成目标文件所要执行的命令。

当依赖文件不存在时,便会寻找依赖文件所需要的依赖,程序便先执行了main.o:main.c和obj.o:obj.c生成依赖文件,再执行第一行的代码。而.PHONY:clear是为了声明clear是一个伪目标,也就是不不需要依赖,相当与一条命令而已。输入make生成可执行文件test,输入make clear执行rm -rf test语句,删除test文件,@的作用是取消回显文本。

变量赋值及通配符

一些在开发中常用的变量名:CC表示编译器,AS表示汇编,MAKE表示make工具,当然用户的变量名是随便取的,上述三个变量名仅是开发者命名的规范而已,变量的定义要放在最前面。

变量的通配符:

${变量名}:引用Makefile文件中变量$<:表示第一个依赖文件$^:表示所有的依赖文件$@:表示生成的目标文件$$:扩展打开Makefile中定义的shell变量

变量的赋值(3种):

延时赋值=:变量被引用时才开始赋值,立即赋值:=:变量会被立即赋值,无需等到被引用时空赋值?=:变量为空时才能赋值,一旦变量被赋值了,就无法用该符号赋值追加赋值+=:在原来的值末尾附加上新值。

例2:

CC=gcc
TARGET:=test
OBJS:=main.c obj.c

${TARGET}:${OBJS}
	${CC} $^ -o $@

常用函数 $(wildcard <指定格式>) 查找匹配格式

列出所有符合指定格式的文件,可通过一些shell的一些通配符指定格式。

例3:列出所有.c结尾的文件

data:=$(wildcard *.c)
#或
data:=$(wildcard %.c)

$(patsubst %.c,%.o,main.c obj.c) 替换

指定字符替换为另外的字符

例4:把含.c结尾的参数替换为.o结尾

data:=$(patsubst %.c,%.o,main.c obj.c)
#把参数 main.c obj.c 替换为 main.o obj.o

(notdir ./dir/main.c) 去除路径信息

去除文件名中的路径信息。

例5:

DOC=( notdir ./dir/main.c )
#去除路径信息,只得到main.c

-I./inc 指定同文件

通过-I ./inc指定头文件路径为./inc

SRC=main.c
INC=-I./inc
test:main.c
	gcc -c ${INC} ${SRC}
#gcc -c 编译汇编不连接,生成.o文件

$(addsuffix SUFFIX,NAMES…) 批量追加后缀

SUFFIX为后缀名,NAMES…为文件名

例6:

DOC:=$(addsuffix .c,text1 text2)
#DOC=text1.c text2.c

include 包含其它文件

用法类似与C语言的#include "xxx.h"。

例7:

include file.h

$(foreach var,list,operate) 循环遍历+操作

list中的变量会被依次赋值到临时变量var,然后根据operate操作var,但list值读完后,函数返回一串operate后的变量。

注意:var在函数执行后将会释放,函数返回的是新的字符串,旧的字符串list不变。

例8

old := a b c d
new := $(foreach n,${old},${n}.o)

最后,新变量为:new=a.o b.o c.o d.o,而旧变量为:old=a b c d不变。


$(call operate,param1,param2,…) 自定义函数

把参数param1、param2传入到操作opeate中,并返回操作后的值。

例9

ope = $(2)$(1)
ret = $(call ope,p1,p2)
all:
	@echo "ret=$(ret)"

最后执行结果为ret=p2p1。

其中all表示默认目标,也可以理解为指定第一个依赖,起到指定程序开始执行位置的作用


内核Makefile
#B站 简说Linux视频源码,仅用于利用内核编译出.KO文件
ifneq($(KERNELRELEASE),)
obj-m := helloDEV.O
else
PWD := $(shell pwd)
KDIR := /home/linux-4.9.229
all:
	make -C $(KDIR) M=$(PWD)
clean:
	rm -rf *.o *.ko *.mod.c *.symvers *.c~ *~
endif

程序进入后,

    执行ifneq($(KERNELRELEASE),),判断KERNELRELEASE是否为空,KERNELRELEASE是内核源码中的一个变量,第一次进入是为空。为空,则进入else部分,在else中,PWD变量获取当前编译的路径,KDIR获取内核源码的路径,然后执行all下的命令make -C $(KDIR) M=$(PWD),其中-C表示先进入到内核路径KDIR下先执行内核的Makefile文件,编译后,定义了KERNELRELEASE,且不为空,然后通过M=$(PWD)回到PWD变量指定的目录下执行该目录下的Makefile文件。再次进入该Makefile文件时,KERNELRELEASE不等空,执行obj-m := helloDEV.O,此语句用与内核的编译系统识别的*(内核编译系统:由内核源码中的众多Makefile文件组成)*。内核编译系统会把所有obj-m选项的文件编译成.KO文件。

韦东山例程编写的Makefile,它同时编译出了应用层的可执行文件*(通过arm-linux-gcc编译),和驱动程序.KO文件(主要通过obj-m += leddrv.o编译)*。

# 1. 使用不同的开发板内核时, 一定要修改KERN_DIR
# 2. KERN_DIR中的内核要事先配置、编译, 为了能编译内核, 要先设置下列环境变量:
# 2.1 ARCH,          比如: export ARCH=arm64
# 2.2 CROSS_COMPILE, 比如: export CROSS_COMPILE=aarch64-linux-gnu-
# 2.3 PATH,          比如: export PATH=$PATH:/home/book/100ask_roc-rk3399-pc/ToolChain-6.3.1/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin 
# 注意: 不同的开发板不同的编译器上述3个环境变量不一定相同,
#       请参考各开发板的高级用户使用手册

KERN_DIR = # 板子所用内核源码的目录

all:
	make -C $(KERN_DIR) M=`pwd` modules 
	$(CROSS_COMPILE)gcc -o ledtest ledtest.c 

clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order
	rm -f ledtest

# 参考内核源码drivers/char/ipmi/Makefile
# 要想把a.c, b.c编译成ab.ko, 可以这样指定:
# ab-y := a.o b.o
# obj-m += ab.o



obj-m += leddrv.o
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/729496.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号