Teste do Makefile do Kernel Linux

Este artigo foca na criação de um projeto de teste simplificado baseado nos princípios do sistema de Makefiles do kernel Linux. Ele serve como uma ferramenta prática para compreender a arquitetura de compilação do kernel, destacando características como modularidade e configuração cruzada.

Estrutura do Código-Fonte

A organização inclui um diretório raiz com cinco subdiretórios: add, sub, main, scripts e um diretório de saída. O sistema de build consiste em um Makefile principal, quatro scripts no diretório scripts, e Makefiles individuais em cada subdiretório de módulo. Os prgoramas em C estão localizados em add/add.c, sub/sub.c e main/main.c.

Implemnetação dos Makefiles

Makefile Raiz

.PHONY: all clean

CMD_MAKE := make

SRC_ROOT := $(or $(KBUILD_SRC), $(CURDIR))
export SRC_ROOT

# Ferramentas de compilação
ASM_PROC = $(CROSS_COMPILE)as
LINK_TOOL = $(CROSS_COMPILE)ld
CC_TOOL = $(CROSS_COMPILE)gcc
CPP_TOOL = $(CC_TOOL) -E
AR_TOOL = $(CROSS_COMPILE)ar
NM_TOOL = $(CROSS_COMPILE)nm

export ASM_PROC LINK_TOOL CC_TOOL CPP_TOOL AR_TOOL NM_TOOL

include $(SRC_ROOT)/scripts/Kbuild.inc

all: complete_target

MODULE_DIRS := add sub main
.PHONY: $(MODULE_DIRS)

OUTPUT_DIRS := $(MODULE_DIRS)
.PHONY: $(OUTPUT_DIRS)

complete_target: $(MODULE_DIRS)
    $(CC_TOOL) -o $@ add/built-in.o sub/built-in.o main/built-in.o

$(MODULE_DIRS):
    $(CMD_MAKE) $(build)=$@

CLEAN_LIST := $(addprefix purge_, $(OUTPUT_DIRS))
.PHONY: $(CLEAN_LIST) clean

$(CLEAN_LIST):
    $(CMD_MAKE) $(clean)=$(patsubst purge_%,%, $@)

clean: $(CLEAN_LIST)
    rm -f complete_target

clean := -f scripts/Makefile.clean obj

.PHONY: all clean

Script de Compilação (scripts/Makefile.build)

# Processo de construção
SOURCE_PATH := $(OBJ_DIR)

.PHONY: compile_all
compile_all:

include scripts/Kbuild.inc

DIR_TARGET := $(if $(filter /%, $(SOURCE_PATH)), $(SOURCE_PATH), $(SRC_ROOT)/$(SOURCE_PATH))
BUILD_FILE := $(if $(wildcard $(DIR_TARGET)/Kbuild), $(DIR_TARGET)/Kbuild, $(DIR_TARGET)/Makefile)
include $(BUILD_FILE)

include scripts/Makefile.lib

ifneq ($(strip $(obj-y)),)
OUTPUT_OBJ := $(OBJ_DIR)/built-in.o
endif

compile_all: $(OUTPUT_OBJ)

CMD_LINK_OBJECT = $(if $(strip $(obj-y)), \
              $(LINK_TOOL) $(ld_flags) -r -o $@ $(filter $(obj-y), $^))

$(OUTPUT_OBJ): $(obj-y)
    $(call if_changed, link_object)

CMD_COMPILE_C = $(CC_TOOL) $(c_flags) -c -o $@ $<

define RULE_COMPILE_C
    $(CMD_COMPILE_C)
endef

$(OBJ_DIR)/%.o: $(SOURCE_PATH)/%.c
    $(call if_changed_rule, compile_c)

.PHONY: FORCE
FORCE:

.PHONY: compile_all

Definições de Funções (scripts/Kbuild.inc)

build := -f scripts/Makefile.build obj

if_changed = $(CMD_$(1))

if_changed_rule = $(RULE_$(1))

Opções de Compilação (scripts/Makefile.lib)

c_flags =

ld_flags = $(LDFLAGS) $(ldflags-y)

obj-y := $(patsubst %/, %/built-in.o, $(obj-y))
obj-y := $(addprefix $(OBJ_DIR)/, $(obj-y))

Script de Limpeza (scripts/Makefile.clean)

# Rotina de limpeza
CLEAN_SRC := $(OBJ_DIR)

.PHONY: perform_clean
perform_clean:

perform_clean:
    rm -f $(CLEAN_SRC)/*.o

Makefile do Módulo Add (add/Makefile)

obj-y += add.o

Limitações do Projeto Atual

  • O sistema não implementa geração automática de dependências entre arquivos.
  • Não há suporte para compilar em um diretório de saída separado do código-fonte.

Tags: Linux Kernel Makefile C Language Build System GNU Make

Publicado em 6-1 13:43 por Thomas