Newer
Older
CubeCactusCpp / Makefile.os
@agalyaramadoss agalyaramadoss on 6 Dec 6 KB shell impelment
# CubeCactusOS Makefile
# Build system for custom MINIX3-based operating system

# Compiler and tools
# Detect OS and set appropriate tools
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
    # macOS - check for cross-compiler (try multiple variants)
    ifeq ($(shell which i386-elf-gcc 2>/dev/null),)
        ifeq ($(shell which x86_64-elf-gcc 2>/dev/null),)
            # No cross-compiler found
            $(error Cross-compiler not found. Install with: brew tap nativeos/i386-elf-toolchain && brew install i386-elf-binutils i386-elf-gcc)
        else
            # Use x86_64-elf cross-compiler in 32-bit mode
            CC = x86_64-elf-gcc
            LD = x86_64-elf-ld
            CFLAGS_ARCH = -m32
            LDFLAGS_ARCH = -m elf_i386 -T $(BOOT_DIR)/linker.ld -nostdlib
            USE_NATIVE = 0
        endif
    else
        # Use i386-elf cross-compiler
        CC = i386-elf-gcc
        LD = i386-elf-ld
        CFLAGS_ARCH = -m32
        LDFLAGS_ARCH = -T $(BOOT_DIR)/linker.ld -nostdlib
        USE_NATIVE = 0
    endif
    AS = nasm
    ASFLAGS = -f elf32
else
    # Linux
    CC = gcc
    AS = nasm
    LD = ld
    ASFLAGS = -f elf32
    CFLAGS_ARCH = -m32
    LDFLAGS_ARCH = -m elf_i386 -T $(BOOT_DIR)/linker.ld -nostdlib
    USE_NATIVE = 0
endif

QEMU = qemu-system-i386

# Try different GRUB variants
ifeq ($(shell which grub-mkrescue 2>/dev/null),)
    ifeq ($(shell which grub2-mkrescue 2>/dev/null),)
        ifeq ($(shell which i686-elf-grub-mkrescue 2>/dev/null),)
            GRUB_MKRESCUE = 
        else
            GRUB_MKRESCUE = i686-elf-grub-mkrescue
        endif
    else
        GRUB_MKRESCUE = grub2-mkrescue
    endif
else
    GRUB_MKRESCUE = grub-mkrescue
endif

# Compiler flags
CFLAGS = $(CFLAGS_ARCH) -ffreestanding -fno-builtin -fno-stack-protector -O2 -Wall -Wextra -I$(KERNEL_DIR)
ifeq ($(USE_NATIVE),1)
    LDFLAGS = $(LDFLAGS_ARCH)
else
    LDFLAGS = $(LDFLAGS_ARCH)
endif

# Directories
KERNEL_DIR = os/kernel
SERVER_DIR = os/servers
DRIVER_DIR = os/drivers
USERLAND_DIR = os/userland
LIB_DIR = os/lib
BOOT_DIR = os/boot
BUILD_DIR = os/build
ISO_DIR = $(BUILD_DIR)/isodir

