摘自:http://blog.csdn.net/jundic/article/details/17535445

参考文档:http://blog.csdn.net/wrx1721267632/article/details/52840355

参考文档:http://wiki.ubuntu.org.cn/%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile:%E9%9A%90%E5%90%AB%E8%A7%84%E5%88%99

  以前在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 中的赋值方法

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

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

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

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

一个例子说明

 x = before
y = $(x)
x = later xx = before
yy := $(xx)
xx = later xxx = before
xxx ?= later yyy ?= before
yyy = later x += last all :
@echo "x=" $(x)
@echo "y=" $(y)
@echo "xx=" $(xx)
@echo "yy=" $(yy)
@echo "xxx=" $(xxx)
@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所不能识别的,那么"$*"就是空值。
 test.o : test1.c test2.c
@echo $@
@echo $<
@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了,关键是应用。

Makefile研究 (一)—— 必备语法的更多相关文章

  1. 老大写得一个非常高大上的Makefile,包括非常多语法:

    一个非常高大上的Makefile,包括非常多语法: TARGET = api-login INSTALL_PATH = /huishoubao/cgi include ../../implements ...

  2. makefile中的shell语法

    在Makefile中写shell代码有点诡异,和不同的shell语法不太一样,如果不了解,看Makefile会莫名其妙.下面总结了一些. 1:尽在Makefile文件的目标项冒号后的另起一行的代码才是 ...

  3. Makefile 入门与基本语法 分类: C/C++ ubuntu 2015-05-18 11:16 466人阅读 评论(0) 收藏

    在我看来,学会写简单的Makefile,阅读较复杂的makefile,是每一个Linux程序员都必须拥有的基本素质.Makefile可以自动识别哪些源文件被更改过,需要重新编译,那些不需要.从而节省大 ...

  4. 【 MAKEFILE 编程基础之二】MAKEFILE 书写规划以及语法规则!

    本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/gcc-makefile/768.html   ...

  5. Makefile研究(三) —— 实际应用

    转自:http://blog.csdn.net/jundic/article/details/17886637 前面讲了Makefile 的简单语法和简单的应用模板,但在实际项目应用中比这个肯定复杂很 ...

  6. C#入门中的必备语法(一)

    首先我们要知道C#语言是一种面向对象的语言由C和C++演变而来,它依赖于.NET Framework..NET Framework可以提供一个强大的代码库供其调用.之所以说C#语言依赖于.NET Fr ...

  7. Makefile研究(二)—— 完整可移植性模板

    转自:http://blog.csdn.net/jundic/article/details/17676461 一直想写一个很全很好移植的Makefile模板,我觉得一个完整makefile 应该包含 ...

  8. GNU autotools自动生成Makefile 介绍

    一.目的 使用autotools工具来帮助我们自动地生成符合自由软件惯例的makefile(这样就可以像常见的GNU程序一样,只要使用"./configure", "ma ...

  9. 内核顶层Makefile相关3

    http://www.groad.net/bbs/simple/?f104.html 伪目标 .PHONY是一个特殊工作目标(special target),它用来指定一个假想的工作目标,也就是说它后 ...

随机推荐

  1. canvas 橡皮擦效果制作

    擦除一定数量后全部消失的有用 imageData 方法的 我把代码贴在最下面 <!DOCTYPE html> <html> <head> <meta char ...

  2. windows下检验caffe是否配置正确

    windows下检验caffe是否配置正确:(注:不考虑搭建caffe的编译环境,而是直接使用caffe官网提供的二进制文件) windows版本源码以及二进制库文件下载地址:https://gith ...

  3. caffe搭建----Visual Studio 2015+CUDA8.0+CUDNN5配置Caffe-windows(BLVC)

    原文来源:  来源:Angle_Cal  2016-12-19 17:32 本博主修改于2017-09-12.  版权所有,转载请注明出处.   BLVC版本的Caffe-windows已经支持Vis ...

  4. 横向卷轴(side-scrolling)地图的canvas实现

    标题有点小题大作了,实际上是实现一张看起来连续的运动背景图片. 效果如下:   // 实现原理: 图片1与图片2是两张首尾衔接的图片,图片1以一定速度移出canvas,图片2慢慢移进canvas,当图 ...

  5. php pack()函数详解与示例

    pack和unpack在一般的程序中还真的不容易见到,但是如果你用过很久以前的php生成excel你就会知道了.他的excel的头就是pack出来的最近在尝试与C交互的时候又用上了这玩意,所以不得不再 ...

  6. centos 在CentOS下编译FFmpeg

    所需软件 准备 yum install autoconf automake gcc gcc-c++ git libtool make nasm pkgconfig zlib-devel  -y 新版还 ...

  7. 模式匹配之尺度空间---scale space

    转载:http://www.cnblogs.com/cfantaisie/archive/2011/06/14/2080917.html   主要步骤  1).尺度空间的生成:     2).检测尺度 ...

  8. IOS之禁用UIWebView的默认交互行为

    本文转载至 http://my.oschina.net/hmj/blog/111344       UIKit提供UIWebView组件,允许开发者在App中嵌入Web页面.通过UIWebView组件 ...

  9. PHP中的面向对象 中的类(class)

    2.11 上午讲的是面向对象中的类(class),一个非常抽象的概念, 类里面成员的定义有 public$abc; private$abc(私有变量): protect $abc(受保护的变量): 下 ...

  10. LESS和sa

    一. Sass/Scss.Less是什么? Sass (Syntactically Awesome Stylesheets)是一种动态样式语言,Sass语法属于缩排语法,比css比多出好些功能(如变量 ...