Merge pull request #16 from johndoe6345789/copilot/remove-makefile-support

Migrate to pure CMake build system by removing all Makefiles
This commit is contained in:
2025-12-28 21:09:30 +00:00
committed by GitHub
14 changed files with 169 additions and 507 deletions

View File

@@ -25,6 +25,7 @@ jobs:
sudo apt-get update sudo apt-get update
sudo apt-get install -y \ sudo apt-get install -y \
build-essential \ build-essential \
cmake \
nasm \ nasm \
qemu-system-x86 \ qemu-system-x86 \
ovmf \ ovmf \
@@ -32,19 +33,21 @@ jobs:
xorriso \ xorriso \
imagemagick imagemagick
- name: Build bootloader - name: Configure CMake
run: | run: |
cd bootloader mkdir -p build
make cd build
cmake ..
- name: Build kernel - name: Build bootloader and kernel
run: | run: |
cd kernel cd build
make cmake --build .
- name: Create bootable image - name: Create bootable image
run: | run: |
make image cd build
cmake --build . --target image
- name: Start QEMU and capture screenshot - name: Start QEMU and capture screenshot
run: | run: |
@@ -56,19 +59,22 @@ jobs:
XVFB_PID=$! XVFB_PID=$!
sleep 2 sleep 2
# Verify disk image exists (created by 'make image') # Verify disk image exists (created by cmake build)
if [ ! -f build/metalos.img ]; then if [ ! -f build/build/metalos.img ]; then
echo "Error: build/metalos.img not found!" echo "Error: build/build/metalos.img not found!"
exit 1 exit 1
fi fi
# Create directory for logs
mkdir -p build/logs
# Start QEMU in the background with a timeout # Start QEMU in the background with a timeout
timeout 30s qemu-system-x86_64 \ timeout 30s qemu-system-x86_64 \
-bios /usr/share/OVMF/OVMF_CODE.fd \ -bios /usr/share/OVMF/OVMF_CODE.fd \
-drive format=raw,file=build/metalos.img \ -drive format=raw,file=build/build/metalos.img \
-m 512M \ -m 512M \
-display gtk \ -display gtk \
-serial file:build/serial.log \ -serial file:build/logs/serial.log \
-no-reboot & -no-reboot &
QEMU_PID=$! QEMU_PID=$!
@@ -77,7 +83,7 @@ jobs:
# Take screenshot using ImageMagick (optional - don't fail if this doesn't work) # Take screenshot using ImageMagick (optional - don't fail if this doesn't work)
# Using subshell to prevent 'set -e' from affecting this optional step # Using subshell to prevent 'set -e' from affecting this optional step
{ import -window root build/qemu-screenshot.png; } || echo "Screenshot capture failed (non-fatal)" { import -window root build/logs/qemu-screenshot.png; } || echo "Screenshot capture failed (non-fatal)"
# Gracefully stop QEMU (don't fail if already stopped) # Gracefully stop QEMU (don't fail if already stopped)
kill $QEMU_PID 2>/dev/null || true kill $QEMU_PID 2>/dev/null || true
@@ -91,9 +97,9 @@ jobs:
- name: Show serial output - name: Show serial output
if: always() if: always()
run: | run: |
if [ -f build/serial.log ]; then if [ -f build/logs/serial.log ]; then
echo "=== QEMU Serial Output ===" echo "=== QEMU Serial Output ==="
cat build/serial.log cat build/logs/serial.log
else else
echo "No serial output captured" echo "No serial output captured"
fi fi
@@ -103,7 +109,7 @@ jobs:
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: qemu-screenshot name: qemu-screenshot
path: build/qemu-screenshot.png path: build/logs/qemu-screenshot.png
if-no-files-found: warn if-no-files-found: warn
- name: Upload serial log - name: Upload serial log
@@ -111,7 +117,7 @@ jobs:
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: serial-log name: serial-log
path: build/serial.log path: build/logs/serial.log
if-no-files-found: warn if-no-files-found: warn
- name: Upload built disk image - name: Upload built disk image
@@ -119,5 +125,5 @@ jobs:
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: metalos-disk-image name: metalos-disk-image
path: build/metalos.img path: build/build/metalos.img
if-no-files-found: warn if-no-files-found: warn

View File

