Skip to content
Advertisement

How does kbuild actually work?

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

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

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 ?

Advertisement

Answer

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

  1. The top-level Makefile does

    JavaScript

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

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

    JavaScript

    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.

  3. Returning to the top-level Makefile, there’s the following:

    JavaScript

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

    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:

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

    JavaScript

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

    JavaScript

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

    JavaScript

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

    JavaScript

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

    JavaScript

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

    JavaScript

    $(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:

    JavaScript

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

    JavaScript

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.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement