kbuild实际如何工作? [英] How does kbuild actually work?

查看:201
本文介绍了kbuild实际如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在开发linux驱动程序时,我已经阅读了有关如何通过文档

When i'm developing a linux driver, i've read about how to write linux kbuild makefile through this document

我知道kbuild系统会使用诸如obj-y obj-m之类的makefile变量来确定要构建什么以及如何构建.

I know kbuild system use makefile variables such as obj-y obj-m to determine what to build and how to build.

但是我很困惑的是kbuild系统真正在哪里执行构建过程.总之,如果我有obj-m = a.o,那么kbuild系统在哪里解析obj-m并执行gcc a.c?

But what i'm confused about is where does kbuild system really execute build process.In a word, if i have obj-m = a.o, then where does kbuild system parse obj-m and execute gcc a.c ?

推荐答案

Kbuild的Makefile并不是最容易阅读的,但这是一个高级解开(使用4.0-rc3内核):

Kbuild's Makefiles aren't the easiest to read, but here's a high-level untangling (using the 4.0-rc3 kernel):

  1. 顶级Makefile做

  1. The top-level Makefile does

include $(srctree)/scripts/Kbuild.include

,其中$(srctree)是顶级内核目录.

, where $(srctree) is the top-level kernel directory.

Kbuild.include定义了各种常见的东西和帮手.其中有build:

Kbuild.include defines various common stuff and helpers. Among these is build:

###
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
# Usage:
# $(Q)$(MAKE) $(build)=dir
build := -f $(srctree)/scripts/Makefile.build obj

build与类似$(MAKE) $(build)=dir的命令一起使用,以执行目录dir的构建.它使用scripts/Makefile.build.

build is used with a command like $(MAKE) $(build)=dir to perform the build for the directory dir. It makes use of scripts/Makefile.build.

返回到顶级Makefile,有以下内容:

Returning to the top-level Makefile, there's the following:

$(vmlinux-dirs): prepare scripts
        $(Q)$(MAKE) $(build)=$@

vmlinux-dirs包含要构建的子目录列表( init usr 内核等). $(Q)$(MAKE) $(build)=<subdirectory>将在每个子目录中运行.

vmlinux-dirs contains a list of subdirectories to build (init, usr, kernel, etc.). $(Q)$(MAKE) $(build)=<subdirectory> will be run for each subdirectory.

上面的规则为内核映像和模块编译目标文件.在顶层Makefile中,还有一些其他特定于模块的内容:

The rule above compiles object files for both the kernel image and modules. Further down in the top-level Makefile, there's some additional module-specific stuff:

ifdef CONFIG_MODULES
...
modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
        # Do additional module-specific stuff using
        # scripts/Makefile.modpost among other things
        # (my comment).
        ...
...
endif # CONFIG_MODULES

  • 现在看一下scripts/Makefile.build($(build)使用的Makefile),它首先初始化obj-*列表和各种其他列表:

  • Looking into scripts/Makefile.build (the Makefile used by $(build)) now, it begins by initializing the obj-* lists and various other lists:

    # Init all relevant variables used in kbuild files so
    # 1) they have correct type
    # 2) they do not inherit any value from the environment
    obj-y :=
    obj-m :=
    lib-y :=
    lib-m :=
    

    再往下一点,它将加载到设置了obj-yobj-m等的Kbuild文件中:

    A bit further down, it loads in the Kbuild file where obj-y, obj-m, etc., are set:

    include $(kbuild-file)
    

    进一步是默认规则,该规则具有$(obj-y)$(obj-m)列表作为先决条件:

    Further down is the default rule, which has the $(obj-y) and $(obj-m) lists as prerequisites:

    __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
             $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
             $(subdir-ym) $(always)
            @:
    

    $(obj-y)的先决条件来自$(builtin-target),其定义如下:

    The $(obj-y) prerequisites come from $(builtin-target), which is defined as follows:

    builtin-target := $(obj)/built-in.o
    ...
    $(builtin-target): $(obj-y) FORCE
            $(call if_changed,link_o_target)
    

    实际的建筑似乎是由以下规则完成的:

    The actual building seems to be performed by the following rule:

    # Built-in and composite module parts
    $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
            $(call cmd,force_checksrc)
            $(call if_changed_rule,cc_o_c)
    

    if_changed_rule来自Kbuild.include.该规则最终在Makefile.build中运行以下命令:

    if_changed_rule is from Kbuild.include. The rule ends up running the following commands in Makefile.build:

    define rule_cc_o_c
            $(call echo-cmd,checksrc) $(cmd_checksrc)                         \
            $(call echo-cmd,cc_o_c) $(cmd_cc_o_c);                            \
            ...
    endef
    

    $(cmd_cc_o_c)似乎是实际的编译命令.通常的定义(在Makefile.build中有两种可能性,AFAICS)似乎如下:

    $(cmd_cc_o_c) seems to be the actual compilation command. The usual definition (there are two possibilities in Makefile.build, AFAICS) seems to be the following:

    cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
    

    除非使用显式设置make CC=clangCC默认为gcc,如在顶层Makefile中所示:

    Unless set explicitly using e.g. make CC=clang, CC defaults to gcc, as can be seen here in the top-level Makefile:

    ifneq ($(CC),)
    ifeq ($(shell $(CC) -v 2>&1 | grep -c "clang version"), 1)
    COMPILER := clang
    else
    COMPILER := gcc
    endif
    export COMPILER
    endif
    

  • 我要解决的方法是在内核构建过程中执行 CTRL-C ,然后查看make报告错误的位置.另一种方便的make调试技术是使用$(warning $(variable))打印variable的值.

    The way I untangled this was by doing a CTRL-C during a kernel build and seeing where make reported the error. Another handy make debugging technique is to use $(warning $(variable)) to print the value of variable.

    这篇关于kbuild实际如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