@@ -24,25 +24,28 @@ jobs:
sudo apt-get update sudo apt-get update
sudo apt-get install -y \ sudo apt-get install -y \
build-essential \ build-essential \
cmake \
nasm \ nasm \
qemu-system-x86 \ qemu-system-x86 \
ovmf \ ovmf \
mtools \ mtools \
xorriso xorriso
- name: Build bootloader - name: Configure CMake
run: | run: |
cd bootloader mkdir -p build
make cd build
cmake ..
- name: Build kernel - name: Build bootloader and kernel
run: | run: |
cd kernel cd build
make cmake --build .
- name: Create bootable image - name: Create bootable image
run: | run: |
make image cd build
cmake --build . --target image
- name: Prepare release directory - name: Prepare release directory
run: | run: |
@@ -51,29 +54,29 @@ jobs:
mkdir -p release mkdir -p release
# Copy the bootable disk image (required) # Copy the bootable disk image (required)
if [ -f build/metalos.img ]; then if [ -f build/build/metalos.img ]; then
cp build/metalos.img release/ cp build/build/metalos.img release/
echo "✓ Copied metalos.img" echo "✓ Copied metalos.img"
else else
echo "Error: build/metalos.img not found!" echo "Error: build/build/metalos.img not found!"
exit 1 exit 1
fi fi
# Copy bootloader if it exists (required) # Copy bootloader if it exists (required)
if [ -f bootloader/bootx64.efi ]; then if [ -f build/bootloader/bootx64.efi ]; then
cp bootloader/bootx64.efi release/ cp build/bootloader/bootx64.efi release/
echo "✓ Copied bootx64.efi" echo "✓ Copied bootx64.efi"
else else
echo "Error: bootloader/bootx64.efi not found!" echo "Error: build/bootloader/bootx64.efi not found!"
exit 1 exit 1
fi fi
# Copy kernel if it exists (required) # Copy kernel if it exists (required)
if [ -f kernel/metalos.bin ]; then if [ -f build/kernel/metalos.bin ]; then
cp kernel/metalos.bin release/ cp build/kernel/metalos.bin release/
echo "✓ Copied metalos.bin" echo "✓ Copied metalos.bin"
else else
echo "Error: kernel/metalos.bin not found!" echo "Error: build/kernel/metalos.bin not found!"
exit 1 exit 1
fi fi

View File

@@ -22,17 +22,23 @@ jobs:
set -e # Exit on any error set -e # Exit on any error
sudo apt-get update sudo apt-get update
sudo apt-get install -y build-essential sudo apt-get install -y build-essential cmake
- name: Configure CMake
run: |
mkdir -p build
cd build
cmake ..
- name: Build unit tests - name: Build unit tests
run: | run: |
cd tests cd build
make all cmake --build .
- name: Run unit tests - name: Run unit tests
run: | run: |
cd tests cd build
make test ctest --output-on-failure
- name: Test summary - name: Test summary
if: always() if: always()

2
.gitignore vendored
View File

@@ -18,6 +18,8 @@
# Build directories # Build directories
build/ build/
build-*/ build-*/
cmake-build/
cmake-build-*/
bootloader/build/ bootloader/build/
kernel/build/ kernel/build/
_codeql_build_dir/ _codeql_build_dir/

View File

@@ -53,9 +53,9 @@ endif()
# Custom target to create bootable image # Custom target to create bootable image
find_program(MFORMAT mformat) find_program(MFORMAT mformat)
find_program(MCOPY mcopy) find_program(MCOPY mcopy)
find_program(MDD mdd) find_program(MMD mmd)
if(MFORMAT AND MCOPY) if(MFORMAT AND MCOPY AND MMD)
add_custom_target(image add_custom_target(image
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/build/iso/EFI/BOOT COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/build/iso/EFI/BOOT
COMMAND ${CMAKE_COMMAND} -E copy COMMAND ${CMAKE_COMMAND} -E copy
@@ -65,10 +65,10 @@ if(MFORMAT AND MCOPY)
${CMAKE_BINARY_DIR}/kernel/metalos.bin ${CMAKE_BINARY_DIR}/kernel/metalos.bin
${CMAKE_BINARY_DIR}/build/iso/ ${CMAKE_BINARY_DIR}/build/iso/
COMMAND ${CMAKE_COMMAND} -E echo "Creating disk image..." COMMAND ${CMAKE_COMMAND} -E echo "Creating disk image..."
COMMAND dd if=/dev/zero of=${CMAKE_BINARY_DIR}/build/metalos.img bs=1M count=64 2>/dev/null COMMAND dd if=/dev/zero of=${CMAKE_BINARY_DIR}/build/metalos.img bs=1M count=64
COMMAND ${MFORMAT} -i ${CMAKE_BINARY_DIR}/build/metalos.img -F -v METALOS :: COMMAND ${MFORMAT} -i ${CMAKE_BINARY_DIR}/build/metalos.img -F -v METALOS ::
COMMAND ${MDD} -i ${CMAKE_BINARY_DIR}/build/metalos.img ::/EFI COMMAND ${MMD} -i ${CMAKE_BINARY_DIR}/build/metalos.img ::/EFI
COMMAND ${MDD} -i ${CMAKE_BINARY_DIR}/build/metalos.img ::/EFI/BOOT COMMAND ${MMD} -i ${CMAKE_BINARY_DIR}/build/metalos.img ::/EFI/BOOT
COMMAND ${MCOPY} -i ${CMAKE_BINARY_DIR}/build/metalos.img COMMAND ${MCOPY} -i ${CMAKE_BINARY_DIR}/build/metalos.img
${CMAKE_BINARY_DIR}/build/iso/EFI/BOOT/bootx64.efi ::/EFI/BOOT/ ${CMAKE_BINARY_DIR}/build/iso/EFI/BOOT/bootx64.efi ::/EFI/BOOT/
COMMAND ${MCOPY} -i ${CMAKE_BINARY_DIR}/build/metalos.img COMMAND ${MCOPY} -i ${CMAKE_BINARY_DIR}/build/metalos.img
@@ -143,6 +143,20 @@ if(QEMU)
COMMENT "Running MetalOS in QEMU with GDB server (port 1234)" COMMENT "Running MetalOS in QEMU with GDB server (port 1234)"
VERBATIM VERBATIM
) )
add_custom_target(qemu-uefi-test
COMMAND ${CMAKE_COMMAND} -E echo "Testing QEMU UEFI boot (no OS image)..."
COMMAND ${CMAKE_COMMAND} -E echo "Using OVMF firmware: ${OVMF_FIRMWARE}"
COMMAND ${CMAKE_COMMAND} -E echo "This will boot to UEFI shell in nographic mode."
COMMAND ${CMAKE_COMMAND} -E echo "You should see UEFI boot messages. Press Ctrl-A then X to exit QEMU."
COMMAND ${QEMU}
-drive if=pflash,format=raw,readonly=on,file=${OVMF_FIRMWARE}
-m 512M
-nographic
-net none
COMMENT "Testing QEMU UEFI setup without OS image"
VERBATIM
)
else() else()
message(WARNING "OVMF firmware not found - QEMU targets will not be available") message(WARNING "OVMF firmware not found - QEMU targets will not be available")
endif() endif()

View File

@@ -152,9 +152,19 @@ Closes #42
Every PR should be tested in QEMU: Every PR should be tested in QEMU:
```bash ```bash
make clean mkdir build && cd build
make all cmake ..
make qemu cmake --build .
cmake --build . --target qemu
```
Or if you already have a build directory:
```bash
cd build
cmake --build . --target clean
cmake --build .
cmake --build . --target qemu
``` ```
Verify: Verify:

144
Makefile
View File

