GNU Makefile 之 (详述) 

一、概述

Makefile中主要包含的内容有:

1、注释

2、文件包含

3、变量定义

4、条件判断

5、函数

6、规则

 

二、注释

只提供单行注释, 凡是以#开头的行都认为是注释行。

#this is a comment 

 

三、文件包含

include的用法,include后面跟一个Makefile文件名. 这样我们可以写一个公共Makefile,包含一些公共变量的定义,其他目录下的Makefile可以把这个公共Makefile文件包含进去。

-include ../Makefile.param (之前的“-”表示包含失败不停止)

 

四、变量定义

1、变量的基础

在Makefile中,变量定义主要有如下几种方式:

#方式一:定义多行变量  

define variable  

value  

value  

endef 

#方式二:  

variable = value 

#方式三:  

variable := value  (直接展开)

#方式四:  

variable += value  (追加变量)

#方式五:  

variable ?= value 

变量的引用可以采用$(variable)和${variable}两种方式。

 

2、变量的高级应用

变量的替换引用:$(VAR:A=B)把变量VAR中的所有有A的地方都替换为B,如

foo := a.o b.o c.o  

bar := $(foo:.o=.c) 

 

override指示符:常规变量,会被执行make命令的参数变量覆盖,比如:

CFLAGS=-o 

如果执行make时使用make CFLAGS=O2,那么CFLAGS会变为o2,为了解决这个问题,可以使用override指示符

override CFLAGS=01 

这样,参数变量中指定的内容不会覆盖Makefile中定义的变量。

 

目标指定变量和模式指定变量:变量都是全局的,而目标指定变量和模式指定变量都是对某个目标或者某种模式局部的,如:

#目标指定变量  

foo:CFLAGS+=-O2 

#模式指定变量  

%.o:CFLAGS+=O1  

 

五、条件判断

条件判断有如下四种形式:

#1  

ifeq  

    do something  

else 

    do something  

endif 

#2  

ifneq   

    do something  

else 

    do something  

endif 

#3  

ifdef   

    do something  

else 

    do something  

endif 

#4  

ifndef   

    do something  

else 

    do something  

endif      

 

六、函数

1、文本处理函数

subst

patsubst

strip

findstring

filter

filter-out

sort

word

words

wordlist

firstword

 

2、文件名处理

dir

notdir

suffix

basename

addsuffix

addprefix

wildcard

 

3、其他

foreach

if

eval

value

 

七、规则

1、显示规则

规则的三要素都直接写出来的。

 

2、隐式规则

所谓隐式规则就是make会自动为一些目标推导依赖。下面列出c和c++相关的隐含规则:

 

1、编译c的隐含规则:<n>.o的目标的依赖会自动推导为<n>.c,并用命令$(CC) -c $(CPPFLAGS) $(CFLAGS)来生成.

2、编译c++的隐含规则:<n>.o的目标的依赖会自动推导为<n>.cc,并用命令$(CXX) -c $(CPPFLAGS) $(CFLAGS)来生成。

3、链接Object文件的隐含规则:<n>目标依赖于<n>.o,链接命令是$(CC) $(LDFLAGS)<n>.o $(LOADLIBES)$(LDLIBS),这一规则对多个依赖文件也是适用的,如x:y.o x.o z.o,但是依赖中至少要有同名的。

 

隐含规则通常都使用一些系统变量,先列出如下:

1、AR:默认是ar

2、CC:默认是cc

3、CXX:默认是g++

4、CPP:c程序的预处理器,默认是$(CC) -E

5、RM:删除文件,默认是rm -f

 

关于命令参数的变量:

1、ARFLAGS:打包程序AR的参数,默认是rv

2、CFLAGS:C语言的编译参数

3、CXXFLAGS:C++语言的编译器参数

4、CPPFLAGS:C预处理器参数

5、LDFLAFS:链接器参数

 

3、模式规则

隐含规则整体感觉太玄,但是可以用模式规则来定义隐含规则,它的目标中必须有%号,如:

%.o:%.c  

Command 

这个就是模式规则,这个规则表明,所有<n>.c到<n>.o的编译都使用Command,而不是内建的默认命令。

 

4、静态模式规则

静态模式规则是模式规则中的一种特例,模式规则是对所有的符合模式的都起作用,而静态模式规则是对特定的目标是用的一种模式规则,如

objects = foo.o bar.o  

all: $(objects)  

$(objects): %.o: %.c  

$(CC) -c $(CFLAGS) $< -o $@ 

#相当于  

foo.o : foo.c  

$(CC) -c $(CFLAGS) foo.c -o foo.o  

bar.o : bar.c  

$(CC) -c $(CFLAGS) bar.c -o bar.o 

其中%.o:%.c这个模式规则是只对objects这个目标起作用的。

 

5、自动化变量

在写一些规则的时候,需要有个变量可以自动的赋值为目标或依赖,下面列举几个常用的自动化变量:

 

1、$@:规则中所有的目标文件集

2、$<:依赖的第一个文件,如果依赖是以模式定义的,那就表示所有依赖文件集

3、$^:规则中的依赖文件集,并且是做了重复删除的

4、$+:跟$^一样,就是没做重复删除。

 

八 例子

根据项目的大小,可以把项目建成平铺式(小型项目)和嵌套式(大型项目),而这两种项目的Makefile文件也会稍有不同,前者通常一个Makefile就可以,放在顶层目录,而后者需要分不同模块写几个不同的Makfile,通过一个顶层的Makefile来包含。下面介绍一个可以用在通常平铺项目中的通用Makefile:

#以下定义目录结构  

SRC_DIR := ./src  

INC_DIR := ./include/a /  

       ./include/b /  

       ./include  

LIB_DIR := ./lib 

 

#以下定义编译工具链  

CROSS=arm-hismall-linux-  

CC=$(CROSS)gcc  

AR=$(CROSS)ar  

RANLIB=$(CROSS)ranlib  

RM=rm -f 

 

#以下定义编译参数  

CFLAGS :=  

DEPENDFLAG :=-MM  

LIB=$(foreach dir, $(LIB_DIR), -L$(dir))  

LIBFLAGS=-lprint  

INC=$(foreach dir, $(INC_DIR), -I$(dir)) 

  

#以下定义文件变量  

SRCS=$(foreach dir, $(SRC_DIR), $(wildcard $(dir)/*.c))  

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

DEPENDS=$(SRCS:.c=.d)  

TARGET=test 

  

#下面定义规则  

all:$(TARGET)   

 

%.d:%.c  

    @set -e; rm -f $@;/  

    $(CC) $(DEPENDFLAG) $(INC) $< |/  

    sed "s?//(.*//):?$(basename $<).o $(basename $<).d:?g"/  

    > $@;/  

 

%.o:%.c  

    $(CC) -o $@ -c $< $(INC)  

    

$(TARGET):$(OBJS)  

    $(CC) -o $@ $< $(LIB) $(LIBFLAGS)  

    

-include $(DEPENDS)

         

.PHONY:clean  

clean:  

    $(RM) $(OBJS) $(DEPENDS) $(TARGET) 

 

转自:http://fxpy.blog.edu.cn/2011/633628.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值