博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Makefile研究 (一)—— 必备语法
阅读量:4352 次
发布时间:2019-06-07

本文共 3859 字,大约阅读时间需要 12 分钟。

摘自:

参考文档:

参考文档:

  以前在windows上学习单片机、ARM的时候都是用IDE去管理编译代码,很多时候都不知道各个程序之间是怎么编译成可执行文件的,只要点下鼠标就可以了。虽然自己也有学习linux以及uboot 但都是看看改改程序。对于makefile认识也是单文件小工程的。认为makefile就是个编译工具,没必要深究。随着阅读的代码量的增多,发现,对于理解一些源码框架比如u-boot、inux 、andriod,要是看不懂makefile理解起来比较困难。而且在嵌入式系统开发中,考虑功能的模块化和可移植性,makefile是一个绕不过的东西。最近一次工作经历深深地刺激了我。是这样,我之前已经完整编译了整个工程,后面修改了某个配置文件,执行make 总是提示那个配置的东西不存在。即使make clean后再make还是会报一堆不知名的错误,我意识到makefile某些编译项用的是未改前的配置,现在有冲突了,当然会报错,这个系统是我们公司开发的有十几万个文件,每次编译都要二十多分钟,我当天一直查这个问题到11:00,伤心地回了家。第二天我默默地从服务器上重新下载新的code,直接修改配置文件,直接make正如我所料一次性编译通过。

        果然是该死的makefile第一次编译ok,修改配置文件,第二次编写就把代码编坏了。这种情况我相信很多搞程序的都遇到过,其实在此前就发现makefile不怎么完美,我经常添加模块还要去修改多个makefile才能使得添加的模块编译进去。跟进的项目终于接近尾声,决心好好研究下。

makefile 其实也是编程语言,他只是编译工具语言,也有语法,个人觉得我们实际应用中掌握常用的语法就好了下面是我总结的常用的Makefile语法。

一、Makefile 中的赋值方法

=    递归赋值 可以向后引用变量

:= 简单扩展 只能引用前面的变量

?= 如果没有赋值 则赋值一次

+=  在原来的基础上添加赋值变量

一个例子说明

1 x = before   2 y = $(x)   3 x = later   4    5 xx = before   6 yy := $(xx)   7 xx = later   8    9 xxx = before  10 xxx ?= later  11   12 yyy ?= before  13 yyy = later  14   15 x += last  16   17 all :  18     @echo "x=" $(x)  19     @echo "y=" $(y)  20     @echo "xx=" $(xx)  21     @echo "yy=" $(yy)  22     @echo "xxx=" $(xxx)  23     @echo "yyy=" $(yyy)

输出是

 x= later last

y= later last

xx=later

yy=before

xxx=before

yyy=later

 

二、Makefile 自动变量

所谓自动化变量,就是这种变量会把模式中所定义的一系列的文件自动地挨个取出,直至所有的符合模式的文件都取完了。这种自动化变量只应出现在规则的命令中。

下面是所有的自动化变量及其说明:

$@  

  表示规则中的目标文件集。在模式规则中,如果有多个目标,那么,"$@"就是匹配于目标中模式定义的集合。

$%

  仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是"foo.a(bar.o)",那么,"$%"就是 "bar.o","$@"就是"foo.a"。如果目标不是函数库文件(Unix下是[.a],Windows下是[.lib]),那么,其值为空。

$<

  依赖目标中的第一个目标名字。如果依赖目标是以模式(即"%")定义的,那么"$<"将是符合模式的一系列的文件集。注意,其是一个一个取出来的。

$^

  所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。

$?

  所有比目标新的依赖目标的集合。以空格分隔。

$+
这个变量很像"$^",也是所有依赖目标的集合。只是它不去除重复的依赖目标。
$*
这个变量表示目标模式中"%"及其之前的部分。如果目标是"dir/a.foo.b",并且目标的模式是"a.%.b",那么,"$*"的值就是"dir/a.foo"。这个变量对于构造有关联的文件名是比较有用。如果目标中没有模式的定义,那么"$*"也就不能被推导出,但是,如果目标文件的后缀是make所识别的,那么"$*"就是除了后缀的那一部分。例如:如果目标是"foo.c",因为".c"是make所能识别的后缀名,所以," $*"的值就是"foo"。这个特性是GNU make的,很有可能不兼容于其它版本的make,所以,你应该尽量避免使用"$*",除非是在隐含规则或是静态模式中。如果目标中的后缀是make所不能识别的,那么"$*"就是空值。
1 test.o : test1.c test2.c  2           @echo $@  3           @echo $<  4           @echo $^

