gpt4 book ai didi

c - kbuild 实际上是如何工作的?

转载 作者:IT王子 更新时间:2023-10-29 00:21:47 26 4
gpt4 key购买 nike

当我在开发 linux 驱动程序时,我已经阅读了有关如何通过此 document 编写 linux kbuild makefile 的信息

我知道 kbuild 系统使用 makefile 变量,例如 obj-y obj-m 来确定构建什么以及如何构建。

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

最佳答案

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

  1. 顶级 Makefile 做

    include $(srctree)/scripts/Kbuild.include

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

  2. Kbuild.include定义各种常见的东西和助手。其中有 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 .

  3. 回到顶层Makefile,有以下内容:

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

    vmlinux-dirs包含要构建的子目录列表(initusrkernel 等)。 $(Q)$(MAKE) $(build)=<subdirectory>将为每个子目录运行。

    上面的规则编译了内核镜像和模块的目标文件。在顶层 Makefile 的下方,还有一些额外的特定于模块的内容:

    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
  4. 调查 scripts/Makefile.build ($(build) 使用的 Makefile)现在,它首先初始化 obj-*列表和各种其他列表:

    # 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 :=

    再往下一点,它加载到 Kbuild 文件中 obj-y , obj-m等,被设置为:

    include $(kbuild-file)

    再往下是默认规则,它有 $(obj-y)$(obj-m)列为先决条件:

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

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

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

    实际的构建似乎是按以下规则执行的:

    # 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 中运行以下命令:

    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 = $(CC) $(c_flags) -c -o $@ $<

    除非使用例如明确设置make CC=clang , CC默认为 gcc ,正如在顶级 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 的值.

关于c - kbuild 实际上是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29231876/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com