# Source files
KERNEL_SRCS = $(wildcard $(KERNEL_DIR)/*.c)
SERVER_SRCS = $(wildcard $(SERVER_DIR)/*.c)
DRIVER_SRCS = $(wildcard $(DRIVER_DIR)/*.c)
LIB_SRCS = $(wildcard $(LIB_DIR)/*.c)
USERLAND_SRCS = $(wildcard $(USERLAND_DIR)/*.c)
BOOT_ASM = $(BOOT_DIR)/boot.S

# Object files
BOOT_OBJ = $(BUILD_DIR)/boot/boot.o
KERNEL_OBJS = $(patsubst $(KERNEL_DIR)/%.c,$(BUILD_DIR)/kernel/%.o,$(KERNEL_SRCS))
SERVER_OBJS = $(patsubst $(SERVER_DIR)/%.c,$(BUILD_DIR)/servers/%.o,$(SERVER_SRCS))
DRIVER_OBJS = $(patsubst $(DRIVER_DIR)/%.c,$(BUILD_DIR)/drivers/%.o,$(DRIVER_SRCS))
LIB_OBJS = $(patsubst $(LIB_DIR)/%.c,$(BUILD_DIR)/lib/%.o,$(LIB_SRCS))
USERLAND_OBJS = $(patsubst $(USERLAND_DIR)/%.c,$(BUILD_DIR)/userland/%.o,$(USERLAND_SRCS))
ALL_OBJS = $(BOOT_OBJ) $(LIB_OBJS) $(KERNEL_OBJS) $(SERVER_OBJS) $(DRIVER_OBJS) $(USERLAND_OBJS)

# Targets
KERNEL_BIN = $(BUILD_DIR)/cubecactusos.bin
ISO_FILE = $(BUILD_DIR)/cubecactusos.iso

.PHONY: all clean os-build os-image os-run help

all: help

# Help target
help:
	@echo "CubeCactusOS Build System"
	@echo ""
	@echo "Targets:"
	@echo "  os-build    - Build the OS kernel and components"
	@echo "  os-image    - Create bootable ISO image"
	@echo "  os-run      - Run OS in QEMU emulator"
	@echo "  os-clean    - Clean build artifacts"
	@echo "  help        - Show this help message"
	@echo ""
	@echo "Quick start:"
	@echo "  make os-build && make os-run"

# Build OS
os-build: $(BUILD_DIR) $(KERNEL_BIN)
	@echo "✓ Build complete: $(KERNEL_BIN)"

# Create directories
$(BUILD_DIR):
	mkdir -p $(BUILD_DIR)/kernel
	mkdir -p $(BUILD_DIR)/servers
	mkdir -p $(BUILD_DIR)/drivers
	mkdir -p $(BUILD_DIR)/lib
	mkdir -p $(BUILD_DIR)/userland
	mkdir -p $(BUILD_DIR)/boot
	mkdir -p $(ISO_DIR)/boot/grub

# Assemble boot code
$(BOOT_OBJ): $(BOOT_ASM) | $(BUILD_DIR)
	@echo "Assembling $<"
	@if ! command -v $(AS) >/dev/null 2>&1; then \
		echo "✗ NASM assembler not found."; \
		echo ""; \
		echo "Install NASM:"; \
		echo "  brew install nasm"; \
		exit 1; \
	fi
	$(AS) $(ASFLAGS) $< -o $@

# Compile kernel
$(BUILD_DIR)/kernel/%.o: $(KERNEL_DIR)/%.c | $(BUILD_DIR)
	@echo "Compiling $<"
	$(CC) $(CFLAGS) -c $< -o $@

# Compile servers
$(BUILD_DIR)/servers/%.o: $(SERVER_DIR)/%.c | $(BUILD_DIR)
	@echo "Compiling $<"
	$(CC) $(CFLAGS) -c $< -o $@

# Compile drivers
$(BUILD_DIR)/drivers/%.o: $(DRIVER_DIR)/%.c | $(BUILD_DIR)
	@echo "Compiling $<"
	$(CC) $(CFLAGS) -c $< -o $@

# Compile library
$(BUILD_DIR)/lib/%.o: $(LIB_DIR)/%.c | $(BUILD_DIR)
	@echo "Compiling $<"
	$(CC) $(CFLAGS) -c $< -o $@

# Compile userland
$(BUILD_DIR)/userland/%.o: $(USERLAND_DIR)/%.c | $(BUILD_DIR)
	@echo "Compiling $<"
	$(CC) $(CFLAGS) -c $< -o $@

# Link kernel
$(KERNEL_BIN): $(ALL_OBJS)
	@echo "Linking kernel..."
ifeq ($(USE_NATIVE),1)
	@echo "⚠ Using native macOS linker (limited functionality)"
	@echo "⚠ For full OS functionality, install cross-compiler:"
	@echo "  brew tap nativeos/i386-elf-toolchain"
	@echo "  brew install i386-elf-binutils i386-elf-gcc"
	@echo ""
endif
	$(LD) $(LDFLAGS) -o $@ $^
	@echo "✓ Kernel linked successfully"

# Create ISO image
os-image: $(KERNEL_BIN)
	@echo "Creating bootable ISO image..."
	@mkdir -p $(ISO_DIR)/boot/grub
	@cp $(KERNEL_BIN) $(ISO_DIR)/boot/cubecactusos.bin
	@cp $(BOOT_DIR)/grub.cfg $(ISO_DIR)/boot/grub/grub.cfg
	@if [ -z "$(GRUB_MKRESCUE)" ]; then \
		echo "✗ GRUB not found. Install with:"; \
		echo "  brew install i686-elf-grub xorriso"; \
		exit 1; \
	fi
	@echo "Using $(GRUB_MKRESCUE) to create ISO..."
	@$(GRUB_MKRESCUE) -o $(ISO_FILE) $(ISO_DIR) 2>&1 | grep -v "warning:" || true
	@if [ -f $(ISO_FILE) ]; then \
		echo "✓ ISO created: $(ISO_FILE)"; \
		ls -lh $(ISO_FILE); \
	else \
		echo "✗ ISO creation failed"; \
		exit 1; \
	fi

# Run in QEMU
os-run: os-image
	@if [ ! -f $(ISO_FILE) ]; then \
		echo "✗ ISO file not found. Run 'make os-image' first."; \
		exit 1; \
	fi
	@if ! command -v $(QEMU) >/dev/null 2>&1; then \
		echo "✗ QEMU not found. Install it:"; \
		echo "  macOS: brew install qemu"; \
		echo "  Linux: sudo apt-get install qemu-system-x86"; \
		exit 1; \
	fi
	@echo "Starting CubeCactusOS in QEMU..."
	$(QEMU) -cdrom $(ISO_FILE) -m 512M -serial stdio

# Clean build artifacts
os-clean:
	rm -rf $(BUILD_DIR)
	@echo "Build directory cleaned"

# Clean everything including OS build
clean: os-clean
	rm -rf build/
	@echo "All build artifacts cleaned"