Linux Kernel Build System

Last update: 2026-02-04 03:53:53 +0800 +0800

The Linux kernel uses GNU Make and Kbuild to configure, compile, link, and install the kernel and its modules. A normal build starts with a configuration target and then builds the default target:

sh
make defconfig
make -j"$(nproc)"

The principal result is vmlinux, an ELF executable. Architectures may additionally produce bootable wrappers such as bzImage, zImage, or vmlinuz. Loadable modules are ELF relocatable objects linked into .ko files.

Source and Output Trees #

An in-tree build has identical srctree and objtree. An out-of-tree build keeps generated files separate:

sh
mkdir build
make O=build defconfig
make -C build -j"$(nproc)"

make clean removes most generated files while retaining enough support for external modules. make mrproper also removes configuration and generated headers, and make distclean additionally removes editor backup and patch files.

Configuration #

make *config targets build and run a Kconfig front end, such as conf for oldconfig or mconf for menuconfig. Kconfig files distributed through the source tree define the option hierarchy. The selected values are written to .config and then transformed into include/config/auto.conf, include/generated/autoconf.h, and per-symbol files under include/config/.

The root Makefile determines SUBARCH from the host, accepts ARCH for a target architecture, and derives SRCARCH for source directories. Cross-compiles normally specify at least ARCH and a toolchain prefix or compiler.

Makefile Layers #

The root Makefile is the entry point. It includes architecture Makefiles and utility snippets such as scripts/Kbuild.include, scripts/Makefile.compiler, and configuration-dependent scripts/Makefile.* fragments. These snippets define shared functions, compiler flags, and rules rather than each subsystem’s object list.

Each source directory supplies a Makefile or, where necessary, a Kbuild file. Kbuild takes precedence. These files normally declare inputs rather than duplicate generic rules:

  • obj-y adds objects or subdirectories built into vmlinux.
  • obj-m adds loadable-module inputs.
  • lib-y and lib-m contribute archive members.
  • always-y names targets that should always be built.
  • hostprogs names tools built for the build host.

An object-list entry can name foo.o or foo/; the trailing slash requests recursive descent into that subdirectory. Configuration-controlled forms such as obj-$(CONFIG_FOO) += foo.o select an input when a symbol is y or m.

Subdirectory Builds #

The root build invokes a directory through:

makefile
$(MAKE) $(build)=path/to/directory

build expands to -f scripts/Makefile.build obj, so this starts a sub-make using scripts/Makefile.build while passing the target directory as obj. That Makefile loads the directory’s Kbuild or Makefile, then scripts/Makefile.lib, which normalizes the declared variables and supplies generic compilation and archive rules. This division lets subsystem Makefiles focus on selecting sources. It also keeps dependencies local: a directory invokes a sub-make rather than reaching directly into another directory’s outputs.

scripts/Makefile.host supplies rules for host tools. The hostprogs-always-y shortcut adds host programs to the always-built set; a host program with no foo-objs, foo-cxxobjs, or Rust object list is compiled from its conventional single source.

Commands and Incremental Dependencies #

Kbuild names reusable recipes with cmd_<name> and concise quiet output with quiet_cmd_<name>. For example, $(call cmd,foo) runs cmd_foo and selects the quiet or verbose log according to V=.

The if_changed, if_changed_dep, and if_changed_rule helpers run a recipe when a prerequisite is newer, the command line has changed, or a target is missing. if_changed_dep additionally processes compiler dependency information. Generated hidden .cmd files record the saved command and dependencies for outputs such as objects, archives, generated headers, modules, and vmlinux. This makes a changed compiler option or Kconfig symbol a valid reason to rebuild an affected target, not just a changed source timestamp.

Directory objects are gathered into built-in.a archives for the built-in kernel or into module inputs. The final link creates vmlinux; architecture-specific rules may then wrap, compress, sign, or package it. Module post-processing resolves exported symbols, emits metadata, and produces .ko files. make modules_install installs modules and runs the installation rules, while architecture-specific install targets place the kernel image where the boot environment expects it.

Migrated Reference Material #

This article analyzes the building process of the Linux kernel, including the implementation of Makefiles. Various build-time generated files and build techniques are discussed.

It is well-known that the Linux kernel should be built by make *config followed by a make call without a goal. The make *config command does nothing more than invoke a wizard program, which may include compiling that wizard program first. It’s the wizard program’s responsibility to properly generate a .config file which holds the user’s choice on the kernel building configs.

The wizard program usually reads various Kconfig files in the source tree to determine what kernel build options are devised by the kernel developer, and in what structure these options should be displayed to an end user. The Kconfig system won’t be discussed as a part of a kernel’s build here. See this article for an intro to the syntax of a Kconfig file and the rules of writing one.

Before a build, it’s recommended to invoke 1 of the 3 clean targets:

  • clean: Remove most generated files but keep the config and enough build support to build external modules
  • mrproper (more proper): Remove all generated files + config + various backup files
  • distclean (clean for distribution): mrproper + remove editor backup and patch files

Out-of-source Build #

Linux supports out-of-source build by an O=dir make CLI argument:

sh
cd linux-6.8.2
mkdir build
make O=build defconfig
cd build
make -j12

In the Makefile, the source directory is referred to by the $(srctree) variable while the build directory is the $(objtree). If the O=dir argument is not used, both will be the same.

A kernel build is initiated by calling a plain make on the build directory. This Makefile-based system also must support future repetitive invocation of make by detecting modifications and building only the necessary parts. The make interface is also versatile and assumes jobs of different nature (clean, generate configs, build modules, build the vmlinux), bringing complexity to the implementation of Makefiles.

We will be exploring how the Makefile pieces are put together to achieve this.

Overview #

The Makefile-based build system of Linux consists of 4 types of file:

  1. The root Makefile. It is the entrance of make execution.

  2. scripts/Kbuild.include and scripts/Makefile.*

    These are auxillary Makefile snippets that implement utilities and variables used by othe Makefiles, instead of defining build rules for the kernel.

  3. The Makefiles in each directory of source tree, including scripts/Makefile.

    These files append string values to certain well-known variables, including obj-y, obj-m, etc., rather than introducing new Makefile rules.

  4. Build time generated .<output_filename>.cmd and .<output_filename>.d in build tree, both being Makefile snipppets.

    They contain only Makefile rules (i.e. dependency) for <output_filename>.

The Root Makefile #

A lot about the mechanics can be learned by inspecting the root Makefile, the very first file a make process parses and executes.

The following pseudo-code briefly describes the root Makefile:

go
func make_single(target) {
    include `scripts/Kbuild.include` for utils functions
    load ARCH SRCARCH etc. variables
    set compilerinclude path

    load include $(srctree)/scripts/Makefile.compiler

    if (target matches '*config') {
        // if this is a config build (i.e. we are generating .config)
        make -f `scripts/Kconfig/Makefile` *config
    } else {
        // non config build includes
        // 1. the actual vmlinuz or modules
        // 2. arch-specific targets
        // 3. clean
        // 4.

        load include/config/auto.conf (.config as Makefile variables)
        load $(srctree)/arch/$(SRCARCH)/Makefile
        load include/config/auto.conf.cmd

        compiler flag adjustment, depending on

        if (`make M=...` or `make KBUILD_EXTMOD=...` set) {
            `__all: modules`: default goal is to build `modules`
        } else {
            `__all: all`: default goal is to build `modules`
        }
    }
}


