c linux makefile linux-kernel kbuild

¿Cómo funciona realmente kbuild?



linux makefile (1)

Los Makefiles de Kbuild no son los más fáciles de leer, pero aquí hay un desenredo de alto nivel (usando el kernel 4.0-rc3):

  1. El Makefile de nivel superior hace

    include $(srctree)/scripts/Kbuild.include

    , donde $(srctree) es el directorio del kernel de nivel superior.

  2. Kbuild.include define varias cosas comunes y ayudantes. Entre estos se encuentra la build :

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

    build se usa con un comando como $(MAKE) $(build)=dir para realizar la compilación del directorio dir . Hace uso de scripts/Makefile.build .

  3. Volviendo al Makefile de nivel superior, hay lo siguiente:

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

    vmlinux-dirs contiene una lista de subdirectorios para compilar ( init , usr , kernel , etc.). $(Q)$(MAKE) $(build)=<subdirectory> se ejecutará para cada subdirectorio.

    La regla anterior compila archivos de objetos tanto para la imagen del kernel como para los módulos. Más abajo en el Makefile de nivel superior, hay algunas cosas adicionales específicas del módulo:

    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. Buscando en scripts/Makefile.build (el Makefile usado por $(build) ) ahora, comienza por inicializar las listas obj-* y varias otras listas:

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

    Un poco más abajo, se carga en el archivo Kbuild donde se establecen obj-y , obj-m , etc.

    include $(kbuild-file)

    Más abajo está la regla predeterminada, que tiene las listas $(obj-y) y $(obj-m) como requisitos previos:

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

    Los requisitos previos de $(obj-y) provienen de $(builtin-target) , que se define de la siguiente manera:

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

    El edificio real parece ser realizado por la siguiente regla:

    # 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 es de Kbuild.include . La regla termina ejecutando los siguientes comandos en 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) parece ser el comando de compilación real. La definición habitual (hay dos posibilidades en Makefile.build , AFAICS) parece ser la siguiente:

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

    A menos que se establezca explícitamente utilizando, por ejemplo, make CC=clang , CC defecto en gcc , como se puede ver aquí en el Makefile de nivel superior:

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

La forma en que lo desenredé fue haciendo una CTRL-C durante una compilación del kernel y viendo dónde cometió el error. Otra técnica práctica de make depuración es usar $(warning $(variable)) para imprimir el valor de la variable .

Cuando estoy desarrollando un controlador de linux, he leído acerca de cómo escribir linux kbuild makefile a través de este document

Sé que el sistema kbuild usa variables makefile como obj-y obj-m para determinar qué construir y cómo construir.

Pero lo que me confunde es dónde el sistema kbuild realmente ejecuta el proceso de compilación. En una palabra, si tengo obj-m = ao , entonces ¿dónde el sistema kbuild analiza obj-m y ejecuta gcc ac ?