注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

学习笔记

正确的方法如同学习书法,开始的时候要临摹,临摹好了然后创造自己的风格。

 
 
 

日志

 
 

[Makefile应用]中间层Makefile的写法  

2012-11-29 23:46:55|  分类: GNU tools |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
       主要内容为:编写一个中间层的Makefile,并对其进行一些重构,比如为相应的Makefile规则的命令添加出错推出处理。
       Makefile与shell的关系可以看下面的两篇文章:
*Makefile与shell脚本区别,网址:http://blog.chinaunix.net/uid-20672257-id-3345593.html
*Makefile与Shell的问题,网址:http://blog.csdn.net/absurd/article/details/636418
       中间层的Makefile的原则是尽量透明,不要添加一些额外的变量进去,防止影响整个Makefile的层次结构。

一、
       比如,当前目录现有如下目录,在各自的目录下均有自己的Makefile,那作为中间层的Makefile只需要进入相应的目录即可。
# ls
gate ground_sense keys leds pwm wiegand
       写法如下:
# cat Makefile
# create by fantity 2012-11-28 v1
target := gate ground_sense keys leds pwm wiegand
.PHONY: $(target) all
all:$(target)
$(target):
 $(MAKE) -C $@
 这里要注意的地方有
1、“:=”,不是“=”,“:=”是将变量直接展开,可防止递归调用。
2、要将$(target)声明称伪目标,否则编译器会将其当作目录。

二、
       添加上install,clean等规则之后,如下:
# cat Makefile
#creat by fantity 2012-11-29 v2
target := gate ground_sense keys leds pwm wiegand
.PHONY: all clean install
all:
 @for p in $(target);do $(MAKE) -C $$p || exit $$?;done
clean install:
 @for p in $(target);do $(MAKE) $@ -C $$p || exit $$?;done
       这里要注意的地方有:
1、变量p的值是要传给shell去执行的,而Makefile传给shell时会剥离一个$,所以这里需要写两个$$。
2、|| exit $$?,检查命令的执行状态,出错退出。
3、$@指代目标列表,指定那个目标就会执行那个目标,并不会全部编译。
       An AND list has the form
command1 && command2
       command2 is executed if, and only if, command1 returns an exit status of zero.
       An OR list has the form
command1 || command2
       command2 is executed if and only if command1 returns a non-zero exit status. The return status of AND and OR lists is the exit  status of the last command executed in the list.

三、
# cat Makefile
# creat by fantity 2012-11-29 v3
# directory of driver
driver_target := gate ground_sense keys leds pwm wiegand
# directory of driver test program
target := gate ground_sense keys leds pwm wiegand eeprom
test_target := $(target:%=%/test)

.PHONY: all driver driver_test clean clean_driver clean_driver_test install install_driver install_driver_test
all:driver driver_test
driver:
 @for p in $(driver_target);do $(MAKE) -C $$p || exit $$?;done
driver_test:
 @for p in $(test_target);do $(MAKE) -C $$p || exit $$?;done
clean:clean_driver clean_driver_test
install:install_driver install_driver_test
clean_driver install_driver
 @for p in $(driver_target);do $(MAKE) $(subst _driver,,$@) -C $$p || exit $$?;done
clean_driver_test install_driver_test:
 @for p in $(test_target);do $(MAKE) $(subst _driver_test,,$@) -C $$p || exit $$?;done
       这里要注意的地方有:
1、$(target:%=%/test),为变量target的成员添加后缀/test。
2、$(subst _driver_test,,$@),搜索目标列表,将列表中的_driver_test替换去掉。

四、
       对底层Makefile进行重构,将其相同的部分提取出来,作为公共的规则文件,供底层Makefile调用,减少代码的维护量。
底层Makefile内容为:
# cat Makefile
RULES_PATH ?= $(shell pwd)/..
include $(RULES_PATH)/driver_rules.mk
       针对不同模块需要修改的文件:
# cat Kbuild
obj-m := gate_char.o
       如果是多个ko文件:
# cat Kbuild
obj-m := device.o driver.o
       规则文件:
# cat driver_rules.mk 
KERNELDIR ?= /second/ezsdk/board-support/linux-2.6.37-psp04.04.00.01
PWD := $(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) CROSS_COMPILE=arm-none-linux-gnueabi- ARCH=arm modules
.PHONY:clean install
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) CROSS_COMPILE=arm-none-linux-gnueabi- ARCH=arm clean
install:
@mkdir -p $(TARGET_FS_DIR)/driver
@cp -f *.ko $(TARGET_FS_DIR)/driver
       需要注意的是:
1、?=是在变量为空时,才对变量赋值。可以用来防止多次复制。
2、Make中的包含include与C语言中的比较类似,执行到包含语句时,会跳转到被包含文件将其展开并执行,然后回到原处接着执行。

五、
       对Makefile进一步简化
# modified by fantity 2012-12-14

# add the directory of driver
driver_target := button char led motor dm814x_pwm
test_target := button led motor dm814x_pwm

all:driver driver_test
clean:driver_clean driver_test_clean
install:driver_install driver_test_install

driver driver_clean driver_install:
for p in $(driver_target);do $(MAKE) $(subst driver_,,$(filter driver_%,$@)) -C $$p || exit 1;done
driver_test driver_test_clean driver_test_install:
for p in $(test_target);do $(MAKE) $(subst driver_test_,,$(filter driver_%,$@)) -C $$p || exit 1;done
这里使用了filter,用来过滤带有指定字符串的变量。
  评论这张
 
阅读(798)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017