@@ -1,144 +0,0 @@
# MetalOS Main Makefile
# Builds bootloader, kernel, and creates bootable image
.PHONY: all bootloader kernel image qemu qemu-debug qemu-gdb qemu-uefi-test test clean distclean
all: bootloader kernel
# Run unit tests
test:
@echo "Running unit tests..."
@cd tests && $(MAKE) test
bootloader:
@echo "Building bootloader..."
@cd bootloader && $(MAKE) || echo "Warning: Bootloader build failed (expected during Phase 1 development)"
kernel:
@echo "Building kernel..."
@cd kernel && $(MAKE) || echo "Warning: Kernel build failed (expected during Phase 1 development)"
# Create bootable disk image for UEFI/QEMU
image: bootloader kernel
@chmod +x scripts/create_image.sh
@./scripts/create_image.sh
# Run in QEMU with UEFI firmware (OVMF)
# Automatically detects OVMF path and display mode
# Set QEMU_DISPLAY=gtk or QEMU_DISPLAY=sdl to use graphical mode
QEMU_DISPLAY ?= none
qemu: image
@echo "Starting QEMU with UEFI firmware..."
@bash -c ' \
if [ -f /usr/share/OVMF/OVMF_CODE.fd ]; then \
OVMF="/usr/share/OVMF/OVMF_CODE.fd"; \
elif [ -f /usr/share/ovmf/OVMF.fd ]; then \
OVMF="/usr/share/ovmf/OVMF.fd"; \
elif [ -f /usr/share/edk2-ovmf/x64/OVMF_CODE.fd ]; then \
OVMF="/usr/share/edk2-ovmf/x64/OVMF_CODE.fd"; \
elif [ -f /usr/share/qemu/ovmf-x86_64.bin ]; then \
OVMF="/usr/share/qemu/ovmf-x86_64.bin"; \
else \
echo "Error: OVMF UEFI firmware not found!"; \
echo "Install with:"; \
echo " Ubuntu/Debian: sudo apt-get install ovmf"; \
echo " Arch Linux: sudo pacman -S edk2-ovmf"; \
echo " Fedora: sudo dnf install edk2-ovmf"; \
exit 1; \
fi; \
echo "Using OVMF firmware: $$OVMF"; \
echo "Display mode: $(QEMU_DISPLAY) (set QEMU_DISPLAY=gtk for graphical)"; \
qemu-system-x86_64 \
-drive if=pflash,format=raw,readonly=on,file=$$OVMF \
-drive format=raw,file=build/metalos.img \
-m 512M \
-serial stdio \
-display $(QEMU_DISPLAY) \
-net none \
'
qemu-debug: image
@echo "Starting QEMU with debug output..."
@bash -c ' \
if [ -f /usr/share/OVMF/OVMF_CODE.fd ]; then \
OVMF="/usr/share/OVMF/OVMF_CODE.fd"; \
elif [ -f /usr/share/ovmf/OVMF.fd ]; then \
OVMF="/usr/share/ovmf/OVMF.fd"; \
elif [ -f /usr/share/edk2-ovmf/x64/OVMF_CODE.fd ]; then \
OVMF="/usr/share/edk2-ovmf/x64/OVMF_CODE.fd"; \
else \
echo "Error: OVMF UEFI firmware not found!"; \
exit 1; \
fi; \
qemu-system-x86_64 \
-drive if=pflash,format=raw,readonly=on,file=$$OVMF \
-drive format=raw,file=build/metalos.img \
-m 512M \
-serial stdio \
-display $(QEMU_DISPLAY) \
-net none \
-d int,cpu_reset \
'
qemu-gdb: image
@echo "Starting QEMU with GDB server on port 1234..."
@bash -c ' \
if [ -f /usr/share/OVMF/OVMF_CODE.fd ]; then \
OVMF="/usr/share/OVMF/OVMF_CODE.fd"; \
elif [ -f /usr/share/ovmf/OVMF.fd ]; then \
OVMF="/usr/share/ovmf/OVMF.fd"; \
elif [ -f /usr/share/edk2-ovmf/x64/OVMF_CODE.fd ]; then \
OVMF="/usr/share/edk2-ovmf/x64/OVMF_CODE.fd"; \
else \
echo "Error: OVMF UEFI firmware not found!"; \
exit 1; \
fi; \
echo "QEMU will wait for GDB connection on localhost:1234"; \
echo "In another terminal, run: gdb kernel/metalos.bin"; \
echo "Then in GDB: target remote localhost:1234"; \
qemu-system-x86_64 \
-drive if=pflash,format=raw,readonly=on,file=$$OVMF \
-drive format=raw,file=build/metalos.img \
-m 512M \
-serial stdio \
-display $(QEMU_DISPLAY) \
-net none \
-s -S \
'
# Quick UEFI test - boots to UEFI shell without OS (for verifying QEMU+OVMF setup)
qemu-uefi-test:
@echo "Testing QEMU UEFI boot (no OS image)..."
@bash -c ' \
if [ -f /usr/share/OVMF/OVMF_CODE.fd ]; then \
OVMF="/usr/share/OVMF/OVMF_CODE.fd"; \
elif [ -f /usr/share/ovmf/OVMF.fd ]; then \
OVMF="/usr/share/ovmf/OVMF.fd"; \
elif [ -f /usr/share/edk2-ovmf/x64/OVMF_CODE.fd ]; then \
OVMF="/usr/share/edk2-ovmf/x64/OVMF_CODE.fd"; \
else \
echo "Error: OVMF UEFI firmware not found!"; \
exit 1; \
fi; \
echo "Using OVMF firmware: $$OVMF"; \
echo "This will boot to UEFI shell in nographic mode."; \
echo "You should see UEFI boot messages. Press Ctrl-A then X to exit QEMU."; \
qemu-system-x86_64 \
-drive if=pflash,format=raw,readonly=on,file=$$OVMF \
-m 512M \
-nographic \
-net none \
'
clean:
@echo "Cleaning build artifacts..."
@cd bootloader && $(MAKE) clean
@cd kernel && $(MAKE) clean
@cd tests && $(MAKE) clean
@rm -rf build
distclean: clean
@echo "Deep clean..."
@find . -name "*.o" -delete
@find . -name "*.d" -delete

View File