func make(targets, need-submake) {
    if (need-submake = 1) {
        make(targets, 0)
        return;
    }

    for each (target in targets)
        make_single(target)
}

scripts/Kbuild.include and scripts/Makefile.*: Makefile utility snippets #

Used by

  • $(MAKE) $(asm-generic)=<dir>
  • $(MAKE) $(build)=<dir>
  • $(MAKE) $(clean)=<dir>
  • $(MAKE) $(dtbinst)=<dir>
  • $(MAKE) $(hdr-inst)=<dir>

respectively as sub-make target.

Included by root Makefile if certain config option is turned on:

Makefile
# Include Additional Makefiles When Needed
include-y			:= scripts/Makefile.extrawarn
include-$(CONFIG_DEBUG_INFO)	+= scripts/Makefile.debug
include-$(CONFIG_DEBUG_INFO_BTF)+= scripts/Makefile.btf
include-$(CONFIG_KASAN)		+= scripts/Makefile.kasan
include-$(CONFIG_KCSAN)		+= scripts/Makefile.kcsan
include-$(CONFIG_KMSAN)		+= scripts/Makefile.kmsan
include-$(CONFIG_UBSAN)		+= scripts/Makefile.ubsan
include-$(CONFIG_KCOV)		+= scripts/Makefile.kcov
include-$(CONFIG_RANDSTRUCT)	+= scripts/Makefile.randstruct
include-$(CONFIG_GCC_PLUGINS)	+= scripts/Makefile.gcc-plugins

Included by the root Makefile if this make invocation will require a compiler:

Makefile
# Include This Also for Config Targets Because Some Architectures Need
# Cc-cross-prefix to Determine CROSS_COMPILE.
ifdef need-compiler
include $(srctree)/scripts/Makefile.compiler
endif

Included by root Makefile if CC is clang:

Makefile
ifneq ($(findstring clang,$(CC_VERSION_TEXT)),)
include $(srctree)/scripts/Makefile.clang
endif

Included by arch-specific Makefile if these 2 functions are needed.

find
./arch/arm/Makefile:308:include $(srctree)/scripts/Makefile.defconf
./arch/powerpc/Makefile:258:include $(srctree)/scripts/Makefile.defconf
./arch/riscv/Makefile:192:	$(Q)$(MAKE) -f $(srctree)/Makefile defconfig 32-bit.config
./arch/arm64/Makefile:205:include $(srctree)/scripts/Makefile.defconf

Used by rules in root Makefile as sub-make Makefile.

Makefile
modules_install:
    $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst \
    sign-only=$(if $(filter modules_install,$(MAKECMDGOALS)),,y)

modules: modpost
ifneq ($(KBUILD_MODPOST_NOFINAL),1)
	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal
endif

single_modules: $(single-no-ko) modules_prepare
	$(Q){ $(foreach m, $(single-ko), echo $(extmod_prefix)$(m:%.ko=%.o);) } > $(MODORDER)
	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
ifneq ($(KBUILD_MODPOST_NOFINAL),1)
	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal
endif
	$(Q)rm -f $(MODORDER)

PHONY += modpost
modpost: $(if $(single-build),, $(if $(KBUILD_BUILTIN), vmlinux.o)) \
	 $(if $(KBUILD_MODULES), modules_check)
	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
  • obj-y: collected from
  • obj-m: collected from subdirectory’s

scripts/Kbuild.include is included by many other Makefiles to provide utility functions. This section discusses the most commonly used ones.

cmd: print and execute commands #

makefile
# $(call Cmd, foo):
# # With Echo Supressed:
# if `cmd_foo` exist,
# print either `quiet_cmd_foo` or `cmd_foo` value as string
# Trap Interrupt
# Call Cmd_foo
# Else
# No-op
cmd = @$(if $(cmd_$(1)),set -e; $($(quiet)log_print) $(delete-on-interrupt) $(cmd_$(1)),:)

The cmd function should be used when you want to call certain Makefile functions and print to the terminal a message. It will respect the make V=[1|2] argument and determine whether to print verbose messages. You see prettified one-line messages during a kernel build thanks to this function, e.g.:

  LDS     scripts/module.lds
  HOSTCC  usr/gen_init_cpio
  CC      init/main.o
  CC      certs/system_keyring.o
  CC      ipc/compat.o
  CC      mm/filemap.o
  AS      arch/x86/entry/entry.o
  CC      fs/open.o
  AR      arch/x86/virt/vmx/built-in.a

To write an operation that fits into this framework, define 2 variables:

  1. a cmd_xxx that holds the actual shell script; and
  2. a quiet_cmd_xxx varaible contains a short message
makefile
quiet_cmd_makefile = GEN     Makefile
      cmd_makefile = { \
	echo "\# Automatically generated by $(srctree)/Makefile: don't edit"; \
	echo "include $(srctree)/Makefile"; \
	} > Makefile

Invoke your operation, whose output adapts to the required verbosity, by:

makefile
$(call cmd,makefile)

kbuild-file: get the path to the Makefile or Kbuild file under $(src) #

makefile
### # The Path to Kbuild or Makefile. Kbuild Has Precedence over Makefile.
kbuild-dir = $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file = $(or $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Makefile)

The caller must define an src variable before calling kbuild-file, which must be a directory name without the trailing slash.

For example:

makefile
# Snippet from: scripts/Makefile.build
# Obj Is an Export-ed Variable to This Submake
src := $(obj)

# Later ...
# include `$(obj)/Kbuild` or `$(obj)/Makefile`
include $(kbuild-file)
  • kbuild-file expands to the absolute path to the Kbuild file, or if absent, the Makefile, under src.
  • kbuild-dir is a helper macro never used independently.

Use these macros, instead of hardcoding $(src)/Makefile, for compatibility. Historically Makefile pieces shattered in each directory have the file name Kbuild. Almost all of them have been renamed to Makefile by the time of this writing, but some old device drivers may be still using Kbuild.

$(build): standard way of invoking sub-make #

$(Q)$(MAKE) $(build)=<dir> is the recommended way to invoke make in a subdirectory. ($(Q) expands to @ or empty, determining whether to echo the recipe.)

You will see recipes like the following one pervasively in Makefiles:

makefile
%config: outputmakefile scripts_basic FORCE
	$(Q)$(MAKE) $(build)=scripts/kconfig $@

build is defined as:

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

That is, without changing the current working directory, $(MAKE) $(build)=dir some-target uses scripts/Makefile.build as the Makefile, and executes its some-target goal with an obj=dir argument, where dir must be a directory name without the trailing slash. Most often, executing the default goal is desired, so some-target is omitted.

The scripts/Makefile.build sorely exist to support

There are 2 other shortcuts that work similarly:

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

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

The way scripts/Makefile.build works is rather intriguing, see below for details.

if_changed_*: #

makefile
### # If_changed      - Execute Command If Any Prerequisite Is Newer Than
# Target, or Command Line Has Changed
# If_changed_dep  - as If_changed, but Uses Fixdep to Reveal Dependencies
# Including Used Config Symbols
# If_changed_rule - as If_changed but Execute Rule Instead
# See Documentation/kbuild/makefiles.rst for More Info
# 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 = $(if $(if-changed-cond),$(rule_$(1)),@:)

# Execute the Command and Also Postprocess Generated .D Dependencies File.
if_changed_dep = $(if $(if-changed-cond),$(cmd_and_fixdep),@:)

if-changed-cond = $(newer-prereqs)$(cmd-check)$(check-FORCE)

# Find Any Prerequisites That Are Newer Than Target or That Do Not Exist.
# PHONY Targets Skipped in Both Cases.
# If There Is No Prerequisite Other Than Phony Targets, $(newer-prereqs) Becomes
# Empty Even If the Target Does Not Exist. Cmd-check Saves This Corner Case.
newer-prereqs = $(filter-out $(PHONY),$?)

scripts/Makefile.build: the module builder #

The purpose of scripts/Makefile.build is to make life easier for kernel module maintainers, such that only variable definition, and no rule, needs to be defined in a module-specific Makefile (rules can be added for documented behavior, see below).

When building a kernel subdirectory, the recommended $(MAKE) $(build)=dir syntax always runs a sub-make with the Makefile scripts/Makefile.build (via the -f option, see build for detail).

Among other scripting, this file includes the $(kbuild-file) (i.e. the Makefile in the dir as given in $(build)=dir, see kbuild-file for detail), and load a scripts/Makefile.lib to normalize the variables defined in the $(kbuild-file):

makefile
# scripts/Makefile.build
# Init Variables, Load Util Functions, Load Compiler Setups ...
include $(kbuild-file)
include $(srctree)/scripts/Makefile.lib

# Do Not Include Hostprogs Rules Unless Needed.
# $(sort ...) Is Used Here to Remove Duplicated Words and Excessive Spaces.
hostprogs := $(sort $(hostprogs))
ifneq ($(hostprogs),)
include $(srctree)/scripts/Makefile.host
endif

With this Makefile.build infrastrucutre, a classic module Makefile nowonly contains variable definitions. This example is from kernel/time/Makefile:

makefile
# SPDX-License-Identifier: GPL-2.0
obj-y += time.o timer.o hrtimer.o
obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o
obj-y += timeconv.o timecounter.o alarmtimer.o

ifeq ($(CONFIG_POSIX_TIMERS),y)
 obj-y += posix-timers.o posix-cpu-timers.o posix-clock.o itimer.o
else
 obj-y += posix-stubs.o
endif

obj-$(CONFIG_GENERIC_CLOCKEVENTS)		+= clockevents.o tick-common.o
ifeq ($(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST),y)
 obj-y						+= tick-broadcast.o
 obj-$(CONFIG_TICK_ONESHOT)			+= tick-broadcast-hrtimer.o
endif
obj-$(CONFIG_GENERIC_SCHED_CLOCK)		+= sched_clock.o
obj-$(CONFIG_TICK_ONESHOT)			+= tick-oneshot.o tick-sched.o
obj-$(CONFIG_LEGACY_TIMER_TICK)			+= tick-legacy.o
obj-$(CONFIG_HAVE_GENERIC_VDSO)			+= vsyscall.o
obj-$(CONFIG_DEBUG_FS)				+= timekeeping_debug.o
obj-$(CONFIG_TEST_UDELAY)			+= test_udelay.o
obj-$(CONFIG_TIME_NS)				+= namespace.o
obj-$(CONFIG_TEST_CLOCKSOURCE_WATCHDOG)		+= clocksource-wdtest.o
obj-$(CONFIG_TIME_KUNIT_TEST)			+= time_test.o

The whole purpose of scripts/Makefile.build is to make life

With all this trouble, scripts/Makefile.build, which powers the $(build)=dir pattern, makes writing a kernel module Makefile much easier.

it defines the value of the received $(obj)/ as its default goal; which depends on also note that $(obj)/ is listed as PHONY, so the target is simply a goal, and doesn’t represent the existing directory of the same name:

makefile
# scripts/Makefile.build
PHONY := $(obj)/
$(obj)/:

# Later ...
$(obj)/: $(if $(KBUILD_BUILTIN), $(targets-for-builtin)) \
	 $(if $(KBUILD_MODULES), $(targets-for-modules)) \
	 $(subdir-ym) $(always-y)
	@:

and:

Critical Variables #

  • hostprogs
  • need-config: whether the following execution requires loading .config configs as Makefile variables.

*.cmd files: file-specific dependency #

For almost all files generated during a build, there is a companion .cmd files also generate at build time.

  • ELF binaries, including - foo.o and .foo.o.cmd - .vdso64.so.cmd - .built-in.a.cmd
  • .modules.order.cmd
  • .unistd_64.h.cmd ./.vmlinux.cmd
  • .x86_pkg_temp_thermal.ko.cmd
  • .x86_pkg_temp_thermal.mod.cmd
  • .lexer.lex.c.cmd
  • include/config/auto.conf and ``include/config/auto.conf.cmd`

For a foo/bar/zoo, its companion foo/bar/.zoo.cmd file is a Makefile snippet that defines the following variable:

makefile
savecmd_<path> :=
source_<path> :=
deps_<path> :=

<path>: $(deps_<path>)

# Mark the Dependencies of Dependencies to Be Empty,
# Since We Compute the Transitive Closure Already for Make
$(deps_<path>):
makefile
savedcmd_vmlinux := ../scripts/link-vmlinux.sh "ld" "-m elf_x86_64 -z noexecstack --no-warn-rwx-segments" "--emit-relocs --discard-none -z max-page-size=0x200000 --build-id=sha1 --orphan-handling=error";  make -f ../arch/x86/Makefile.postlink vmlinux

source_vmlinux := ../scripts/link-vmlinux.sh

deps_vmlinux := \
    $(wildcard include/config/LTO_CLANG) \
    $(wildcard include/config/X86_KERNEL_IBT) \
    $(wildcard include/config/MODULES) \
    $(wildcard include/config/VMLINUX_MAP) \
    $(wildcard include/config/CPU_BIG_ENDIAN) \
    $(wildcard include/config/KALLSYMS_ALL) \
    $(wildcard include/config/KALLSYMS_ABSOLUTE_PERCPU) \
    $(wildcard include/config/KALLSYMS_BASE_RELATIVE) \
    $(wildcard include/config/SHELL) \
    $(wildcard include/config/DEBUG_INFO_BTF) \
    $(wildcard include/config/KALLSYMS) \
    $(wildcard include/config/BPF) \
    $(wildcard include/config/BUILDTIME_TABLE_SORT) \

vmlinux: $(deps_vmlinux)

$(deps_vmlinux):


source_foo/bar/zoo := ../kernel/pid.c
deps_foo/bar/zoo :=

Make Invocation #

The kernel supports multiple flavor of make invocation:

  • make

     make without goal
    
  • make [O=<dir>] *config

     This creates
    
     triggers `config-build := 1`
    
  • `make

Some build-optimization files pervasively exist in the

  1. the config process

    By invoking one of the `make *config` goal,
    
    - build a CLI prompt-based `conf` ELF executable or ncurses-based `mconf` in `scripts/kconfig/`;
    - end up with
           - `.config` file
           - `include/config/auto.conf`
           - `include/config/*`
           - `include/generated/autoconf.h`
    

