追踪内核Makefile 的一点心得。

算学习内核的一个小阶梯。留念于此。
追踪内核Makefile,解释3个小问题:
这里先来解释第一个问题:
------------------------------------------------------------
1. 为什么直接执行make -f scripts/Makefile.build obj=scripts/basic 会出现错误?
------------------------------------------------------------
在linux 源码目录下,敲make, 我看到了它一系列make 过程, 其中有一条
    make -f scripts/Makefile.build obj=scripts/basic
我在源码目录下,直接敲命令 make -f scripts/Makefile.build obj=scripts/basic
它报错:
     /scripts/basic/Makefile: No such file or directory
甚是奇怪,明明看到make 执行了这条命令,单独执行又不行,到底是什么原因呢?

首先判定scripts/basic/Makefile 是确实存在的。只要cat scripts/basic/Makefile就可以证实。
打开顶层Makefile, 定位到如下位置:
# Basic helpers built in scripts/
PHONY += scripts_basic
scripts_basic:
#    $(error build=$(build))
    @echo "line 1------\n";
    cat scripts/basic/Makefile
    @echo "line 2------\n";
    $(Q)$(MAKE) $(build)=scripts/basic
    $(warning ----$(MAKE) $(build)=scripts/basic----)

显示了 make -f scripts/Makefile.build obj=scripts/basic
进一步确认了执行make 是可以运行命令的,但make -f ... 不可以。所以进一步研究!

打开scripts/Makefile.build文件,
找到出错的代码行:
 21 include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)

估计是kbuild-dir 出了问题。所以我们添加打印信息。

16 kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
$(warning --src=$(src), srctree=$(srctree), kbuild-dir=$(kbuild-dir)--)
$(warning "filter result:" $(filter /%, $(src)))
为什么加srctree 打印?判断kbuild-dir 出问题后,又进一步定位到srctree.

srctree 是 顶层Makefile 的一个变量,make数据库认为是环境变量.
srctree        := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))
KBUILD_SRC 未曾赋值,所以srctree = $(CURDIR).
$(CURDIR) 是原生环境变量,就是当前路径.
现在已经追查到头了,问题也已经解决了,当然也有了处理办法了。
********************************************************************************
只所以在顶层目录下敲make 可以执行命令,是因为srctree 被顶层Makefile赋予了当前路径.
直接敲命令make -f script/Makefile.build obj=<subdir> , 由于跳过了顶层Makefile,
此时srctree 为空, 使得kbuild-dir 出错, 路径出错了,将无法进行后续的操作。
********************************************************************************
在简化为: 环境变量变化了,所以执行会出错


注: 为了提交调试效率,可以添加stop 语句, $(error text) 就可以提前退出make
ifeq "$(src)" "scripts/basic"
$(error "stop here")
endif


----------------------------------
2. 继续追踪: 一个cp 错误提示
----------------------------------
 make -f scripts/Makefile.build obj=drivers/net/wireless/rtl8188eu srctree="./"
 cp: cannot stat ‘/home/hjj/cxt/ADSP-EDU-BF533-uClinux-V2.1/uClinux源码/ADSP-EDU-BF533uC_V2.1/linux-2.6.x/autoconf_rtl8188e_usb_linux.h’: No such file or directory

如何定位这个错误在哪里呢?
还有一个杀手锏 make -d, 能很快定位问题之所在。


----------------------------------
3. uclinux 主目录下运行make, 发现了一个
  CALL    scripts/checksyscalls.sh
  试分析一下它的作用。
----------------------------------
行首#为自己的注释
#scripts/checksyscalls.sh 是一个文件,为missing-syscalls 的依赖
missing-syscalls: scripts/checksyscalls.sh FORCE
    $(call cmd,syscalls)
# 执行的cmd 为:
#`scripts/Kbuild.include', line 135
cmd = @$(echo-cmd) $(cmd_$(1))

#call 传参syscalls($1) 将变为 $(cmd_syscalls)
#$(cmd_syscalls) 可能是quiet_cmd_syscalls, 或者是cmd_syscalls
# './Kbuild', line 55)
quiet_cmd_syscalls = CALL    $<
      cmd_syscalls = $(CONFIG_SHELL) $< $(CC) $(c_flags)
#可以看到, 带quiet_ 和不带quiet两个字串,作为变量将会代表不同的含义。
# 前面将显示 "CALL ....", 后面将是一个完整的编译显示命令。

#echo-cmd 是自定义函数,完成打印的功能, 如果参数1引用不为空,就打印出来
#`scripts/Kbuild.include', line 131)
echo-cmd = $(if $($(quiet)cmd_$(1)), echo '  $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)

# `scripts/Kbuild.include', line 25)
escsq = $(subst $(squote),'\$(squote)',$1)
# 其中squote 为单引号', 把单引号用\反引用

#非quiet 时显示:
/bin/sh scripts/checksyscalls.sh bfin-uclinux-gcc -Wp,-MD,./.missing-syscalls.d  -nostdinc -isystem /opt/uClinux/bfin-uclinux/lib/gcc/bfin-uclinux/4.1.2/include -D__KERNEL__ -Iinclude  -include include/linux/autoconf.h -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -mno-fdpic -mcpu=bf533-0.3 -fomit-frame-pointer  -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign    -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(missing_syscalls)"  -D"KBUILD_MODNAME=KBUILD_STR(missing_syscalls)"

#这只是一个引用显示函数,真正编译的实现是通过:
make -f scripts/Makefile.build obj=. missing-syscalls
#通过调用核心Makefile.build, 维护missing-syscalls 目标,
#这在编译prepare0 时会被调用, 对script/Makefile.build 的分析,要另启一篇。


感叹于make 调试功能的薄弱,只能借助与warning,error,make -p, verbose, make -d 种种手段,再加上时间....
如果分析了make 程序,又将如何呢? 好像没有必要,没有时间,没有动力,跟现在的结果相比....再说吧...
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值