@@ -67,18 +67,18 @@ See [docs/ROADMAP.md](docs/ROADMAP.md) for detailed phase breakdown.
## Building ## Building
MetalOS supports **multiple build systems** - choose what works best for you! MetalOS uses **CMake** as its build system for a modern, cross-platform build experience.
### Quick Start (Make - Traditional) ### Quick Start (CMake)
```bash ```bash
make all # Build bootloader, kernel, and userspace mkdir build && cd build
make test # Run unit tests cmake ..
make qemu # Test in QEMU with UEFI firmware cmake --build .
make clean # Clean build artifacts cmake --build . --target qemu
``` ```
### CMake + Ninja (Fast Modern Build) ### Using Ninja (Faster Builds)
```bash ```bash
mkdir build && cd build mkdir build && cd build
@@ -103,19 +103,15 @@ The easiest way to build MetalOS with all dependencies:
```bash ```bash
./scripts/docker-build.sh # Build Docker image ./scripts/docker-build.sh # Build Docker image
./scripts/docker-run.sh scripts/setup-deps.sh # Setup dependencies ./scripts/docker-run.sh scripts/setup-deps.sh # Setup dependencies
./scripts/docker-run.sh make all # Build everything ./scripts/docker-run.sh cmake --build build # Build everything
./scripts/docker-run.sh make qemu # Test in QEMU
``` ```
**See [docs/BUILD_SYSTEMS.md](docs/BUILD_SYSTEMS.md) for detailed comparison and usage of all build systems.**
**QEMU UEFI Testing**: **QEMU UEFI Testing**:
```bash ```bash
make qemu # Boot in QEMU with UEFI (headless) cmake --build . --target qemu # Boot in QEMU with UEFI (headless)
make qemu QEMU_DISPLAY=gtk # Boot with graphical display cmake --build . --target qemu-debug # Boot with debug output
make qemu-debug # Boot with debug output cmake --build . --target qemu-gdb # Boot with GDB debugging
make qemu-gdb # Boot with GDB debugging cmake --build . --target qemu-uefi-test # Test UEFI firmware setup
make qemu-uefi-test # Test UEFI firmware setup
``` ```
See [docs/BUILD.md](docs/BUILD.md) for detailed build instructions and [docs/TESTING.md](docs/TESTING.md) for testing guide. See [docs/BUILD.md](docs/BUILD.md) for detailed build instructions and [docs/TESTING.md](docs/TESTING.md) for testing guide.

View File