The kernel uses sub-make. Whether sub-make is a good practice is debatable.

   logics of submake division of the linux kernel (which is also an pretty common and reasonable one):
   All sub-Makefile only modify / depends on the files in its own directory (and sub-directories that is not managed by a sub-Makefile).
   If some file depends on a file in another subMake directory to be up-to-date, a $`(Make)` calls should be invoked rather than
   typing literal depend on that file (in the dependency list).

Makefile Distribution #

Build Switch Macros #

  • __KERNEL__
  • __ASSEMBLY__

Kconfig Tree #

Makefile Analysis #

SUBARCH, ARCH, and SRCARCH #

Some variables are first setup in the Makefile at the very beginning of a make build. They are passed to Kconfig and Kbuild such that the generation of kernel config wizard works properly.

SUBARCH by the shell script in the scripts/subarch.include:

makefile
# Root Makefile:
# Include $(srctree)/scripts/subarch.include
# SUBARCH Tells the Usermode Build What the Underlying Arch Is.  That Is Set
# First, and If a Usermode Build Is Happening, the "ARCH=um" on the Command
# Line Overrides the Setting of ARCH Below.  If a Native Build Is Happening,
# Then ARCH Is Assigned, Getting Whatever Value It Gets Normally, And
# SUBARCH Is Subsequently Ignored.
SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
				  -e s/sun4u/sparc64/ \
				  -e s/arm.*/arm/ -e s/sa110/arm/ \
				  -e s/s390x/s390/ \
				  -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
				  -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
				  -e s/riscv.*/riscv/ -e s/loongarch.*/loongarch/)

The ARCH variable defaults to $(SUBARCH) if not explicitly given on the CLI as make ARCH=...:

makefile
ARCH		?= $(SUBARCH)

Using an explicit make ARCH=... is mandatory if you are cross-compiling the kernel for a different CPU architecture.

SRCARCH is derived from ARCH and is precisely one of the subdirectory names in arch/:

makefile
SRCARCH 	:= $(ARCH)

# Additional ARCH Settings for X86
ifeq ($(ARCH),i386)
        SRCARCH := x86
endif
ifeq ($(ARCH),x86_64)
        SRCARCH := x86
endif

# Additional ARCH Settings for Sparc
ifeq ($(ARCH),sparc32)
       SRCARCH := sparc
endif
ifeq ($(ARCH),sparc64)
       SRCARCH := sparc
endif

# Additional ARCH Settings for Parisc
ifeq ($(ARCH),parisc64)
       SRCARCH := parisc
endif

SRCARCH is used whenever architecture-dependent sources need to be referenced in the Makefiles or Kconfig files:

sh
# arch/Kconfig
# Note: arch/$(SRCARCH)/Kconfig Needs to Be Included First So That It Can
# Override the Default Values in This File.
# Source "arch/$(SRCARCH)/Kconfig"

Generated Content #

The following ordinary files are generated during a kernel build (.o and .name.*.cmd are ignored):

  • *.cmd:

     These are Makefile snippets. For `foo.bar`, there (usually) exists a `.foo.bar.cmd` containing a single rule
     that describes `foo.bar`'s dependency.
    
    
     usually they are hidden files (i.e. file name start with a dot), with the exception of `include/auto.conf.cmd`.
    
     not all .c and .h files has companion .cmd files. This is documented behavior
    
  • *.d files:

