uboot rules.mk 自动生成依赖分析

 先贴出 rules.mk 源码:

#########################################################################


_depend: $(obj).depend


$(obj).depend: $(src)Makefile $(TOPDIR)/config.mk $(SRCS)
@rm -f $@
@for f in $(SRCS); do \
g=`basename $$f | sed -e 's/\(.*\)\.\w/\1.o/'`; \
$(CC) -M $(HOST_CFLAGS) $(CPPFLAGS) -MQ $(obj)$$g $$f >> $@ ; \
done


#########################################################################

哇,看着好复杂啊,头大了。

任何复杂的东西都是由简单的东西拼接而成的,别急,我们一点点来把它支解。


前面的
_depend: $(obj).depend


$(obj).depend: $(src)Makefile $(TOPDIR)/config.mk $(SRCS)
@rm -f $@
@for f in $(SRCS); do \

估计大家都懂,就不作过多解释了。


下面我们来看

g=`basename $$f | sed -e 's/\(.*\)\.\w/\1.o/'`; \

其目标是将把文件扩展名的首个字符替换成o。

main.c --->main.o

book@book-desktop:~/workspace/test/ex-1$ f=main.c; g=`basename $f | sed -e 's/\(.*\)\.\w/\1.o/'`;echo $g
main.o

究竟是怎样做到呢?

里面有个basename 函数

man basename:

NAME
       basename - strip directory and suffix from filenames


SYNOPSIS
       basename NAME [SUFFIX]
       basename OPTION


DESCRIPTION
       Print NAME with any leading directory components removed.  If specified, also remove a trailing SUFFIX.


       --help display this help and exit


       --version
              output version information and exit


EXAMPLES
       basename /usr/bin/sort
              Output "sort".


从上面的解说来看,就时去掉某个文件的路径名得来它的文件名。


接着这里使用了管道命令,前面命令的stdout 作出后面命令的stdin 。

对于 f=main.c; g=`basename $f 

它的输出就是main.c


再看 sed -e 's/\(.*\)\.\w/\1.o/'`;

乍一看符合合sed 's/ word1/word2 /'  用word2替换word1的命令模式

word1 为\(.*\)\.\w

.*表示任意多个字符;
\(.*\)是用来做后向引用的,\1就是它了;
\.是一个点
\w用于匹配字母,数字或下划线字符;

word2为\1.o

所以上面的命令大意就是保留XXX.X 的"."前面部分。后面的X用o代替。

e.g:

main.c-->main.o  

start.s--->start.o

至于sed 命令选项 -e 网上解释为:

sed选项

 选项  功能
 -e  进行多项编辑,即对输入行应用多条sed命令时使用
 -n  取消默认的输出
 -f  指定sed脚本的文件名
book@book-desktop:~/workspace/test/ex-1$ ls
1  2  include  main.c  main.o  Makefile  subdir  test

book@book-desktop:~/workspace/test/ex-1$ ls
1  2  include  main.c  main.o  Makefile  subdir  test


book@book-desktop:~/workspace/test/ex-1$ cat 2
just for check
just for test
just for CHECK
just for TEST

文件2里面的内容是上面那样的。

接下我们进行替换

book@book-desktop:~/workspace/test/ex-1$ sed -e 's/check/test/' -e 's/test/TEST/' 2
just for TEST
just for TEST
just for CHECK
just for TEST

我们先把check替换为test ,再基于上面的替换结果把test替换为TEST.


好了前面的一大堆目的就是为了得到XXX.o 的文件并赋值给g。我们继续看下面的。

$(CC) -M $(HOST_CFLAGS) $(CPPFLAGS) -MQ $(obj)$$g $$f >> $@ ;

我们翻译下得到,忽略$(HOST_CFLAGS) $(CPPFLAGS) 

HOSTCFLAGS= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer

CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS)\
-D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE)\


gcc -M -MQ main.o main.c >> .depend

接下的疑问就是-M -MQ 选项了,翻译自GCC的帮助文档:

-M 不是输出预编译过程的结果,而是输出一个用于make的规则,该规则描述了这个main源文件的依赖关系。预编译器输出的这个make规则包含名字与原文件相同的目标文件,冒号和所有include文件的名字。这些include文件主要来自于-include或-imacros命令行选项。

除非明确的指定-MT或-MQ,否则目标文件名由两部分组成:源文件名加目标文件后缀和可以被删除的目标文件路径。如果有多个include的文件,该规则将使用\-newline将其分成几行。该规则并没用命令。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值