@@ -1,55 +0,0 @@
# MetalOS Bootloader Makefile
# Builds UEFI bootloader (bootx64.efi)
# Cross-compiler setup
CC = gcc
LD = ld
OBJCOPY = objcopy
# Directories
SRC_DIR = src
INC_DIR = include
BUILD_DIR = build
# Compiler flags for UEFI
CFLAGS = -Wall -Wextra -Werror \
-ffreestanding -fno-stack-protector -fno-stack-check \
-fshort-wchar -mno-red-zone \
-I$(INC_DIR) \
-DEFI_FUNCTION_WRAPPER
# Linker flags for UEFI
LDFLAGS = -shared -Bsymbolic -nostdlib \
-znocombreloc -T uefi.lds
# Source files
SOURCES = $(wildcard $(SRC_DIR)/*.c)
OBJECTS = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SOURCES))
# Output
TARGET = bootx64.efi
.PHONY: all clean
all: $(BUILD_DIR) $(TARGET)
$(BUILD_DIR):
mkdir -p $(BUILD_DIR)
# Compile C files
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
# Link and create EFI binary
$(TARGET): $(OBJECTS)
$(LD) $(LDFLAGS) $(OBJECTS) -o $(BUILD_DIR)/bootx64.so
$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic \
-j .dynsym -j .rel -j .rela -j .reloc \
--target=efi-app-x86_64 \
$(BUILD_DIR)/bootx64.so $@
clean:
rm -rf $(BUILD_DIR) $(TARGET)
# Note: This is a simplified Makefile
# A real implementation would use gnu-efi or proper UEFI SDK

View File

@@ -21,10 +21,12 @@ The easiest way to build MetalOS is using Docker, which provides a pre-configure
./scripts/docker-run.sh scripts/setup-deps.sh ./scripts/docker-run.sh scripts/setup-deps.sh
# 3. Build MetalOS # 3. Build MetalOS
./scripts/docker-run.sh make all mkdir build && cd build
cmake ..
cmake --build .
# 4. Test in QEMU (headless mode) # 4. Test in QEMU (headless mode)
./scripts/docker-run.sh make qemu cmake --build . --target qemu
# 5. Optional: Interactive shell in container # 5. Optional: Interactive shell in container
./scripts/docker-run.sh /bin/bash ./scripts/docker-run.sh /bin/bash
@@ -33,7 +35,7 @@ The easiest way to build MetalOS is using Docker, which provides a pre-configure
### What's Included in Docker ### What's Included in Docker
The Docker image includes: The Docker image includes:
- **Build tools**: GCC, NASM, Make, CMake, Meson - **Build tools**: GCC, NASM, CMake, Meson
- **QEMU**: For testing with UEFI firmware - **QEMU**: For testing with UEFI firmware
- **OVMF**: UEFI firmware for QEMU - **OVMF**: UEFI firmware for QEMU
- **Dependency management**: Scripts to download AMD firmware, Mesa RADV, QT6 - **Dependency management**: Scripts to download AMD firmware, Mesa RADV, QT6
@@ -127,11 +129,15 @@ This produces `kernel/metalos.bin` - the kernel binary.
## Creating Bootable Image ## Creating Bootable Image
```bash ```bash
# From repository root # From repository root, if you haven't already
make image mkdir build && cd build
cmake ..
# Create the bootable image
cmake --build . --target image
``` ```
This creates `build/metalos.img` - a bootable disk image containing: This creates the bootable disk image at `<build-directory>/build/metalos.img` (e.g., `build/build/metalos.img` if your build directory is named `build/`). The image contains:
- EFI System Partition with bootloader - EFI System Partition with bootloader
- Kernel binary - Kernel binary
- Any required data files - Any required data files
@@ -146,41 +152,33 @@ Ensure QEMU and OVMF are installed:
```bash ```bash
# Ubuntu/Debian # Ubuntu/Debian
sudo apt-get install qemu-system-x86 ovmf mtools sudo apt-get install qemu-system-x86 ovmf mtools cmake
# Arch Linux # Arch Linux
sudo pacman -S qemu-full edk2-ovmf mtools sudo pacman -S qemu-full edk2-ovmf mtools cmake
# Fedora # Fedora
sudo dnf install qemu-system-x86 edk2-ovmf mtools sudo dnf install qemu-system-x86 edk2-ovmf mtools cmake
``` ```
### Boot MetalOS in QEMU ### Boot MetalOS in QEMU
```bash ```bash
make qemu cd build
cmake --build . --target qemu
``` ```
This will: This will:
1. Build bootloader and kernel (or use placeholders if build fails) 1. Build bootloader and kernel
2. Create a bootable FAT32 disk image with UEFI boot structure 2. Create a bootable FAT32 disk image with UEFI boot structure
3. Launch QEMU with OVMF UEFI firmware in headless mode 3. Launch QEMU with OVMF UEFI firmware in headless mode
4. Boot the system (will drop to UEFI shell until bootloader is complete) 4. Boot the system
**Display Options**: By default, QEMU runs in headless mode (no graphics). To use graphical display:
```bash
# Use GTK display (if available)
make qemu QEMU_DISPLAY=gtk
# Use SDL display (if available)
make qemu QEMU_DISPLAY=sdl
```
### Boot with Debug Output ### Boot with Debug Output
```bash ```bash
make qemu-debug cd build
cmake --build . --target qemu-debug
``` ```
This includes CPU interrupt and reset debugging output. This includes CPU interrupt and reset debugging output.
@@ -191,7 +189,8 @@ For debugging with GDB:
```bash ```bash
# Terminal 1 - Start QEMU with GDB server # Terminal 1 - Start QEMU with GDB server
make qemu-gdb cd build
cmake --build . --target qemu-gdb
# Terminal 2 - Connect GDB # Terminal 2 - Connect GDB
gdb kernel/metalos.bin gdb kernel/metalos.bin
@@ -206,7 +205,8 @@ QEMU will wait for GDB connection before starting execution.
To verify QEMU and OVMF are properly installed without needing a bootable OS image: To verify QEMU and OVMF are properly installed without needing a bootable OS image:
```bash ```bash
make qemu-uefi-test cd build
cmake --build . --target qemu-uefi-test
``` ```
This boots directly to the UEFI shell, confirming your QEMU+OVMF setup works correctly. This boots directly to the UEFI shell, confirming your QEMU+OVMF setup works correctly.
@@ -292,10 +292,14 @@ ENABLE_SERIAL ?= 1
```bash ```bash
# Clean all build artifacts # Clean all build artifacts
make clean cd build
cmake --build . --target clean
# Clean everything including dependencies # Or remove the build directory entirely
make distclean cd ..
rm -rf build
mkdir build && cd build
cmake ..
``` ```
## Troubleshooting ## Troubleshooting

View File

@@ -1,21 +1,15 @@
# MetalOS Build Systems Guide # MetalOS Build Systems Guide
MetalOS supports multiple build systems to accommodate different developer preferences and workflows. MetalOS uses **CMake** as its primary build system, which can be used with different build backends for different workflows.
## Quick Start ## Quick Start
### Using Make (Traditional) ### Using CMake (Default)
```bash
make all # Build everything
make qemu # Test in QEMU
make clean # Clean build artifacts
```
### Using CMake + Make
```bash ```bash
mkdir build && cd build mkdir build && cd build
cmake .. cmake ..
cmake --build . cmake --build .
cmake --build . --target qemu # Test in QEMU
``` ```
### Using CMake + Ninja (Fastest) ### Using CMake + Ninja (Fastest)
@@ -23,6 +17,7 @@ cmake --build .
mkdir build && cd build mkdir build && cd build
cmake -G Ninja .. cmake -G Ninja ..
ninja ninja
ninja qemu # Test in QEMU
``` ```
### Using Conan + CMake ### Using Conan + CMake
@@ -35,89 +30,38 @@ cmake --build .
## Build System Comparison ## Build System Comparison
| Build System | Speed | Features | Best For | | Build Backend | Speed | Features | Best For |
|--------------|-------|----------|----------| |---------------|-------|----------|----------|
| **Make** | Medium | Simple, traditional | Quick builds, CI/CD | | **Make** (default) | Medium | Cross-platform, standard | General use, CI/CD |
| **CMake** | Medium | Cross-platform, modern | Complex projects, IDEs |
| **Ninja** | Fast | Parallel builds | Development, large projects | | **Ninja** | Fast | Parallel builds | Development, large projects |
| **Conan** | Medium | Dependency management | Projects with external deps | | **Conan** | Medium | Dependency management | Projects with external deps |
## Detailed Usage ## Detailed Usage
### 1. Make (Traditional Build System) ### 1. CMake (Primary Build System)
The original build system using GNU Make. CMake is the primary build system for MetalOS, providing cross-platform support and modern features.
#### Build Commands #### Build Commands
```bash ```bash
# Build all components # Configure and build
make all
# Build individually
make bootloader
make kernel
make test
# Create bootable image
make image
# Run in QEMU
make qemu # Headless mode
make qemu QEMU_DISPLAY=gtk # With GUI
make qemu-debug # With debug output
make qemu-gdb # With GDB server
# Clean
make clean # Clean build artifacts
make distclean # Deep clean
```
#### Advantages
- ✅ Simple and straightforward
- ✅ No additional dependencies
- ✅ Works on all Unix-like systems
- ✅ Easy to understand and modify
#### Disadvantages
- ❌ Not cross-platform (Windows requires special setup)
- ❌ Can be slower for large projects
- ❌ Limited dependency tracking
---
### 2. CMake (Modern Build Generator)
CMake generates build files for various build systems (Make, Ninja, Visual Studio, etc.).
#### Build Commands
```bash
# Configure (generates build files)
mkdir build && cd build mkdir build && cd build
cmake .. cmake ..
# Configure with specific generator
cmake -G "Unix Makefiles" ..
cmake -G Ninja ..
cmake -G "Visual Studio 17 2022" .. # Windows
# Configure with options
cmake -DBUILD_BOOTLOADER=ON -DBUILD_KERNEL=ON -DBUILD_TESTS=ON ..
cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake -DCMAKE_BUILD_TYPE=Release ..
# Build
cmake --build . cmake --build .
cmake --build . --parallel 8 # Use 8 parallel jobs
# Build specific targets # Build specific targets
cmake --build . --target bootloader_efi cmake --build . --target bootloader_efi
cmake --build . --target kernel_bin cmake --build . --target kernel_bin
cmake --build . --target image cmake --build . --target image
# Run custom targets # Create bootable image
cmake --build . --target qemu cmake --build . --target image
cmake --build . --target qemu-debug
cmake --build . --target qemu-gdb # Run in QEMU
cmake --build . --target qemu # Headless mode
cmake --build . --target qemu-debug # With debug output
cmake --build . --target qemu-gdb # With GDB server
cmake --build . --target qemu-uefi-test # Test UEFI setup
# Test # Test
ctest ctest
@@ -133,6 +77,23 @@ cmake --build . --target clean
rm -rf build # Complete clean rm -rf build # Complete clean
``` ```
#### Advantages
- ✅ Cross-platform (Windows, Linux, macOS)
- ✅ IDE integration (CLion, VSCode, Visual Studio)
- ✅ Modern dependency management
- ✅ Better parallel build support
- ✅ Generates compile_commands.json for IDEs
#### Disadvantages
- ❌ Requires cmake installation
- ❌ Slightly more complex setup
---
### 2. Ninja (Fast Build Backend)
Ninja is a fast build backend that can be used with CMake for faster incremental builds.
#### Advantages #### Advantages
- ✅ Cross-platform (Windows, Linux, macOS) - ✅ Cross-platform (Windows, Linux, macOS)
- ✅ IDE integration (CLion, Visual Studio, VS Code) - ✅ IDE integration (CLion, Visual Studio, VS Code)

View File

@@ -63,9 +63,11 @@ add_executable(kernel_elf $<TARGET_OBJECTS:kernel_obj> ${KERNEL_ASM_OBJECTS})
set_target_properties(kernel_elf PROPERTIES set_target_properties(kernel_elf PROPERTIES
OUTPUT_NAME metalos.elf OUTPUT_NAME metalos.elf
LINKER_LANGUAGE C LINKER_LANGUAGE C
POSITION_INDEPENDENT_CODE OFF
) )
target_link_options(kernel_elf PRIVATE target_link_options(kernel_elf PRIVATE
-nostdlib -nostdlib
-no-pie
-T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld -T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld
) )

View File

@@ -1,79 +0,0 @@
# MetalOS Kernel Makefile
# Cross-compiler (x86_64 bare metal)
CC = x86_64-elf-gcc
AS = nasm
LD = x86_64-elf-ld
OBJCOPY = x86_64-elf-objcopy
# Check if cross-compiler exists, fallback to regular gcc
ifeq ($(shell which $(CC) 2>/dev/null),)
CC = gcc
LD = ld
OBJCOPY = objcopy
endif
# Directories
SRC_DIR = src
INC_DIR = include
BUILD_DIR = build
# Compiler flags
CFLAGS = -Wall -Wextra -Werror \
-ffreestanding -fno-stack-protector \
-mno-red-zone -mcmodel=large \
-I$(INC_DIR) \
-O2
# Assembler flags
ASFLAGS = -f elf64
# Linker flags
LDFLAGS = -nostdlib -T linker.ld
# Source files
C_SOURCES = $(shell find $(SRC_DIR) -name '*.c')
ASM_SOURCES = $(shell find $(SRC_DIR) -name '*.asm')
# Object files
C_OBJECTS = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(C_SOURCES))
ASM_OBJECTS = $(patsubst $(SRC_DIR)/%.asm,$(BUILD_DIR)/%.o,$(ASM_SOURCES))
OBJECTS = $(C_OBJECTS) $(ASM_OBJECTS)
# Output
TARGET = metalos.bin
.PHONY: all clean
all: $(BUILD_DIR) $(TARGET)
$(BUILD_DIR):
mkdir -p $(BUILD_DIR)
mkdir -p $(BUILD_DIR)/core
mkdir -p $(BUILD_DIR)/hal
mkdir -p $(BUILD_DIR)/drivers
mkdir -p $(BUILD_DIR)/syscall
# Compile C files
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) -c $< -o $@
# Assemble ASM files
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.asm
@mkdir -p $(dir $@)
$(AS) $(ASFLAGS) $< -o $@
# Link kernel
$(TARGET): $(OBJECTS)
$(LD) $(LDFLAGS) $(OBJECTS) -o $@
clean:
rm -rf $(BUILD_DIR) $(TARGET)
# Print variables for debugging
info:
@echo "C Sources: $(C_SOURCES)"
@echo "ASM Sources: $(ASM_SOURCES)"
@echo "Objects: $(OBJECTS)"
@echo "Compiler: $(CC)"

View File

@@ -1,64 +0,0 @@
# MetalOS Test Suite Makefile
CC = gcc
CFLAGS = -Wall -Wextra -std=c11 -I../tests/include -I../kernel/include -I../bootloader/include
LDFLAGS =
# Test source files
TEST_SOURCES = $(wildcard unit/*.c)
TEST_BINARIES = $(TEST_SOURCES:.c=)
# Default target
.PHONY: all
all: $(TEST_BINARIES)
# Build each test binary
unit/%: unit/%.c include/test_framework.h
@echo "Building test: $@"
$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
# Run all tests
.PHONY: test
test: all
@echo ""
@echo "╔════════════════════════════════════════════╗"
@echo "║ Running MetalOS Test Suite ║"
@echo "╚════════════════════════════════════════════╝"
@echo ""
@for test in $(TEST_BINARIES); do \
./$$test || exit 1; \
done
@echo ""
@echo "╔════════════════════════════════════════════╗"
@echo "║ All Test Suites Passed ✓ ║"
@echo "╚════════════════════════════════════════════╝"
@echo ""
# Run tests with verbose output
.PHONY: test-verbose
test-verbose: all
@for test in $(TEST_BINARIES); do \
echo "Running $$test..."; \
./$$test -v; \
echo ""; \
done
# Clean test binaries
.PHONY: clean
clean:
@echo "Cleaning test binaries..."
@rm -f $(TEST_BINARIES)
@rm -f unit/*.o
@echo "Clean complete"
# Help target
.PHONY: help
help:
@echo "MetalOS Test Suite Makefile"
@echo ""
@echo "Targets:"
@echo " all - Build all test binaries"
@echo " test - Build and run all tests"
@echo " test-verbose - Run tests with verbose output"
@echo " clean - Remove test binaries"
@echo " help - Show this help message"