Module directory has the commmon files:

  • built-in.a:

  • modules.order:

  • include/config/*

     This directory contains
     - `auto.conf.cmd`:
     - `auto.conf`: in the same syntax as the `.config`
     - `kernel.release`:
     - empty files (around 1700 of them) with file name be kernel config options, 1 for each option whose value is `y` or `m`
    

2 directories are generated at build time, holding important headers:

  • $(objtree)/include/generated
  • $(objtree)/arch/x86/include/generated

A build will also create the directory include/config holding:

  • include/config/kernel.release

  • include/config/auto.conf.cmd

  • include/config/auto.conf

  • One empty file for each configs whose file name is …

  • include/generated

  • arch/<arch>/include/generated

Implementation Details #

After ignoring modules directory with only build-in.a and modules.order, we will end up with:

sh
./
├── arch/
│   ├── x86/
│   │   ├── boot/
│   │   │   ├── bzImage
│   │   │   ├── compressed/
│   │   │   │   ├── drivers/
│   │   │   │   │   └── firmware/
│   │   │   │   │       └── efi/
│   │   │   │   │           └── libstub/
│   │   │   │   ├── mkpiggy*
│   │   │   │   ├── piggy.S
│   │   │   │   ├── vmlinux*
│   │   │   │   ├── vmlinux.bin*
│   │   │   │   ├── vmlinux.bin.gz
│   │   │   │   ├── vmlinux.lds
│   │   │   │   └── vmlinux.relocs
│   │   │   ├── cpustr.h
│   │   │   ├── mkcpustr*
│   │   │   ├── setup.bin*
│   │   │   ├── setup.elf*
│   │   │   ├── tools/
│   │   │   │   ├── build*
│   │   │   ├── vmlinux.bin
│   │   │   ├── voffset.h
│   │   │   ├── zoffset.h
│   │   ├── crypto/
│   │   ├── entry/
│   │   │   ├── syscalls/
│   │   │   ├── vdso/
│   │   │   │   ├── vdso2c*
│   │   │   │   ├── vdso32/
│   │   │   │   │   ├── vdso32.lds
│   │   │   │   ├── vdso32.so*
│   │   │   │   ├── vdso32.so.dbg*
│   │   │   │   ├── vdso64.so*
│   │   │   │   ├── vdso64.so.dbg*
│   │   │   │   ├── vdso-image-32.c
│   │   │   │   ├── vdso-image-64.c
│   │   │   │   ├── vdso.lds
│   │   │   └── vsyscall/
│   │   ├── events/
│   │   │   ├── amd/
│   │   │   ├── intel/
│   │   │   └── zhaoxin/
│   │   ├── ia32/
│   │   ├── include/
│   │   │   └── generated/
│   │   │       ├── asm/
│   │   │       │   ├── early_ioremap.h
│   │   │       │   ├── irq_regs.h
│   │   │       │   ├── kmap_size.h
│   │   │       │   ├── local64.h
│   │   │       │   ├── mcs_spinlock.h
│   │   │       │   ├── mmiowb.h
│   │   │       │   ├── module.lds.h
│   │   │       │   ├── orc_hash.h
│   │   │       │   ├── rwonce.h
│   │   │       │   ├── syscalls_32.h
│   │   │       │   ├── syscalls_64.h
│   │   │       │   ├── unaligned.h
│   │   │       │   ├── unistd_32_ia32.h
│   │   │       │   ├── unistd_64_x32.h
│   │   │       └── uapi/
│   │   │           └── asm/
│   │   │               ├── bpf_perf_event.h
│   │   │               ├── errno.h
│   │   │               ├── fcntl.h
│   │   │               ├── ioctl.h
│   │   │               ├── ioctls.h
│   │   │               ├── ipcbuf.h
│   │   │               ├── param.h
│   │   │               ├── poll.h
│   │   │               ├── resource.h
│   │   │               ├── socket.h
│   │   │               ├── sockios.h
│   │   │               ├── termbits.h
│   │   │               ├── termios.h
│   │   │               ├── types.h
│   │   │               ├── unistd_32.h
│   │   │               ├── unistd_64.h
│   │   │               ├── unistd_x32.h
│   │   ├── kernel/
│   │   │   ├── acpi/
│   │   │   ├── apic/
│   │   │   ├── asm-offsets.s
│   │   │   ├── cpu/
│   │   │   │   ├── capflags.c
│   │   │   │   ├── mce/
│   │   │   │   ├── microcode/
│   │   │   │   ├── mtrr/
│   │   │   ├── fpu/
│   │   │   ├── kprobes/
│   │   │   ├── vmlinux.lds
│   │   ├── lib/
│   │   │   ├── inat-tables.c
│   │   │   ├── lib.a
│   │   ├── mm/
│   │   │   ├── pat/
│   │   ├── net/
│   │   ├── pci/
│   │   ├── platform/
│   │   │   ├── atom/
│   │   │   ├── ce4100/
│   │   │   ├── efi/
│   │   │   ├── geode/
│   │   │   ├── intel/
│   │   │   ├── intel-mid/
│   │   │   ├── intel-quark/
│   │   │   ├── iris/
│   │   │   ├── olpc/
│   │   │   ├── scx200/
│   │   │   ├── ts5500/
│   │   │   └── uv/
│   │   ├── power/
│   │   ├── realmode/
│   │   │   ├── rm/
│   │   │   │   ├── pasyms.h
│   │   │   │   ├── realmode.bin*
│   │   │   │   ├── realmode.elf*
│   │   │   │   ├── realmode.lds
│   │   │   │   ├── realmode.relocs
│   │   ├── tools/
│   │   │   ├── relocs*
│   │   └── virt/
│   │       └── vmx/
│   └── x86_64/
│       └── boot/
│           └── bzImage -> ../../x86/boot/bzImage
├── block/
│   └── partitions/
├── certs/
│   ├── extract-cert*
│   ├── signing_key.x509
│   ├── x509_certificate_list
├── .checked-atomic-arch-fallback.h
├── .checked-atomic-instrumented.h
├── .checked-atomic-long.h
├── .config
├── crypto/
│   ├── asymmetric_keys/
│   │   ├── pkcs7.asn1.c
│   │   ├── pkcs7.asn1.h
│   │   ├── x509_akid.asn1.c
│   │   ├── x509_akid.asn1.h
│   │   ├── x509.asn1.c
│   │   ├── x509.asn1.h
│   ├── rsaprivkey.asn1.c
│   ├── rsaprivkey.asn1.h
│   ├── rsapubkey.asn1.c
│   ├── rsapubkey.asn1.h
├── drivers/
│   ├── acpi/
│   │   ├── acpica/
│   │   ├── dptf/
│   │   ├── numa/
│   │   ├── pmic/
│   │   └── x86/
│   ├── amba/
│   ├── android/
│   ├── ata/
│   ├── auxdisplay/
│   ├── base/
│   │   ├── firmware_loader/
│   │   │   ├── builtin/
│   │   ├── power/
│   │   ├── regmap/
│   │   ├── test/
│   ├── block/
│   ├── bus/
│   │   ├── mhi/
│   ├── cache/
│   ├── cdrom/
│   ├── char/
│   │   ├── agp/
│   │   ├── hw_random/
│   │   ├── ipmi/
│   ├── clk/
│   │   ├── actions/
│   │   ├── analogbits/
│   │   ├── bcm/
│   │   ├── imgtec/
│   │   ├── imx/
│   │   ├── ingenic/
│   │   ├── mediatek/
│   │   ├── microchip/
│   │   ├── mstar/
│   │   ├── mvebu/
│   │   ├── ralink/
│   │   ├── renesas/
│   │   ├── socfpga/
│   │   ├── sprd/
│   │   ├── starfive/
│   │   ├── sunxi-ng/
│   │   ├── ti/
│   │   ├── versatile/
│   │   └── xilinx/
│   ├── clocksource/
│   ├── connector/
│   ├── cpufreq/
│   ├── cpuidle/
│   │   ├── governors/
│   ├── crypto/
│   │   ├── hisilicon/
│   │   ├── intel/
│   │   │   ├── ixp4xx/
│   │   │   ├── keembay/
│   │   ├── starfive/
│   │   ├── stm32/
│   │   └── xilinx/
│   ├── cxl/
│   │   ├── core/
│   ├── dax/
│   │   ├── hmem/
│   ├── dma/
│   │   ├── dw/
│   │   ├── hsu/
│   │   ├── idxd/
│   │   ├── mediatek/
│   │   ├── qcom/
│   │   ├── ti/
│   │   └── xilinx/
│   ├── dma-buf/
│   ├── firewire/
│   ├── firmware/
│   │   ├── arm_ffa/
│   │   ├── arm_scmi/
│   │   ├── broadcom/
│   │   ├── cirrus/
│   │   ├── efi/
│   │   │   ├── libstub/
│   │   │   │   ├── lib.a
│   │   ├── imx/
│   │   ├── meson/
│   │   ├── microchip/
│   │   ├── psci/
│   │   ├── qcom/
│   │   ├── smccc/
│   │   ├── tegra/
│   │   └── xilinx/
│   ├── gpu/
│   │   ├── drm/
│   │   │   ├── arm/
│   │   │   ├── bridge/
│   │   │   │   ├── analogix/
│   │   │   │   ├── cadence/
│   │   │   │   ├── imx/
│   │   │   │   └── synopsys/
│   │   │   ├── display/
│   │   │   ├── gud/
│   │   │   ├── hisilicon/
│   │   │   ├── i2c/
│   │   │   ├── i915/
│   │   │   │   ├── display/
│   │   │   │   ├── gem/
│   │   │   │   ├── gt/
│   │   │   │   │   └── uc/
│   │   │   │   ├── pxp/
│   │   │   │   ├── soc/
│   │   │   ├── imx/
│   │   │   ├── mxsfb/
│   │   │   ├── omapdrm/
│   │   │   ├── panel/
│   │   │   ├── renesas/
│   │   │   │   └── rcar-du/
│   │   │   ├── solomon/
│   │   │   ├── tests/
│   │   │   ├── tilcdc/
│   │   │   ├── tiny/
│   │   │   ├── ttm/
│   │   │   ├── virtio/
│   │   │   └── xlnx/
│   │   ├── host1x/
│   │   └── vga/
│   ├── hid/
│   │   └── usbhid/
│   ├── hwmon/
│   ├── hwtracing/
│   │   └── intel_th/
│   ├── i2c/
│   │   ├── algos/
│   │   ├── busses/
│   │   └── muxes/
│   ├── i3c/
│   ├── idle/
│   ├── input/
│   │   ├── joystick/
│   │   ├── keyboard/
│   │   ├── misc/
│   │   ├── mouse/
│   │   ├── serio/
│   │   ├── tablet/
│   │   ├── touchscreen/
│   ├── iommu/
│   │   ├── amd/
│   │   ├── arm/
│   │   │   ├── arm-smmu/
│   │   │   ├── arm-smmu-v3/
│   │   ├── intel/
│   │   ├── iommufd/
│   ├── irqchip/
│   ├── leds/
│   │   ├── blink/
│   │   ├── simple/
│   │   └── trigger/
│   ├── macintosh/
│   ├── mailbox/
│   ├── md/
│   ├── media/
│   │   ├── common/
│   │   │   ├── b2c2/
│   │   │   ├── saa7146/
│   │   │   ├── siano/
│   │   │   ├── v4l2-tpg/
│   │   │   └── videobuf2/
│   │   ├── firewire/
│   │   ├── i2c/
│   │   ├── mmc/
│   │   │   └── siano/
│   │   ├── pci/
│   │   │   ├── b2c2/
│   │   │   ├── ddbridge/
│   │   │   ├── dm1105/
│   │   │   ├── intel/
│   │   │   │   ├── ipu3/
│   │   │   │   ├── ivsc/
│   │   │   ├── mantis/
│   │   │   ├── netup_unidvb/
│   │   │   ├── ngene/
│   │   │   ├── pluto2/
│   │   │   ├── pt1/
│   │   │   ├── pt3/
│   │   │   ├── saa7146/
│   │   │   ├── smipcie/
│   │   │   └── ttpci/
│   │   ├── platform/
│   │   │   ├── allegro-dvt/
│   │   │   ├── amlogic/
│   │   │   │   ├── meson-ge2d/
│   │   │   ├── amphion/
│   │   │   ├── aspeed/
│   │   │   ├── atmel/
│   │   │   ├── cadence/
│   │   │   ├── chips-media/
│   │   │   │   ├── coda/
│   │   │   │   └── wave5/
│   │   │   ├── intel/
│   │   │   ├── marvell/
│   │   │   ├── mediatek/
│   │   │   │   ├── jpeg/
│   │   │   │   ├── mdp/
│   │   │   │   ├── mdp3/
│   │   │   │   ├── vcodec/
│   │   │   │   │   ├── common/
│   │   │   │   │   ├── decoder/
│   │   │   │   │   ├── encoder/
│   │   │   │   └── vpu/
│   │   │   ├── microchip/
│   │   │   ├── nuvoton/
│   │   │   ├── nvidia/
│   │   │   │   └── tegra-vde/
│   │   │   ├── nxp/
│   │   │   │   ├── dw100/
│   │   │   │   ├── imx8-isi/
│   │   │   │   ├── imx-jpeg/
│   │   │   ├── qcom/
│   │   │   │   ├── camss/
│   │   │   │   └── venus/
│   │   │   ├── renesas/
│   │   │   │   ├── rcar-vin/
│   │   │   │   ├── rzg2l-cru/
│   │   │   │   └── vsp1/
│   │   │   ├── rockchip/
│   │   │   │   ├── rga/
│   │   │   │   └── rkisp1/
│   │   │   ├── samsung/
│   │   │   │   ├── exynos4-is/
│   │   │   │   ├── exynos-gsc/
│   │   │   │   ├── s3c-camif/
│   │   │   │   ├── s5p-g2d/
│   │   │   │   ├── s5p-jpeg/
│   │   │   │   └── s5p-mfc/
│   │   │   ├── st/
│   │   │   │   ├── sti/
│   │   │   │   │   ├── bdisp/
│   │   │   │   │   ├── c8sectpfe/
│   │   │   │   │   ├── delta/
│   │   │   │   │   └── hva/
│   │   │   │   └── stm32/
│   │   │   ├── sunxi/
│   │   │   │   ├── sun4i-csi/
│   │   │   │   ├── sun6i-csi/
│   │   │   │   ├── sun6i-mipi-csi2/
│   │   │   │   ├── sun8i-a83t-mipi-csi2/
│   │   │   │   ├── sun8i-di/
│   │   │   │   └── sun8i-rotate/
│   │   │   ├── ti/
│   │   │   │   ├── am437x/
│   │   │   │   ├── cal/
│   │   │   │   ├── davinci/
│   │   │   │   ├── j721e-csi2rx/
│   │   │   │   ├── omap/
│   │   │   │   ├── omap3isp/
│   │   │   │   └── vpe/
│   │   │   ├── verisilicon/
│   │   │   ├── via/
│   │   │   └── xilinx/
│   │   ├── rc/
│   │   │   ├── keymaps/
│   │   ├── spi/
│   │   ├── test-drivers/
│   │   ├── tuners/
│   │   └── usb/
│   │       ├── b2c2/
│   │       ├── dvb-usb/
│   │       ├── dvb-usb-v2/
│   │       ├── s2255/
│   │       ├── siano/
│   │       ├── ttusb-budget/
│   │       └── ttusb-dec/
│   ├── mfd/
│   ├── misc/
│   │   ├── cardreader/
│   │   ├── cb710/
│   │   ├── eeprom/
│   │   ├── lis3lv02d/
│   │   ├── mei/
│   │   └── ti-st/
│   ├── mmc/
│   ├── net/
│   │   ├── ethernet/
│   │   │   ├── 3com/
│   │   │   ├── 8390/
│   │   │   ├── adaptec/
│   │   │   ├── agere/
│   │   │   ├── alacritech/
│   │   │   ├── alteon/
│   │   │   ├── amazon/
│   │   │   ├── amd/
│   │   │   ├── aquantia/
│   │   │   ├── arc/
│   │   │   ├── asix/
│   │   │   ├── atheros/
│   │   │   ├── broadcom/
│   │   │   ├── brocade/
│   │   │   ├── cadence/
│   │   │   ├── cavium/
│   │   │   │   ├── common/
│   │   │   │   ├── liquidio/
│   │   │   │   ├── octeon/
│   │   │   │   └── thunder/
│   │   │   ├── chelsio/
│   │   │   ├── cisco/
│   │   │   ├── cortina/
│   │   │   ├── dec/
│   │   │   │   └── tulip/
│   │   │   ├── dlink/
│   │   │   ├── emulex/
│   │   │   ├── engleder/
│   │   │   ├── ezchip/
│   │   │   ├── fujitsu/
│   │   │   ├── fungible/
│   │   │   ├── google/
│   │   │   ├── huawei/
│   │   │   ├── i825xx/
│   │   │   ├── intel/
│   │   │   │   ├── e1000/
│   │   │   │   ├── e1000e/
│   │   │   ├── litex/
│   │   │   ├── marvell/
│   │   │   │   ├── octeon_ep/
│   │   │   │   ├── octeontx2/
│   │   │   │   ├── prestera/
│   │   │   ├── mellanox/
│   │   │   ├── micrel/
│   │   │   ├── microchip/
│   │   │   ├── microsoft/
│   │   │   ├── mscc/
│   │   │   ├── myricom/
│   │   │   ├── natsemi/
│   │   │   ├── neterion/
│   │   │   ├── netronome/
│   │   │   ├── ni/
│   │   │   ├── nvidia/
│   │   │   ├── oki-semi/
│   │   │   ├── packetengines/
│   │   │   ├── pensando/
│   │   │   ├── qlogic/
│   │   │   ├── qualcomm/
│   │   │   │   ├── emac/
│   │   │   ├── rdc/
│   │   │   ├── realtek/
│   │   │   ├── renesas/
│   │   │   ├── rocker/
│   │   │   ├── samsung/
│   │   │   ├── seeq/
│   │   │   ├── sfc/
│   │   │   ├── silan/
│   │   │   ├── sis/
│   │   │   ├── smsc/
│   │   │   ├── socionext/
│   │   │   ├── stmicro/
│   │   │   ├── sun/
│   │   │   ├── synopsys/
│   │   │   ├── tehuti/
│   │   │   ├── ti/
│   │   │   ├── vertexcom/
│   │   │   ├── via/
│   │   │   ├── wangxun/
│   │   │   ├── wiznet/
│   │   │   ├── xilinx/
│   │   │   └── xircom/
│   │   ├── mdio/
│   │   ├── pcs/
│   │   ├── phy/
│   │   ├── pse-pd/
│   │   ├── usb/
│   │   └── wireless/
│   │       ├── admtek/
│   │       ├── ath/
│   │       ├── atmel/
│   │       ├── broadcom/
│   │       ├── intel/
│   │       ├── intersil/
│   │       ├── marvell/
│   │       ├── mediatek/
│   │       ├── microchip/
│   │       ├── purelifi/
│   │       ├── quantenna/
│   │       ├── ralink/
│   │       ├── realtek/
│   │       ├── rsi/
│   │       ├── silabs/
│   │       ├── st/
│   │       ├── ti/
│   │       ├── virtual/
│   │       └── zydas/
│   ├── nfc/
│   ├── nvme/
│   │   ├── common/
│   │   ├── host/
│   │   └── target/
│   ├── nvmem/
│   │   ├── layouts/
│   ├── pci/
│   │   ├── controller/
│   │   │   ├── dwc/
│   │   │   ├── mobiveil/
│   │   ├── hotplug/
│   │   ├── msi/
│   │   ├── pcie/
│   │   ├── switch/
│   ├── pcmcia/
│   ├── perf/
│   ├── platform/
│   │   ├── surface/
│   │   └── x86/
│   │       ├── amd/
│   │       ├── intel/
│   ├── pnp/
│   │   ├── pnpacpi/
│   ├── power/
│   │   └── supply/
│   ├── pps/
│   │   ├── clients/
│   │   ├── generators/
│   ├── ptp/
│   ├── pwm/
│   ├── rtc/
│   ├── scsi/
│   │   ├── pcmcia/
│   │   ├── scsi_devinfo_tbl.c
│   ├── soc/
│   │   ├── amlogic/
│   │   ├── apple/
│   │   ├── aspeed/
│   │   ├── bcm/
│   │   ├── fsl/
│   │   ├── fujitsu/
│   │   ├── hisilicon/
│   │   ├── imx/
│   │   ├── ixp4xx/
│   │   ├── loongson/
│   │   ├── mediatek/
│   │   ├── microchip/
│   │   ├── nuvoton/
│   │   ├── pxa/
│   │   ├── qcom/
│   │   ├── renesas/
│   │   ├── rockchip/
│   │   ├── sunxi/
│   │   ├── ti/
│   │   └── xilinx/
│   ├── thermal/
│   │   ├── broadcom/
│   │   ├── intel/
│   │   │   ├── x86_pkg_temp_thermal.ko
│   │   │   ├── x86_pkg_temp_thermal.mod
│   │   │   ├── x86_pkg_temp_thermal.mod.c
│   │   ├── mediatek/
│   │   ├── qcom/
│   │   ├── samsung/
│   │   ├── st/
│   │   ├── tegra/
│   ├── tty/
│   │   ├── hvc/
│   │   ├── ipwireless/
│   │   ├── serial/
│   │   │   ├── 8250/
│   │   └── vt/
│   │       ├── conmakehash*
│   │       ├── consolemap_deftbl.c
│   │       ├── defkeymap.c
│   ├── ufs/
│   ├── usb/
│   │   ├── class/
│   │   ├── common/
│   │   ├── core/
│   │   ├── early/
│   │   ├── host/
│   │   ├── misc/
│   │   ├── mon/
│   │   ├── phy/
│   │   └── storage/
│   ├── video/
│   │   ├── backlight/
│   │   ├── console/
│   │   ├── fbdev/
│   │   │   ├── core/
│   │   │   ├── omap/
│   │   │   └── omap2/
│   │   │       └── omapfb/
│   │   │           ├── displays/
│   │   │           ├── dss/
│   ├── virtio/
│   └── watchdog/
├── fs/
│   ├── 9p/
│   ├── autofs/
│   ├── debugfs/
│   ├── devpts/
│   ├── efivarfs/
│   │   ├── efivarfs.ko
│   │   ├── efivarfs.mod
│   │   ├── efivarfs.mod.c
│   ├── exportfs/
│   ├── ext4/
│   ├── fat/
│   ├── hostfs/
│   ├── hugetlbfs/
│   ├── iomap/
│   ├── isofs/
│   ├── jbd2/
│   ├── kernfs/
│   ├── lockd/
│   ├── netfs/
│   ├── nfs/
│   ├── nfs_common/
│   ├── nls/
│   ├── notify/
│   │   ├── dnotify/
│   │   ├── fanotify/
│   │   ├── inotify/
│   ├── proc/
│   ├── quota/
│   ├── ramfs/
│   ├── sysfs/
│   ├── tracefs/
│   ├── unicode/
├── .gitignore
├── include/
│   ├── config/     #
│   └── generated/
│       ├── asm-offsets.h
│       ├── autoconf.h
│       ├── bounds.h
│       ├── compile.h
│       ├── rustc_cfg
│       ├── timeconst.h
│       ├── uapi/
│       │   └── linux/
│       │       └── version.h
│       ├── utsrelease.h
│       └── utsversion.h
├── init/
│   ├── utsversion-tmp.h
├── io_uring/
├── ipc/
├── kernel/
│   ├── bounds.s
│   ├── bpf/
│   ├── cgroup/
│   ├── dma/
│   ├── entry/
│   ├── events/
│   ├── futex/
│   ├── irq/
│   ├── livepatch/
│   ├── locking/
│   ├── module/
│   ├── power/
│   ├── printk/
│   ├── rcu/
│   ├── sched/
│   ├── time/
│   ├── trace/
├── lib/
│   ├── crc32table.h
│   ├── crypto/
│   │   ├── mpi/
│   ├── dim/
│   ├── fonts/
│   ├── gen_crc32table*
│   ├── lib.a
│   ├── lz4/
│   ├── lzo/
│   ├── math/
│   ├── oid_registry_data.c
│   ├── test_fortify/
│   ├── xz/
│   ├── zlib_deflate/
│   ├── zlib_inflate/
│   └── zstd/
│       ├── common/
│       ├── decompress/
├── Makefile
├── mm/
├── modules.builtin
├── modules.builtin.modinfo
├── Module.symvers
├── net/
│   ├── 802/
│   ├── 9p/
│   ├── bpf/
│   ├── core/
│   ├── dns_resolver/
│   ├── dsa/
│   ├── ethernet/
│   ├── ethtool/
│   ├── handshake/
│   ├── ipv4/
│   │   ├── netfilter/
│   │   │   ├── iptable_nat.ko
│   │   │   ├── iptable_nat.mod
│   │   │   ├── iptable_nat.mod.c
│   ├── ipv6/
│   │   ├── netfilter/
│   ├── mac80211/
│   │   ├── tests/
│   ├── netfilter/
│   │   ├── nf_log_syslog.ko
│   │   ├── nf_log_syslog.mod
│   │   ├── nf_log_syslog.mod.c
│   │   ├── xt_addrtype.ko
│   │   ├── xt_addrtype.mod
│   │   ├── xt_addrtype.mod.c
│   │   ├── xt_LOG.ko
│   │   ├── xt_LOG.mod
│   │   ├── xt_LOG.mod.c
│   │   ├── xt_mark.ko
│   │   ├── xt_mark.mod
│   │   ├── xt_mark.mod.c
│   │   ├── xt_MASQUERADE.ko
│   │   ├── xt_MASQUERADE.mod
│   │   ├── xt_MASQUERADE.mod.c
│   │   ├── xt_nat.ko
│   │   ├── xt_nat.mod
│   │   ├── xt_nat.mod.c
│   ├── netlabel/
│   ├── netlink/
│   ├── packet/
│   ├── rfkill/
│   ├── sched/
│   ├── sunrpc/
│   │   ├── auth_gss/
│   ├── unix/
│   ├── wireless/
│   │   ├── shipped-certs.c
│   │   ├── tests/
│   └── xfrm/
├── scripts/
│   ├── asn1_compiler*
│   ├── basic/
│   │   ├── fixdep*
│   ├── gcc-plugins/
│   ├── kallsyms*
│   ├── kconfig/
│   │   ├── conf*
│   │   ├── lexer.lex.c
│   │   ├── lxdialog/
│   │   ├── mconf*
│   │   ├── mconf-bin
│   │   ├── mconf-cflags
│   │   ├── mconf-libs
│   │   ├── parser.tab.c
│   │   ├── parser.tab.h
│   ├── mod/
│   │   ├── devicetable-offsets.h
│   │   ├── devicetable-offsets.s
│   │   ├── elfconfig.h
│   │   ├── mk_elfconfig*
│   │   ├── modpost*
│   ├── module.lds
│   ├── selinux/
│   │   ├── genheaders/
│   │   │   ├── genheaders*
│   │   └── mdp/
│   │       ├── mdp*
│   ├── sorttable*
├── security/
│   ├── integrity/
│   ├── keys/
│   └── selinux/
│       ├── av_permissions.h
│       ├── flask.h
│       ├── ss/
├── sound/
│   ├── arm/
│   ├── atmel/
│   ├── core/
│   │   ├── seq/
│   ├── drivers/
│   │   ├── mpu401/
│   │   ├── opl3/
│   │   ├── opl4/
│   │   ├── pcsp/
│   │   └── vx/
│   ├── firewire/
│   ├── hda/
│   ├── i2c/
│   │   └── other/
│   ├── isa/
│   │   ├── ad1816a/
│   │   ├── ad1848/
│   │   ├── cs423x/
│   │   ├── es1688/
│   │   ├── galaxy/
│   │   ├── gus/
│   │   ├── msnd/
│   │   ├── opti9xx/
│   │   ├── sb/
│   │   ├── wavefront/
│   │   └── wss/
│   ├── mips/
│   ├── parisc/
│   ├── pci/
│   │   ├── ac97/
│   │   ├── ali5451/
│   │   ├── asihpi/
│   │   ├── au88x0/
│   │   ├── aw2/
│   │   ├── ca0106/
│   │   ├── cs46xx/
│   │   ├── cs5535audio/
│   │   ├── ctxfi/
│   │   ├── echoaudio/
│   │   ├── emu10k1/
│   │   ├── hda/
│   │   ├── ice1712/
│   │   ├── korg1212/
│   │   ├── lola/
│   │   ├── lx6464es/
│   │   ├── mixart/
│   │   ├── nm256/
│   │   ├── oxygen/
│   │   ├── pcxhr/
│   │   ├── riptide/
│   │   ├── rme9652/
│   │   ├── trident/
│   │   ├── vx222/
│   │   └── ymfpci/
│   ├── pcmcia/
│   │   ├── pdaudiocf/
│   │   └── vx/
│   ├── ppc/
│   ├── sh/
│   ├── soc/
│   ├── sparc/
│   ├── spi/
│   ├── synth/
│   │   ├── emux/
│   ├── usb/
│   │   ├── 6fire/
│   │   ├── bcd2000/
│   │   ├── caiaq/
│   │   ├── hiface/
│   │   ├── misc/
│   │   └── usx2y/
│   ├── virtio/
│   ├── x86/
│   └── xen/
├── source -> ../
├── System.map
├── t
├── .tmp_vmlinux.kallsyms1*
├── .tmp_vmlinux.kallsyms1.S
├── .tmp_vmlinux.kallsyms1.syms
├── .tmp_vmlinux.kallsyms2*
├── .tmp_vmlinux.kallsyms2.S
├── .tmp_vmlinux.kallsyms2.syms
├── tools/
│   └── objtool/
│       ├── arch/
│       │   └── x86/
│       │       ├── lib/
│       │       │   └── inat-tables.c
│       ├── fixdep*
│       ├── libsubcmd/
│       │   ├── include/
│       │   │   └── subcmd/
│       │   │       ├── exec-cmd.h
│       │   │       ├── help.h
│       │   │       ├── pager.h
│       │   │       ├── parse-options.h
│       │   │       └── run-command.h
│       │   ├── libsubcmd.a
│       ├── objtool*
├── tt
├── usr/
│   ├── gen_init_cpio*
│   ├── initramfs_data.cpio
│   ├── initramfs_inc_data
├── .version
├── virt/
│   ├── lib/
├── vmlinux*
├── vmlinux.a
├── .vmlinux.export.c

Misc #

all include from root makefile

makefile
include $(srctree)/scripts/Kbuild.include
include $(srctree)/scripts/subarch.include

include $(srctree)/scripts/Makefile.clang
include $(srctree)/scripts/Makefile.compiler
include $(srctree)/arch/$(SRCARCH)/Makefile

ifdef need-config
include include/config/auto.conf
endif

include $(srctree)/arch/$(SRCARCH)/Makefile
include include/config/auto.conf.cmd
include $(addprefix $(srctree)/, $(include-y))

Techniques: Ensure a File Has Been Generated #

file-name target with no dependency is considered always up-to-date, unless that file doesn’t exist (i.e. effectively becomes a PHONY):

makefile
# $(KCONFIG_CONFIG) defaults to `.config`.
# Whenever make finds that the `.config` file doesn't exist thus the recipe needs to be executed, it's a problem
$(KCONFIG_CONFIG):
	@echo >&2 '***'
	@echo >&2 '*** Configuration file "$@" not found!'
	@echo >&2 '***'
	@echo >&2 '*** Please run some configurator (e.g. "make oldconfig" or'
	@echo >&2 '*** "make menuconfig" or "make xconfig").'
	@echo >&2 '***'
	@/bin/false

Comments

Read or comment on GitHub (sign-in required to comment)