Makefile Manager
Dividimos el Makefile en submódulos, cada uno con su
propia lógica de construcción. Un
Makefile Manager (Makefile) en la raíz
orquesta la ejecución de los demás.
-
✅ Cada módulo tiene su propio
makefile.mk -
✅ El
Makefileen la raíz coordina todo - ✅ Evita duplicación de código y mejora mantenimiento
📌 Ubicación de los archivos en la estructura del proyecto:
/OSProject ├── build/ ├── configs/ │ ├── config.mk # Configuración general │ ├── architecture.mk # Configuración específica por arquitectura │ ├── dependencies.mk # Manejo de dependencias externas ├── doc/ ├── scripts/ │ ├── build.sh │ ├── run_debug.sh │ └── run_qemu.sh ├── src/ │ ├── arch/ │ ├── kernel/ │ ├── drivers/ ├── third_party/ ├── tools/ ├── Makefile # Gestor principal └── README.md
1. Makefile (Makefile Manager) 📌
Este archivo gestiona la ejecución de los demás submódulos:
# Carga los módulos
include configs/config.mk
include configs/architecture.mk
include configs/dependencies.mk
# Orquestación de las funciones
.PHONY: all clean compile run debug iso
all: structure dependencies compile
structure:
@$(MAKE) -C configs structure
dependencies:
@$(MAKE) -C configs dependencies
compile:
@$(MAKE) -C src compile
clean:
@$(MAKE) -C configs clean
@$(MAKE) -C src clean
run:
@$(MAKE) -C scripts run_qemu.sh $(ARCH)
debug:
@$(MAKE) -C scripts run_debug.sh $(ARCH)
iso:
@$(MAKE) -C configs generate_iso
2. configs/config.mk (Configuración General)
Define variables y estructura del proyecto.
# Directorios principales
ROOT_DIRS := build doc src tools configs scripts third_party
BUILD_DIRS := build/x86_16 build/x86_32 build/x86_64 build/arm build/tools
.PHONY: structure clean
structure:
@echo "Creando estructura..."
@mkdir -p $(ROOT_DIRS) $(BUILD_DIRS)
@echo "Estructura creada correctamente."
clean:
@echo "Limpiando..."
@rm -rf $(ROOT_DIRS)
@echo "Estructura eliminada."
3. configs/architecture.mk (Gestión de Arquitecturas)
Selecciona herramientas según la arquitectura.
ARCH ?= x86_64
ifeq ($(ARCH), x86_16)
AS := nasm
ASFLAGS := -f bin
LD := ld
LDFLAGS := -m i8086
OUTPUT_FILE := build/x86_16/boot.bin
elifeq ($(ARCH), x86_32)
AS := nasm
ASFLAGS := -f elf32
LD := ld
LDFLAGS := -m elf_i386 -T configs/linker_32.ld
OUTPUT_FILE := build/x86_32/kernel_32.elf
elifeq ($(ARCH), x86_64)
AS := nasm
ASFLAGS := -f elf64
LD := ld
LDFLAGS := -m elf_x86_64 -T configs/linker_64.ld
OUTPUT_FILE := build/x86_64/kernel_64.elf
elifeq ($(ARCH), arm)
AS := arm-none-eabi-as
ASFLAGS := -mcpu=arm926ej-s
LD := arm-none-eabi-ld
LDFLAGS := -T configs/linker_arm.ld
OUTPUT_FILE := build/arm/kernel_arm.elf
else
$(error "Arquitectura no soportada: $(ARCH)")
endif
4. configs/dependencies.mk (Manejo de Dependencias)
Instala y gestiona librerías externas.
DEPS_DIR := third_party
LIBC_VERSION := 1.2.0
BOOTLOADER_VERSION := 0.8.5
NETWORK_STACK_VERSION := 2.1.3
.PHONY: dependencies
dependencies:
@echo "Instalando dependencias..."
@mkdir -p $(DEPS_DIR)/libc-$(LIBC_VERSION) $(DEPS_DIR)/bootloader-$(BOOTLOADER_VERSION) $(DEPS_DIR)/network_stack-$(NETWORK_STACK_VERSION)
@echo "Dependencias instaladas correctamente."
5. configs/generate_iso.mk (Generación de ISO)
Crea una imagen ISO arrancable.
ISO_DIR := iso
ISO_FILE := build/osproject.iso
.PHONY: generate_iso
generate_iso:
@echo "Creando imagen ISO..."
@mkdir -p $(ISO_DIR)/boot
@cp build/$(ARCH)/kernel.elf $(ISO_DIR)/boot/
@grub-mkrescue -o $(ISO_FILE) $(ISO_DIR)
@echo "Imagen ISO generada exitosamente."
6. src/Makefile.mk (Compilación del Kernel)
Compila el kernel y módulos.
include ../configs/architecture.mk
.PHONY: compile clean
compile:
@echo "Compilando el kernel..."
@$(AS) $(ASFLAGS) src/arch/$(ARCH)/boot.asm -o $(OUTPUT_FILE)
@$(LD) $(LDFLAGS) -o $(OUTPUT_FILE) src/kernel/main.o
@echo "Compilación finalizada."
clean:
@echo "Limpiando compilación..."
@rm -f $(OUTPUT_FILE)
7. scripts/Makefile.mk (Ejecución y Depuración)
Lógica para correr en QEMU y debug con GDB.
.PHONY: run debug
run:
@bash scripts/run_qemu.sh $(ARCH)
debug:
@bash scripts/run_debug.sh $(ARCH)
🔹 Ventajas del Makefile Modular
- ✅ Escalabilidad: Fácil de modificar o extender.
- ✅ Mayor claridad: Cada módulo tiene su propia lógica de construcción.
- ✅ Mejor mantenimiento: Evita repetir configuraciones innecesarias.
- ✅ Automatización completa: Desde la estructura hasta la ejecución y depuración.

Comentarios
Publicar un comentario