天天看点

《嵌入式Linux开发实用教程》——1.2 Makefile基本知识

本节书摘来异步社区《嵌入式linux开发实用教程》一书中的第1章,第1.2节,作者:朱兆祺 ,李强 ,袁晋蓉 ,更多章节内容可以访问云栖社区“异步社区”公众号查看

嵌入式linux开发实用教程

makefile如今能得以广泛应用,这还得归功于它被包含在unix系统中。在make诞生之前,unix系统的编译系统主要由“make”、“install”shell脚本程序和程序的源代码组成。它可以把不同目标的命令组成一个文件,而且可以抽象化依赖关系的检查和存档。这是向现代编译环境发展的重要一步。1977年,斯图亚特·费尔德曼在贝尔实验室里制作了这个软件。2003年,斯图亚特·费尔德曼因发明了这样一个重要的工具而接受了美国计算机协会(acm)颁发的软件系统奖。

makefile文件可以实现自动化编译,只需要一个“make”命令,整个工程就能完全自动编译,极大地提高了软件开发的效率。目前虽有众多依赖关系检查工具,但是make是应用最广泛的一个。一个程序员会不会写makefile,从一个侧面说明了这个程序员是否具备完成大型工程的能力。

一个简单的makefile语句由目标、依赖条件、指令组成。

obj := $(objtree)/

objtree  := $(if $(build_dir),$(build_dir),$(curdir))

export build_dir=/tmp/build<code>`</code>

$(if $(build_dir),$(build_dir),$(curdir))的含义:如果“build_dir”变量值不为空,则将变量“build_dir”指定的目录作为一个子目录;否则将目录“curdir”作为一个子目录。

2.递归展开式变量

这类变量的定义是通过“=”和“define”来定义的。

x = $(y)

y = $(z)

z = $(x)<code>`</code>

这样的话会使得makefile出错,因为到最终引用了自己。

其二,这种风格的变量定义中如果使用了函数,那么包含在变量值中的函数总会在变量被引用的地方执行。

3.直接展开式变量

为了避免递归展开式变量存在的问题和不方便,gnu make支持另外一种风格的变量,称为直接展开式变量。这种风格的变量使用“:=”定义。在使用“:=”定义变量时,变量值中对其他变量或者函数的引用在定义变量时被展开,也就是对变量进行替换。

x := student

x ?= teacher

all:  

  @echo $(x)<code>`</code>

由于x在之前被赋值了,所以这里的输出是student。

5.变量的替换引用

对于一个已经定义的变量,可以使用变量的替换引用将变量中的后缀字符使用指定的字符替换。格式为“$(x:a=b)”(或者“${x:a=b}”),即将变量“x”中所有以“a”字符结尾的字替换为以“b”结尾的字。

x = fun.o main.o

x += sub.o

这里的输出是:fun.o main.o sub.o。

1.ifneq关键字

这个关键字是用来判断两个参数是否不相等。格式为:

version   = 2013

patchlevel  = 04

sublevel   =

extraversion =

ifneq "$(sublevel)" ""

u_boot_version = $(version).$(patchlevel).$(sublevel)$(extraversion)

else

u_boot_version = $(version).$(patchlevel)$(extraversion)

endif<code>`</code>

先将sublevel使用$()展开和替换,如果sublevel的值不是空,则执行:

ifeq “value1”“value2”

ifeq (value1,value2)<code>`</code>

和ifneq一样,先要将value1和value2展开替换之后,再进行比较。

ifndef value<code>`</code>

由于在makefile中,没有定义的变量的值为空。

subdirs += $(subdir_examples)<code>`</code>

否则不执行。

4.ifdef关键字

ifdef关键字用来判断一个变量是否已经进行定义过。格式:

ifdef config_sys_ldscript  

    # need to strip off double quotes  

    ldscript := $(subst ",,$(config_sys_ldscript))

如果config_sys_ldscript定义过,则执行:

zhu := $(shell cat func)

all:

    @ echo $(zhu)<code>`</code>

func文件中的内容:

zhuzhaoqi@zhuzhaoqi-desktop:~/u-boot/makefile/shellfunction$ make

juxst zhuzhaoqi<code>`</code>

在u-boot和linux内核源码中将会大量使用到shell函数。

3.subst函数

subst函数是字符串替换函数,语法为:

$(subst 被替换字串 替换字串 替换操作字符串)

执行subst函数之后,返回的是执行替换操作之后的字符串。如下:

echo  zhu zhaoqi

zhu zhaoqi<code>`</code>

即将“z”替换成了“z”。

4.dir函数

dir函数作用为取出该文件的目录,其语法为:

$(dir 文件名称)

执行该函数之后返回文件目录部分。

makefile中常用函数较多,笔者就不一一例举了,读者可参考相关书籍进行深入了解。

继续阅读