结果为

test.o

test1.c

test1.c test2.c

三、Makefile中的常用函数

1、文本替换 函数 $(subst ma,   wo   ,hello world!!)

将hello world!! 中间的wo 替换成ma

结果为  hello marld!!

 

2、格式替换函数 $(patsubst %.c ,%.o , test.c test1.c test2.c)

将.c 的格式替换成.o

结果为 test.o test1.o test2.o

 

3、去掉空格函数 $(strip a    b               c)

结果 a b c

4、字符串查找函数

$(findstring a,a b c d)

在字符串a b c d 中查找 a  ,找到就返回查到的值 ,否则为 "  "

上面结果为 a

 

5、格式匹配过滤函数 $(filter %.c %.s , mod1.c mod2.o mod3.s mod4.h)

查找格式是%.c 和 %.s 的文件

结果为 mod1.c mod2.s

 

6、格式不匹配函数 $(filter-out %.c %.s, mod1.c mod2.o mod3.s mod4.h)

它的和filter相反

结果为 mod2.o mod4.h

 

7、$(sort  hello  world branck)

按字母排列

结果为  branck hello world

 

8 、抽取文件目录函数$( dir source/hello.c inc/hello.h mksh)

结果: source/  inc/  ./

 

9、抽取文件名函数 $(nodir source/hello.c inc/hello.h mksh)

结果: hello.c hello.h mksh

 

10、提取文件名后缀函数 $(suffix source/hello.c inc/hello.h mksh)

结果: .c  .h

 

11、去除后缀名函数 $(basename sourc/hello.c inc/hello.h mksh)

结果: source/hello   inc/hello mksh

 

12、添加后缀名函数 $(addsuffix .c ,hello fun)

结果: hello.c fun.c

 

13、添加前缀函数 $(addprefix source/ , mod1.c mod2.c mod3.c)

结果: source/mod1.c source/mod2.c source/mod3.c

 

14、格式匹配函数 $(wildcard  source/*.c)

查找source 目录下所有.c 文件

 

15、格式匹配用法

SRCS = mod1.c mod2.c mod3.c

$(SRCS : %.c = %.o)

结果为mod1.o mod2.o mod3.o

 

16、目录循环搜索

dirs :=  dir1 dir2 dir3 dir4

files := $( foreach dir ,$(dirs) ,$(wildcard $(dir)/*)

查找 目录 dir1 dir2 dir3 dir4 目录下所有的文件。

 

17、在Makefile 中执行shell 脚本的方法

$(shell command)

SRCS := $(shell ls *.c)

则srcs 中所有的c程序。

 

四、Makefile 中的编译基础知识

1、编译时 指定头文件路径 用 -I

2、编译时 指定库路径用 -L 指定函数库名 用 -l (小写L )

3、在Makefile 指定宏定义 配置到程序中 -D

 

五、条件判断语句

1、ifdef/ifndf  (param)

       endif    

#    param  是否定义

2、ifeq/ifneq (a,b)

       endif  

#  a和b是否相等

我想Makefile 的基础知识掌握这些就ok了,关键是应用。

 

转载于:https://www.cnblogs.com/computer1-2-3/p/7589204.html

你可能感兴趣的文章
庆祝我国人民自主研发多叉转二叉成功
查看>>
EasyCodeScanner生成二维码
查看>>
ABP框架
查看>>
python文件操作
查看>>
10分钟 教你学会Linux/Unix下的vi文本编辑器
查看>>
洛谷 - P4997 - 不围棋 - 并查集 - 模拟
查看>>
关于值传递和引用传递的一些小笔记
查看>>
TAB + 滚动 + 时间间隔点击
查看>>
个人博客3-微软必应词典客户端的案例分析
查看>>
修改oracle密码
查看>>
第四百八十三天 how can I 坚持
查看>>
Packetbeat协议扩展开发教程(2)
查看>>
深入tornado中的http1connection
查看>>
Python开发【第九篇】:协程、异步IO
查看>>
Codeforces Round #243 (Div. 2)——Sereja and Table
查看>>
排序算法之堆排序
查看>>
什么是Pro*C/C++,嵌入式SQL,第一个pro*c程序,pro*c++,Makefile,Proc增删改查
查看>>
给久坐族的10个保健建议
查看>>
RedHat9.0下载地址
查看>>
走势终完美 --执子之手
查看>>