make s3c2410_defconfig分析

来源:互联网 发布:4钻淘宝店出售多少钱 编辑:程序博客网 时间:2024/05/18 02:36
材料:linux-2.6.22.6
在主Makefile中有%config的定义,但是先要考虑config-targets是否为1来判断%config目标是否生效。
config-targets有两处定义,如下:
    config-targets := 0
    ifeq ($(KBUILD_EXTMOD),)
            ifneq ($(filter config %config,$(MAKECMDGOALS)),)
                    config-targets := 1
                    ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)
                            mixed-targets := 1
                    endif
            endif
    endif
    其中,KBUILD_EXTMOD为空。
        $(MAKECMDGOALS)表示命令行执行的目标,即s3c2410_defconfig。
        所以,$(filter config %config,$(MAKECMDGOALS))为s3c2410_defconfig。
所以,config-targets为1。即%config目标有效。
接下来分析%config标号
config %config: scripts_basic outputmakefile FORCE
    $(Q)mkdir -p include/linux include/config    //$(Q)为@,表示终端中不显示命令信息
    $(Q)$(MAKE) $(build)=scripts/kconfig $@        //$@表示目标
一 依赖:
(1)scripts_basic
    在主Makefile有scripts_basic的定义,如下:
        scripts_basic:
            $(Q)$(MAKE) $(build)=scripts/basic
    其中,build := -f scripts/Makefile.build obj    (详见umage生成过程)
    综上,命令为make -f scripts/Makefile.build obj=scripts/basic
    没有指定目标,即上面的可以分析为make执行scripts/Makefile.build的第一个目标(__build),并设置obj=scripts/basic。
    __build有如下定义:        
        __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
                 $(if $(KBUILD_MODULES),$(obj-m)) \
                 $(subdir-ym) $(always)
                @:
        其中,KBUILD_BUILTIN在Makefile中设置为1,考虑以下变量。
        (1.1)builtin-target
            在scripts/Makefile.build中有如下定义:
                ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),)
                    builtin-target := $(obj)/built-in.o
                endif
            还没有有效的配置生成,所以obj-y,obj-m,obj-n,obj-,lib-target均为空。
            builtin-target为空。
        (1.2)lib-target
            在scripts/Makefile.build中有如下定义:                
                ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),)
                    lib-target := $(obj)/lib.a
                endif
            根据上面分析,lib-target为空。
        (1.3)extra-y
            为空。
        (1.4)if $(KBUILD_MODULES),$(obj-m)
            KBUILD_MODULES为空,为空。
        (1.5)subdir-ym
            在scripts/Makefile.lib中有如下定义:
            subdir-ym    := $(sort $(subdir-y) $(subdir-m))
                subdir-ym    := $(addprefix $(obj)/,$(subdir-ym))
            在scripts/Makefile.lib中有如下定义:
                __subdir-y    := $(patsubst %/,%,$(filter %/, $(obj-y)))
                subdir-y    += $(__subdir-y)
                __subdir-m    := $(patsubst %/,%,$(filter %/, $(obj-m)))
                subdir-m    += $(__subdir-m)
            所以,subdir-ym也为空。
        (1.6)always
            根据scripts/Makefile.build第17行,可以知道当前包含目录scripts/basic/Makefile。
            因此,对always有如下定义:
                hostprogs-y    := fixdep docproc
                always        := $(hostprogs-y)
            所以always := fixdep docproc
        (1.7)转化结果
            __build: fixdep docproc
                @:
        (1.8)fixdep和docproc的生成
            在scripts/basic/Makefile中有如下定义:
                hostprogs-y    := fixdep docproc
            在scripts/Makefile.host中有如下定义:
                __hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))                    
                host-csingle := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m)))
            从字面上理解,host-csingle是主机上运行的程序,并非使用交叉工具链的程序,并且是从单个C文件生成的。
            __hostprogs包含很多程序,下面仅仅以fixdep为例子说明,docproc同理。
            由于fixdep-objs不存在,所以host-csingle可以转化为:
                host-csingle := fixdep
            在scripts/basic/Makefile中,然后对host-csingle有如下操作:
                host-csingle    := $(addprefix $(obj)/,$(host-csingle))
            所以可以得到host-csingle:=scripts/basic/fixdep
            然后在scripts/Makefile.host中,有如下定义:
                $(host-csingle): $(obj)/%: $(src)/%.c FORCE
                    $(call if_changed_dep,host-csingle)
            (1.8.1)目标与依赖得转换
                这里第一个冒号前的部分($(host-csingle))是目标,第二个冒号前(即$(obj)/%)是目标匹配模式,最后一个冒号后的部分($(src)/%.c)是匹配的依赖。(详见:http://guliqun1983.blog.163.com/blog/static/50111685201171842740793/)当host-csingle为fixdep的时候,会按照匹配方式查找依赖得到fixdep.c。因此转换结果如下:
                    scripts/basic/fixdep: scripts/basic/fixdep.c
                        $(call if_changed_dep,host-csingle)
            (1.8.2)$(call if_changed_dep,host-csingle)
                在Kbuild.include中有如下定义:
                    if_changed_dep = $(if $(strip $(any-prereq) $(arg-check) ),                  \
                        @set -e;                                                             \
                        $(echo-cmd) $(cmd_$(1));                                             \
                        scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\
                        rm -f $(depfile);                                                    \
                        mv -f $(dot-target).tmp $(dot-target).cmd)
                意思就是如果目标不存在或依赖发生改变,就会执行后面得命令:
                其中各个符号的说明如下:                
                    (a)$(echo-cmd) $(cmd_$(1))            
                        其中,echo-cmd为打印命令,暂时忽略。
                        $(cmd_$(1)可转换为cmd_host-csingle
                        在scripts/Makefile.host中有如下定义:
                            cmd_host-csingle    = $(HOSTCC) $(hostc_flags) -o $@ $< $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
                        其中:HOSTCC在主Makefile中被定义为gcc,并导出到全局变量。
                            hostc_flags是一些编译选项,暂时不深入。
                            $@是fixdep。$<是第一个依赖文件,即scripts/basic/fixdep.c。
                            HOST_LOADLIBES仅仅在scripts/kconfig/Makefile中有定义,但未包含这个文件,所以该值为空。
                            HOSTLOADLIBES_$(@F),即HOSTLOADLIBES_fixdep,没有定义为空。
                    调试运行,运行如下命令,与分析一致。得到一下命令
                    gcc -Wp,-MD,scripts/basic/.fixdep.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer     -o scripts/basic/fixdep scripts/basic/fixdep.c   
                    (b)scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;
                        在Kbuild.include中有
                            comma   := ,
                            dot-target = $(dir $@).$(notdir $@)
                            depfile = $(subst $(comma),_,$(dot-target).d)
                        所以,dot-target =scripts/basic/.fixdep
                            depfile = scripts/basic/.fixdep.d
                        $@为fixdep。
                        这个时候还没有fixdep,所以下面小部分以docproc为例说明。
                        可以转化为:
                            scripts/basic/fixdep scripts/basic/.docproc.d scripts/basic/docproc '$(make-cmd)' >  scripts/basic/.docproc.tmp
                        由于尚未分析fixdep,但是看结果可以猜测是fixdep生成包含docproc.c的依赖和生成目标的文件。        
                    (c)rm -f $(depfile)
                        rm -f scripts/basic/.fixdep.d
                    (d)mv -f $(dot-target).tmp $(dot-target).cmd)
                        mv -f scripts/basic/.fixdep.tmp scripts/basic/.fixdep.cmd
    
(2)outputmakefile
    在主Makefile中有如下定义:
        outputmakefile:
            ifneq ($(KBUILD_SRC),)
                $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
                $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
            endif
    由于KBUILD_SRC为空,所以outputmakefile为空。

二 mkdir -p include/linux include/config
    建立目录include/linux和include/config


三 $(MAKE) $(build)=scripts/kconfig $@
(1)转化结果
    可以转化为 make -f scripts/Makefile.build obj=scripts/kconfig s3c2410_defconfig
    这里,在scripts/Makefile.build中有包含scripts/kconfig/Makefile的语句。
    并在scripts/kconfig/Makefile中有如下定义:
        %_defconfig: $(obj)/conf
            $(Q)$< -D arch/$(ARCH)/configs/$@ arch/$(ARCH)/Kconfig
    可转化为
        s3c2410_defconfig:    scripts/kconfig/conf
            scripts/kconfig/conf -D arch/arm/configs/s3c2410_defconfig arch/arm/Kconfig
    即执行程序scripts/kconfig/conf,后面的为参数。
(2)conf程序的生成
    接下里需要分析的是scritps/kconfig/conf程序的生成。
    在scripts/kconfig/Makefile有如下定义:
        hostprogs-y := conf qconf gconf kxgettext
    在scritps/Makefile.host有如下定义:
        __hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))
        __hostprogs     := $(addprefix $(obj)/,$(__hostprogs))
        host-cmulti    := $(foreach m,$(__hostprogs),\
           $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))
    这里简化如下:
        __hostprogs := scritps/kconfig/conf
        host-cmulti    := $(if $(conf-cxxobjs),,$(if $(conf-objs),scritps/kconfig/conf))    
    其中:
        conf-cxxobjs不存在。
        在scripts/kconfig/Makefile定义conf-obj如下:
            conf-objs    := conf.o  zconf.tab.o
    综上,host-cmulti := scritps/kconfig/conf
    同时,在scripts/Makefile.host中有如下定义:
        $(host-cmulti): $(obj)/%: $(host-cobjs) $(host-cshlib) FORCE
            $(call if_changed,host-cmulti)

    (2.1)依赖与目标的转换
        (2.1.1)host-cobjs
            按照执行顺序有如下定义:
            在scripts/kconfig/Makefile        
                hostprogs-y := conf qconf gconf kxgettext    (注:如果执行那个make menuconfig会增加mconf)
            此时host-progs未定义,因此scipts/Makefile.build中关于hostprogs-y的赋值不执行。
            hostprogs-m未定义
            在scripts/Makefile.host中有如下定义:
                __hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))            
                host-cobjs    := $(sort $(foreach m,$(__hostprogs),$($(m)-objs)))
                host-cobjs    := $(filter-out %.so,$(host-cobjs))
                host-cobjs    := $(addprefix $(obj)/,$(host-cobjs))
            在scripts/kconfig/Makefile有如下定义:
                conf-objs    := conf.o  zconf.tab.o
                kxgettext-objs    := kxgettext.o zconf.tab.o
            由于qconf-target未定义,qconf-objs为空。(当执行make xconfig会定义这个)
            由于gconf-target未定义,qconf-objs为空。(当执行make gconfig会定义这个)
            所以host-cobjs := scripts/kconfig/conf.o scripts/kconfig/kxgettext.o scripts/kconfig/zconf.tab.o  
        (2.1.2)host-cshlib
            在scripts/Makefile.host中定义:
                host-cshlib    := $(sort $(filter %.so, $(host-cobjs)))
                host-cshlib    := $(addprefix $(obj)/,$(host-cshlib))
            这里可知,与host-cobjs相同
        (2.1.3)转换结果
            scritps/kconfig/conf : scritps/kconfig/conf.o
        (2.1.4)scritps/kconfig/conf.o kxgettexgt.o zconf.tab.o的生成
            仅仅以scritps/kconfig/conf.o为例子说明。
            在scripts/Makefile.host有如下定义:
                $(host-cobjs): $(obj)/%.o: $(src)/%.c FORCE
                    $(call if_changed_dep,host-cobjs)
            可以转化为如下:
                scritps/kconfig/conf.o : scritps/kconfig/conf.c
                    $(call if_changed_dep,host-cobjs)
                根据前面的分析,可以生成scritps/kconfig/conf.o的过程。
    (2.2)$(call if_changed,host-cmulti)
        根据之前的分析,可以知道相当于执行命令cmd_host-cmulti
        在scritps/Makefile.host中有如下定义:
            cmd_host-cmulti    = $(HOSTCC) $(HOSTLDFLAGS) -o $@ \
                $(addprefix $(obj)/,$($(@F)-objs)) \
                $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
            scritps/kconfig/Makefile中有如下定义:
                HOST_LOADLIBES   = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
            根据分析得到结果是要链接的库。
            HOSTLOADLIBES_$(@F),即HOSTLOADLIBES_conf未定义。
            $(@F)-objs),即conf-objs,为conf.o  zconf.tab.o
        所以,可以得到如下命令
            gcc $(HOSTLDFLAGS) -o conf scripts/kconfig/conf.o  scripts/kconfig/zconf.tab.o -l需要的库


四 结论
make s3c2410_defconfig执行的动作简单说如下:
(1)生成scripts/basic/fixdep和scripts/basic/docproc
(2)建立目录include/linux和include/config
(2)执行程序scripts/kconfig/conf -D arch/arm/configs/s3c2410_defconfig arch/arm/Kconfig
可见,主要工作在conf程序中执行。

0 0
原创粉丝点击