常见makefile语法

1.指定头文件目录
(1)系统目录
(2)可以指定 -i的大写

2.库文件在哪
(1)系统目录,工具链
(2)自已指定的库文件目录 -L
(3)指定库文件 -l

1.Makefile
规则:
目标文件:依赖文件(当依赖比目标新)

Test: a.o b.o
gcc -o test a.o b.o 
a.o : a.c
gcc -c -o a.o a.c
b.o : b.c
gcc -c -o b.o b.c 

Makefile其实挺简单
一个简单的Makefile文件包含一系列的“规则”,其样式如下:

目标(target): 依赖(prerequiries)<tab>命令(command)

如果“依赖文件”比“目标文件”更加新,那么执行“命令”来重新生成“目标文件”。
命令被执行的2个条件:依赖文件比目标文件新,或是 目标文件还没生成。
先介绍Makefile的2个函数

A.  $(foreach var,list,text)

简单地说,就是 for each var in list, change it to text。
对list中的每一个元素,取出来赋给var,然后把var改为text所描述的形式。
例子:

objs := a.o b.o
dep_files := $(foreach  f,  $(objs),  .$(f).d)  // 最终 dep_files := .a.o.d .b.o.d
B.  $(wildcard pattern)

pattern所列出的文件是否存在,把存在的文件都列出来。
例子:

src_files := $( wildcard  *.c)  // 最终 src_files中列出了当前目录下的所有.c文件

2.Makefile语法

A.通配符:%.o
$@ 表示目标
$< 表示第一个依赖
$^ 表示所有依赖文件
test: a.o b.o c.o
gcc -o test $^
%.o : %.c
gcc -c -o $@ $< 
clean:
rm  *.o  test
.PHONY  clean把clean设为假想目标

即时变量,延时变量,export

A :=  XXX  #A的值即可确定 
B =   xxx  #B的值使用才确定
?= 延时变量,只有第一次起效
+=   #附加,它是即时还是附加取决前面的定义
A  :=  $(C)
B  =  $(C)引用
C  =  123
All:
@echo $(A)  引用
@echo $(B)

2.makefile函数
(1).

A = a b c
B = $(foreach  f,  $(A),  $(f).o) 
all:
@echo  B  =  $(B)

(2).

$(filter pattern..,text) 在text中取出符合patten格式的值
$(filter-out   pattern..,text) 在text中取出不符合patten格式的值
$(wildcard pattern)  #pattern定义文件格式,wildcard取出其中存在文件

比如:
C =a b c d
D =$(filter %/, ( c ) ) E = (c)) E = (c))E=(fileter-out %/, $©)从中取出

files = $(wildcard *.c)

all:
@echo B = $(B)
@echo D = $(D)
@ECHO E = $(E)
@echo files = $(files)

$(patsubst pattern, replacement, $(var))) 取出来做些替换

命令:
gcc -c -o c.o c.c -MD -MF c.d既生成C.O又生成依赖文件

objs = a.o b.o c.o

dep_files := $(patsubst %,.%.d, $(objs))
dep_files := $(wildcard $(dep_files))

CFLAGS = -Werror -Iinclude

test: $(objs)
gcc -o test $^

ifneq ($(dep_files),)
include $(dep_files)
endif

%.o : %.c
gcc $(CFLAGS) -c -o $@ < − M D − M F . < -MD -MF . <MDMF.@.d

clean:
rm *.o test

distclean:
rm $(dep_files)

.PHONY: clean

编译驱动makefile示例

# 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 =  /home/book/100ask_stm32mp157_pro-sdk/Linux-5.4
KERN_DIR =  /home/book/100ask_imx6ull-sdk/Linux-4.9.88

all:
	make -C $(KERN_DIR) M=`pwd` modules 
	$(CROSS_COMPILE)gcc -o oled_test oled_test.c
clean:
	make -C $(KERN_DIR) M=`pwd` modules clean
	rm -rf modules.order   oled_test

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



obj-m += oled_drv.o

通用Makefile的使用
① 零星知识点
A. make命令的使用:
执行make命令时,它会去当前目录下查找名为“Makefile”的文件,并根据它的指示去执行操作,生成第一个目标。
我们可以使用“-f”选项指定文件,不再使用名为“Makefile”的文件,比如:

make  -f  Makefile.build 

我们可以使用“-C”选项指定目录,切换到其他目录里去,比如:

make -C  a/  -f  Makefile.build 

我们可以指定目标,不再默认生成第一个目标:

make -C  a/  -f  Makefile.build   other_target

B. 即时变量、延时变量:
变量的定义语法形式如下:

A  =  xxx   // 延时变量
B  ?= xxx    // 空赋值,只有第一次定义时赋值才成功;如果曾定义过,此赋值无效
C  := xxx    // 立即变量
D  += yyy   // 如果D在前面是延时变量,那么现在它还是延时变量;
// 如果D在前面是立即变量,那么现在它还是立即变量

在GNU make中对变量的赋值有两种方式:延时变量、立即变量。

上图中,变量A是延时变量,它的值在使用时才展开、才确定。比如:
A = $@
test:
@echo $A
上述Makefile中,变量A的值在执行时才确定,它等于test,是延时变量。
如果使用“A := @ ” , 这 是 立 即 变 量 , 这 时 @”,这是立即变量,这时 @@为空,所以A的值就是空。
C. 变量的导出(export):
在编译程序时,我们会不断地使用“make -C dir”切换到其他目录,执行其他目录里的Makefile。如果想让某个变量的值在所有目录中都可见,要把它export出来。
比如“CC = $(CROSS_COMPILE)gcc”,这个CC变量表示编译器,在整个过程中都是一样的。定义它之后,要使用“export CC”把它导出来。
② 通用Makefile的设计思想
A. 在Makefile文件中确定要编译的文件、目录,比如:

obj-y += main.o
obj-y += a/

“Makefile”文件总是被“Makefile.build”包含的。

B. 在Makefile.build中设置编译规则,有3条编译规则:
i. 怎么编译子目录? 进入子目录编译:

$(subdir-y):
	make -C $@ -f $(TOPDIR)/Makefile.build

ii. 怎么编译当前目录中的文件?

%.o : %.c
	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -Wp,-MD,$(dep_file) -c -o $@ $<

iii. 当前目录下的.o和子目录下的built-in.o要打包起来:

built-in.o : $(cur_objs) $(subdir_objs)
	$(LD) -r -o $@ $^

C. 顶层Makefile中把顶层目录的built-in.o链接成APP:

$(TARGET) : built-in.o
	$(CC) $(LDFLAGS) -o $(TARGET) built-in.o
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吴凯你在想啥呢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值