zoukankan      html  css  js  c++  java
  • Linux Kernel Makefile Test

    一、本文说明

      本文为linux内核Makefile整体分析的续篇,是依据Linux内核Makefile体系的主要内容编写一个简要的测试工程。Linux内核Makefile体系就好像一只“大鸟”,而这篇测试算是“麻雀”,主要是为了通过动手实战进一步理解Linux内核Makefile体系的原理和特点。

    二、源码结构

    1、测试源码包括1个顶层目录以及5个子目录。

    2、Makefile体系的构成是顶层1个Makefile文件、scripts目录中的4个脚本文件以及add、sub、main三个目录中的Makefile文件。

    3、C程序源码是add/add.c、sub/sub.c、main/main.c

    三、Makefile重要源码展示

    1、顶层Makefile

    PHONY :=  
    MAKE := make
    
    srctree        := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))
    export srctree 
    
    AS        = $(CROSS_COMPILE)as
    LD        = $(CROSS_COMPILE)ld
    CC        = $(CROSS_COMPILE)gcc
    CPP        = $(CC) -E
    AR        = $(CROSS_COMPILE)ar
    NM        = $(CROSS_COMPILE)nm
    
    export AS LD CC CPP AR NM 
    
    include $(srctree)/scripts/Kbuild.include //该文件中定义有build变量
    
    all: target
    
    srcdir := add sub main
    PHONY += $(srcdir)
    
    objdir := $(srcdir)
    PHONY += $(objdir)
    
    target: $(srcdir) //总目标的依赖是srcdir
        gcc -o target add/built-in.o sub/built-in.o main/built-in.o  //定义总目标的生成规则
    
    $(srcdir):  //通过srcdir依次生成各个子目录中的*/built-in.o
        $(MAKE) $(build)=$@ 
    
    clean-dirs := $(addprefix _clean_,$(objdir)) //clean-dirs其实与objdir中的目录是一样的,只是为了执行不同的命令(clean-dirs要删除目标文件),所以要clean-dirs的前边要加上前缀以与srcdir=objdir的目标区别
    PHONY += $(clean-dirs) clean
    
    $(clean-dirs):
        $(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
    
    clean: $(clean-dirs)
        rm -f target
    
    clean := -f scripts/Makefile.clean obj
    
    .PHONY: $(PHONY)

    2、srcdirs/Makefile.build

    # ==========================================================================
    # Building
    # ==========================================================================
    
    src := $(obj)
    
    PHONY := __build
    __build: //Makefile.build中的总目标
    
    include scripts/Kbuild.include
    
    # The filename Kbuild has precedence over Makefile
    kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
    kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
    include $(kbuild-file)  //包含子目录中的Makefile
    
    include scripts/Makefile.lib
    
    ifneq ($(strip $(obj-y)),)
    builtin-target := $(obj)/built-in.o
    endif
    
    __build: $(builtin-target)
    
    # If the list of objects to link is empty, just create an empty built-in.o
    cmd_link_o_target = $(if $(strip $(obj-y)),
                  $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^))
     
    $(builtin-target): $(obj-y)
        $(call if_changed,link_o_target) //调用生成库built-in.o的函数
     
    cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
    
    define rule_cc_o_c
        $(cmd_cc_o_c)                                     
    endef
    
    # Built-in and composite module parts
    $(obj)/%.o: $(src)/%.c 
        $(call if_changed_rule,cc_o_c) //调用生成目标文件.o的函数
    
    PHONY += FORCE
    FORCE:
    
    .PHONY: $(PHONY)

    3、srcdirs/Kbuild.include

    build := -f scripts/Makefile.build obj
    
    if_changed = $(cmd_$(1))//定义函数if_changed                                 
        
    # Usage: $(call if_changed_rule,foo)
    # Will check if $(cmd_foo) or any of the prerequisites changed,
    # and if so will execute $(rule_foo).
    if_changed_rule = $(rule_$(1)) //定义函数if_changed_rule

    4、srcdirs/Makefile.lib

    c_flags        =        //定义gcc编译器选项
    
    ld_flags       = $(LDFLAGS) $(ldflags-y) //定义ld连接器选项
    obj-y := $(patsubst %/, %/built-in.o, $(obj-y)) //对obj-y中的目录添加built-in.o
    obj
    -y := $(addprefix $(obj)/,$(obj-y))//再添加obj前缀

    5、srcdirs/Makefile.clean

    # ==========================================================================
    # Cleaning up
    # ==========================================================================
    
    src := $(obj)
    
    PHONY := __clean //此为Makefile.clean中的总目标
    __clean:   
    rm
    -f $(obj)/*.o //删除目标文件.o

    6、add/Makefile

    obj-y                += add.o

     四、当前源码缺陷

    1、没有完成依赖的自动生成

    2、没有完成生成目标的目录与源码不在同一目录的功能

    附:LinuxKernelMakefileTest.zip

  • 相关阅读:
    内核并发管理---spin lock
    redhat samba安装配置
    内核系统调用接口分析
    kernel makefile
    你知道C#中的Lambda表达式的演化过程吗?
    农码一生博文索引
    那些年搞不懂的术语、概念:协变、逆变、不变体
    Asp.Net生命周期
    ASP.NET配置文件Web.config 详细解释
    加盐密码哈希:如何正确使用
  • 原文地址:https://www.cnblogs.com/amanlikethis/p/3676857.html
Copyright © 2011-2022 走看看