mirror of
https://github.com/johndoe6345789/MetalOS.git
synced 2026-04-24 13:45:02 +00:00
Add CMake, Ninja, and Conan build system support
Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
15
.gitignore
vendored
15
.gitignore
vendored
@@ -17,9 +17,24 @@
|
||||
|
||||
# Build directories
|
||||
build/
|
||||
build-*/
|
||||
bootloader/build/
|
||||
kernel/build/
|
||||
|
||||
# CMake specific
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
cmake_install.cmake
|
||||
CMakeUserPresets.json
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
|
||||
# Conan specific
|
||||
conaninfo.txt
|
||||
conanbuildinfo.*
|
||||
conan.lock
|
||||
graph_info.json
|
||||
|
||||
# Test binaries
|
||||
tests/unit/test_*
|
||||
!tests/unit/*.c
|
||||
|
||||
161
CMakeLists.txt
Normal file
161
CMakeLists.txt
Normal file
@@ -0,0 +1,161 @@
|
||||
# MetalOS Root CMakeLists.txt
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(MetalOS
|
||||
VERSION 0.1.0
|
||||
DESCRIPTION "Minimal OS for QT6 applications"
|
||||
LANGUAGES C CXX ASM
|
||||
)
|
||||
|
||||
# Set C standard
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
# Set C++ standard
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Export compile commands for IDE support
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Default to Release build if not specified
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
|
||||
endif()
|
||||
|
||||
# Options
|
||||
option(BUILD_BOOTLOADER "Build UEFI bootloader" ON)
|
||||
option(BUILD_KERNEL "Build kernel" ON)
|
||||
option(BUILD_TESTS "Build unit tests" ON)
|
||||
|
||||
# Build output directory
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
|
||||
# Create build directory for image
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/build)
|
||||
|
||||
# Add subdirectories
|
||||
if(BUILD_BOOTLOADER)
|
||||
add_subdirectory(bootloader)
|
||||
endif()
|
||||
|
||||
if(BUILD_KERNEL)
|
||||
add_subdirectory(kernel)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTS)
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
# Custom target to create bootable image
|
||||
find_program(MFORMAT mformat)
|
||||
find_program(MCOPY mcopy)
|
||||
find_program(MDD mdd)
|
||||
|
||||
if(MFORMAT AND MCOPY)
|
||||
add_custom_target(image
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/build/iso/EFI/BOOT
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_BINARY_DIR}/bootloader/bootx64.efi
|
||||
${CMAKE_BINARY_DIR}/build/iso/EFI/BOOT/
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_BINARY_DIR}/kernel/metalos.bin
|
||||
${CMAKE_BINARY_DIR}/build/iso/
|
||||
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 ${MFORMAT} -i ${CMAKE_BINARY_DIR}/build/metalos.img -F -v METALOS ::
|
||||
COMMAND ${MDD} -i ${CMAKE_BINARY_DIR}/build/metalos.img ::/EFI
|
||||
COMMAND ${MDD} -i ${CMAKE_BINARY_DIR}/build/metalos.img ::/EFI/BOOT
|
||||
COMMAND ${MCOPY} -i ${CMAKE_BINARY_DIR}/build/metalos.img
|
||||
${CMAKE_BINARY_DIR}/build/iso/EFI/BOOT/bootx64.efi ::/EFI/BOOT/
|
||||
COMMAND ${MCOPY} -i ${CMAKE_BINARY_DIR}/build/metalos.img
|
||||
${CMAKE_BINARY_DIR}/build/iso/metalos.bin ::/
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Success! Created ${CMAKE_BINARY_DIR}/build/metalos.img"
|
||||
DEPENDS bootloader_efi kernel_bin
|
||||
COMMENT "Creating bootable disk image"
|
||||
VERBATIM
|
||||
)
|
||||
else()
|
||||
message(WARNING "mtools not found - 'image' target will not be available")
|
||||
endif()
|
||||
|
||||
# Custom target to run in QEMU
|
||||
find_program(QEMU qemu-system-x86_64)
|
||||
if(QEMU)
|
||||
# Find OVMF firmware
|
||||
set(OVMF_PATHS
|
||||
/usr/share/OVMF/OVMF_CODE.fd
|
||||
/usr/share/ovmf/OVMF.fd
|
||||
/usr/share/edk2-ovmf/x64/OVMF_CODE.fd
|
||||
/usr/share/qemu/ovmf-x86_64.bin
|
||||
)
|
||||
|
||||
foreach(ovmf_path ${OVMF_PATHS})
|
||||
if(EXISTS ${ovmf_path})
|
||||
set(OVMF_FIRMWARE ${ovmf_path})
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(OVMF_FIRMWARE)
|
||||
message(STATUS "Found OVMF firmware: ${OVMF_FIRMWARE}")
|
||||
|
||||
add_custom_target(qemu
|
||||
COMMAND ${QEMU}
|
||||
-drive if=pflash,format=raw,readonly=on,file=${OVMF_FIRMWARE}
|
||||
-drive format=raw,file=${CMAKE_BINARY_DIR}/build/metalos.img
|
||||
-m 512M
|
||||
-serial stdio
|
||||
-display none
|
||||
-net none
|
||||
DEPENDS image
|
||||
COMMENT "Running MetalOS in QEMU"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(qemu-debug
|
||||
COMMAND ${QEMU}
|
||||
-drive if=pflash,format=raw,readonly=on,file=${OVMF_FIRMWARE}
|
||||
-drive format=raw,file=${CMAKE_BINARY_DIR}/build/metalos.img
|
||||
-m 512M
|
||||
-serial stdio
|
||||
-display none
|
||||
-net none
|
||||
-d int,cpu_reset
|
||||
DEPENDS image
|
||||
COMMENT "Running MetalOS in QEMU with debug output"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(qemu-gdb
|
||||
COMMAND ${QEMU}
|
||||
-drive if=pflash,format=raw,readonly=on,file=${OVMF_FIRMWARE}
|
||||
-drive format=raw,file=${CMAKE_BINARY_DIR}/build/metalos.img
|
||||
-m 512M
|
||||
-serial stdio
|
||||
-display none
|
||||
-net none
|
||||
-s -S
|
||||
DEPENDS image
|
||||
COMMENT "Running MetalOS in QEMU with GDB server (port 1234)"
|
||||
VERBATIM
|
||||
)
|
||||
else()
|
||||
message(WARNING "OVMF firmware not found - QEMU targets will not be available")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "QEMU not found - QEMU targets will not be available")
|
||||
endif()
|
||||
|
||||
# Print configuration summary
|
||||
message(STATUS "")
|
||||
message(STATUS "MetalOS Configuration:")
|
||||
message(STATUS " Version: ${PROJECT_VERSION}")
|
||||
message(STATUS " Build type: ${CMAKE_BUILD_TYPE}")
|
||||
message(STATUS " Bootloader: ${BUILD_BOOTLOADER}")
|
||||
message(STATUS " Kernel: ${BUILD_KERNEL}")
|
||||
message(STATUS " Tests: ${BUILD_TESTS}")
|
||||
message(STATUS "")
|
||||
40
README.md
40
README.md
@@ -67,7 +67,36 @@ See [docs/ROADMAP.md](docs/ROADMAP.md) for detailed phase breakdown.
|
||||
|
||||
## Building
|
||||
|
||||
### Docker Build (Recommended)
|
||||
MetalOS supports **multiple build systems** - choose what works best for you!
|
||||
|
||||
### Quick Start (Make - Traditional)
|
||||
|
||||
```bash
|
||||
make all # Build bootloader, kernel, and userspace
|
||||
make test # Run unit tests
|
||||
make qemu # Test in QEMU with UEFI firmware
|
||||
make clean # Clean build artifacts
|
||||
```
|
||||
|
||||
### CMake + Ninja (Fast Modern Build)
|
||||
|
||||
```bash
|
||||
mkdir build && cd build
|
||||
cmake -G Ninja ..
|
||||
ninja
|
||||
ninja qemu
|
||||
```
|
||||
|
||||
### Conan (With Package Management)
|
||||
|
||||
```bash
|
||||
mkdir build && cd build
|
||||
conan install .. --build=missing
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../build/Release/generators/conan_toolchain.cmake -G Ninja
|
||||
ninja
|
||||
```
|
||||
|
||||
### Docker Build (Recommended for Consistency)
|
||||
|
||||
The easiest way to build MetalOS with all dependencies:
|
||||
|
||||
@@ -78,14 +107,7 @@ The easiest way to build MetalOS with all dependencies:
|
||||
./scripts/docker-run.sh make qemu # Test in QEMU
|
||||
```
|
||||
|
||||
### Native Build
|
||||
|
||||
```bash
|
||||
make all # Build bootloader, kernel, and userspace
|
||||
make test # Run unit tests
|
||||
make qemu # Test in QEMU with UEFI firmware
|
||||
make clean # Clean build artifacts
|
||||
```
|
||||
**See [docs/BUILD_SYSTEMS.md](docs/BUILD_SYSTEMS.md) for detailed comparison and usage of all build systems.**
|
||||
|
||||
**QEMU UEFI Testing**:
|
||||
```bash
|
||||
|
||||
84
bootloader/CMakeLists.txt
Normal file
84
bootloader/CMakeLists.txt
Normal file
@@ -0,0 +1,84 @@
|
||||
# MetalOS Bootloader CMakeLists.txt
|
||||
# Builds UEFI bootloader (bootx64.efi)
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(MetalOS_Bootloader C)
|
||||
|
||||
# Source files
|
||||
set(BOOTLOADER_SOURCES
|
||||
src/main.c
|
||||
)
|
||||
|
||||
# Header files
|
||||
set(BOOTLOADER_HEADERS
|
||||
include/bootloader.h
|
||||
include/efi.h
|
||||
)
|
||||
|
||||
# Compiler flags for UEFI
|
||||
set(UEFI_CFLAGS
|
||||
-Wall
|
||||
-Wextra
|
||||
-Werror
|
||||
-ffreestanding
|
||||
-fno-stack-protector
|
||||
-fno-stack-check
|
||||
-fshort-wchar
|
||||
-mno-red-zone
|
||||
-DEFI_FUNCTION_WRAPPER
|
||||
)
|
||||
|
||||
# Linker flags for UEFI
|
||||
set(UEFI_LDFLAGS
|
||||
-shared
|
||||
-Bsymbolic
|
||||
-nostdlib
|
||||
-znocombreloc
|
||||
)
|
||||
|
||||
# Create object library
|
||||
add_library(bootloader_obj OBJECT ${BOOTLOADER_SOURCES})
|
||||
target_include_directories(bootloader_obj PRIVATE include)
|
||||
target_compile_options(bootloader_obj PRIVATE ${UEFI_CFLAGS})
|
||||
|
||||
# Create shared library (intermediate)
|
||||
add_library(bootloader_so SHARED $<TARGET_OBJECTS:bootloader_obj>)
|
||||
set_target_properties(bootloader_so PROPERTIES
|
||||
OUTPUT_NAME bootx64
|
||||
SUFFIX .so
|
||||
LINKER_LANGUAGE C
|
||||
)
|
||||
target_link_options(bootloader_so PRIVATE
|
||||
${UEFI_LDFLAGS}
|
||||
-T ${CMAKE_CURRENT_SOURCE_DIR}/uefi.lds
|
||||
)
|
||||
|
||||
# Custom command to convert .so to .efi
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/bootx64.efi
|
||||
COMMAND ${CMAKE_OBJCOPY}
|
||||
-j .text -j .sdata -j .data -j .dynamic
|
||||
-j .dynsym -j .rel -j .rela -j .reloc
|
||||
--target=efi-app-x86_64
|
||||
$<TARGET_FILE:bootloader_so>
|
||||
${CMAKE_CURRENT_BINARY_DIR}/bootx64.efi
|
||||
DEPENDS bootloader_so
|
||||
COMMENT "Converting bootloader to EFI format"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Custom target for the EFI file
|
||||
add_custom_target(bootloader_efi ALL
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/bootx64.efi
|
||||
)
|
||||
|
||||
# Install target
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/bootx64.efi
|
||||
DESTINATION boot/efi/EFI/BOOT
|
||||
)
|
||||
|
||||
# Print status
|
||||
message(STATUS "Bootloader configuration:")
|
||||
message(STATUS " Sources: ${BOOTLOADER_SOURCES}")
|
||||
message(STATUS " Output: bootx64.efi")
|
||||
72
conanfile.py
Normal file
72
conanfile.py
Normal file
@@ -0,0 +1,72 @@
|
||||
"""
|
||||
MetalOS Conan Package Configuration
|
||||
|
||||
This file defines the dependencies and build configuration for MetalOS.
|
||||
Currently, MetalOS is a freestanding OS with no external dependencies,
|
||||
but this file is prepared for future use when we integrate:
|
||||
- Mesa RADV (GPU driver)
|
||||
- QT6 (application framework)
|
||||
- Other system libraries
|
||||
"""
|
||||
|
||||
from conan import ConanFile
|
||||
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout
|
||||
|
||||
|
||||
class MetalOSConan(ConanFile):
|
||||
name = "metalos"
|
||||
version = "0.1.0"
|
||||
license = "MIT"
|
||||
author = "MetalOS Contributors"
|
||||
url = "https://github.com/johndoe6345789/MetalOS"
|
||||
description = "Minimal OS for QT6 applications on AMD64 + Radeon RX 6600"
|
||||
topics = ("os", "uefi", "minimal", "qt6", "gpu")
|
||||
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
options = {
|
||||
"build_bootloader": [True, False],
|
||||
"build_kernel": [True, False],
|
||||
"build_tests": [True, False],
|
||||
}
|
||||
default_options = {
|
||||
"build_bootloader": True,
|
||||
"build_kernel": True,
|
||||
"build_tests": True,
|
||||
}
|
||||
|
||||
# Specify which generator to use (cmake, make, ninja, etc.)
|
||||
generators = "CMakeDeps"
|
||||
|
||||
# No external dependencies yet (freestanding OS)
|
||||
# Future dependencies will be added here:
|
||||
# requires = (
|
||||
# "qt/6.5.0@qt/stable", # When we port QT6
|
||||
# "mesa/22.3.0@system/stable", # When we integrate Mesa RADV
|
||||
# )
|
||||
|
||||
def layout(self):
|
||||
cmake_layout(self)
|
||||
|
||||
def generate(self):
|
||||
tc = CMakeToolchain(self)
|
||||
# Pass options to CMake
|
||||
tc.variables["BUILD_BOOTLOADER"] = self.options.build_bootloader
|
||||
tc.variables["BUILD_KERNEL"] = self.options.build_kernel
|
||||
tc.variables["BUILD_TESTS"] = self.options.build_tests
|
||||
tc.generate()
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self)
|
||||
cmake.configure()
|
||||
cmake.build()
|
||||
|
||||
def package(self):
|
||||
cmake = CMake(self)
|
||||
cmake.install()
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.libs = [] # MetalOS doesn't provide libraries
|
||||
self.cpp_info.bindirs = ["boot", "boot/efi/EFI/BOOT"]
|
||||
|
||||
# Set environment variables for tools that need to find our binaries
|
||||
self.buildenv_info.append_path("PATH", self.package_folder)
|
||||
418
docs/BUILD_SYSTEMS.md
Normal file
418
docs/BUILD_SYSTEMS.md
Normal file
@@ -0,0 +1,418 @@
|
||||
# MetalOS Build Systems Guide
|
||||
|
||||
MetalOS supports multiple build systems to accommodate different developer preferences and workflows.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Using Make (Traditional)
|
||||
```bash
|
||||
make all # Build everything
|
||||
make qemu # Test in QEMU
|
||||
make clean # Clean build artifacts
|
||||
```
|
||||
|
||||
### Using CMake + Make
|
||||
```bash
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
### Using CMake + Ninja (Fastest)
|
||||
```bash
|
||||
mkdir build && cd build
|
||||
cmake -G Ninja ..
|
||||
ninja
|
||||
```
|
||||
|
||||
### Using Conan + CMake
|
||||
```bash
|
||||
mkdir build && cd build
|
||||
conan install .. --build=missing
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
## Build System Comparison
|
||||
|
||||
| Build System | Speed | Features | Best For |
|
||||
|--------------|-------|----------|----------|
|
||||
| **Make** | Medium | Simple, traditional | Quick builds, CI/CD |
|
||||
| **CMake** | Medium | Cross-platform, modern | Complex projects, IDEs |
|
||||
| **Ninja** | Fast | Parallel builds | Development, large projects |
|
||||
| **Conan** | Medium | Dependency management | Projects with external deps |
|
||||
|
||||
## Detailed Usage
|
||||
|
||||
### 1. Make (Traditional Build System)
|
||||
|
||||
The original build system using GNU Make.
|
||||
|
||||
#### Build Commands
|
||||
```bash
|
||||
# Build all components
|
||||
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
|
||||
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 . --parallel 8 # Use 8 parallel jobs
|
||||
|
||||
# Build specific targets
|
||||
cmake --build . --target bootloader_efi
|
||||
cmake --build . --target kernel_bin
|
||||
cmake --build . --target image
|
||||
|
||||
# Run custom targets
|
||||
cmake --build . --target qemu
|
||||
cmake --build . --target qemu-debug
|
||||
cmake --build . --target qemu-gdb
|
||||
|
||||
# Test
|
||||
ctest
|
||||
ctest --output-on-failure
|
||||
ctest -V # Verbose
|
||||
|
||||
# Install
|
||||
cmake --install .
|
||||
cmake --install . --prefix /path/to/install
|
||||
|
||||
# Clean
|
||||
cmake --build . --target clean
|
||||
rm -rf build # Complete clean
|
||||
```
|
||||
|
||||
#### Advantages
|
||||
- ✅ Cross-platform (Windows, Linux, macOS)
|
||||
- ✅ IDE integration (CLion, Visual Studio, VS Code)
|
||||
- ✅ Modern and widely adopted
|
||||
- ✅ Better dependency tracking
|
||||
- ✅ Supports multiple generators
|
||||
|
||||
#### Disadvantages
|
||||
- ❌ More complex than Make
|
||||
- ❌ Requires CMake to be installed
|
||||
- ❌ Learning curve for CMakeLists.txt syntax
|
||||
|
||||
---
|
||||
|
||||
### 3. Ninja (Fast Build System)
|
||||
|
||||
Ninja is designed for speed and is often used with CMake.
|
||||
|
||||
#### Build Commands
|
||||
```bash
|
||||
# Configure with Ninja generator
|
||||
mkdir build && cd build
|
||||
cmake -G Ninja ..
|
||||
|
||||
# Build (much faster than Make)
|
||||
ninja
|
||||
|
||||
# Build specific targets
|
||||
ninja bootloader_efi
|
||||
ninja kernel_bin
|
||||
ninja image
|
||||
ninja qemu
|
||||
|
||||
# Clean
|
||||
ninja clean
|
||||
```
|
||||
|
||||
#### Advantages
|
||||
- ✅ **Very fast** - optimized for speed
|
||||
- ✅ Better parallelization than Make
|
||||
- ✅ Accurate dependency tracking
|
||||
- ✅ Clean output format
|
||||
- ✅ Works great with CMake
|
||||
|
||||
#### Disadvantages
|
||||
- ❌ Requires Ninja to be installed
|
||||
- ❌ Less familiar than Make
|
||||
- ❌ Requires CMake to generate build files
|
||||
|
||||
---
|
||||
|
||||
### 4. Conan (Package Manager + Build System)
|
||||
|
||||
Conan manages dependencies and integrates with CMake.
|
||||
|
||||
#### Setup
|
||||
```bash
|
||||
# Install Conan (first time only)
|
||||
pip install conan
|
||||
|
||||
# Initialize Conan profile (first time only)
|
||||
conan profile detect --force
|
||||
```
|
||||
|
||||
#### Build Commands
|
||||
```bash
|
||||
# Create build directory
|
||||
mkdir build && cd build
|
||||
|
||||
# Install dependencies (currently none, but ready for future)
|
||||
conan install .. --build=missing
|
||||
|
||||
# Alternative: Install with specific settings
|
||||
conan install .. --build=missing -s build_type=Debug
|
||||
conan install .. --build=missing -s build_type=Release
|
||||
|
||||
# Configure with Conan-generated toolchain
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake
|
||||
|
||||
# Build
|
||||
cmake --build .
|
||||
|
||||
# Or use Conan to build directly
|
||||
cd ..
|
||||
conan build . --build-folder=build
|
||||
```
|
||||
|
||||
#### Advantages
|
||||
- ✅ Dependency management (for future QT6, Mesa, etc.)
|
||||
- ✅ Reproducible builds
|
||||
- ✅ Version management
|
||||
- ✅ Cross-platform package management
|
||||
- ✅ Integration with CMake and other build systems
|
||||
|
||||
#### Disadvantages
|
||||
- ❌ Requires Python and Conan
|
||||
- ❌ Additional complexity
|
||||
- ❌ Currently overkill (we have no dependencies yet)
|
||||
- ❌ Learning curve
|
||||
|
||||
---
|
||||
|
||||
## Which Build System Should I Use?
|
||||
|
||||
### For Quick Development
|
||||
**Use: Make or CMake + Ninja**
|
||||
```bash
|
||||
# Make - simplest
|
||||
make all && make qemu
|
||||
|
||||
# Or Ninja - fastest
|
||||
cd build-ninja && ninja && ninja qemu
|
||||
```
|
||||
|
||||
### For IDE Integration
|
||||
**Use: CMake**
|
||||
- Works with CLion, Visual Studio Code, Visual Studio
|
||||
- Configure your IDE to use the CMakeLists.txt
|
||||
|
||||
### For CI/CD
|
||||
**Use: Make or CMake**
|
||||
```bash
|
||||
# GitHub Actions, GitLab CI, etc.
|
||||
make all && make test
|
||||
|
||||
# Or with CMake
|
||||
cmake -B build -G Ninja
|
||||
cmake --build build
|
||||
ctest --test-dir build
|
||||
```
|
||||
|
||||
### For Cross-Platform Development
|
||||
**Use: CMake + Ninja**
|
||||
```bash
|
||||
# Works on Linux, macOS, Windows
|
||||
cmake -G Ninja -B build
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
### For Projects with Dependencies (Future)
|
||||
**Use: Conan + CMake**
|
||||
```bash
|
||||
# When we add QT6, Mesa RADV, etc.
|
||||
conan install . --build=missing
|
||||
cmake --preset conan-release
|
||||
cmake --build --preset conan-release
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
MetalOS/
|
||||
├── Makefile # Traditional Make build
|
||||
├── CMakeLists.txt # Root CMake configuration
|
||||
├── conanfile.py # Conan package definition
|
||||
├── conanfile.txt # Simple Conan configuration
|
||||
├── bootloader/
|
||||
│ ├── Makefile # Bootloader Make build
|
||||
│ └── CMakeLists.txt # Bootloader CMake build
|
||||
├── kernel/
|
||||
│ ├── Makefile # Kernel Make build
|
||||
│ └── CMakeLists.txt # Kernel CMake build
|
||||
└── tests/
|
||||
├── Makefile # Tests Make build
|
||||
└── CMakeLists.txt # Tests CMake build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Build Options
|
||||
|
||||
### CMake Options
|
||||
```bash
|
||||
# Enable/disable components
|
||||
-DBUILD_BOOTLOADER=ON/OFF
|
||||
-DBUILD_KERNEL=ON/OFF
|
||||
-DBUILD_TESTS=ON/OFF
|
||||
|
||||
# Build type
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
|
||||
# Compiler
|
||||
-DCMAKE_C_COMPILER=/usr/bin/gcc
|
||||
-DCMAKE_CXX_COMPILER=/usr/bin/g++
|
||||
|
||||
# Install prefix
|
||||
-DCMAKE_INSTALL_PREFIX=/opt/metalos
|
||||
```
|
||||
|
||||
### Make Options
|
||||
```bash
|
||||
# Display mode for QEMU
|
||||
QEMU_DISPLAY=gtk
|
||||
QEMU_DISPLAY=sdl
|
||||
QEMU_DISPLAY=none
|
||||
|
||||
# Verbose output
|
||||
V=1
|
||||
VERBOSE=1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### CMake: Ninja not found
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt-get install ninja-build
|
||||
|
||||
# macOS
|
||||
brew install ninja
|
||||
|
||||
# Arch Linux
|
||||
sudo pacman -S ninja
|
||||
```
|
||||
|
||||
### CMake: OVMF not found
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt-get install ovmf
|
||||
|
||||
# Arch Linux
|
||||
sudo pacman -S edk2-ovmf
|
||||
|
||||
# Or specify manually
|
||||
cmake .. -DOVMF_FIRMWARE=/path/to/OVMF.fd
|
||||
```
|
||||
|
||||
### Conan: Profile not found
|
||||
```bash
|
||||
# Detect default profile
|
||||
conan profile detect --force
|
||||
|
||||
# Create custom profile
|
||||
conan profile show default > myprofile
|
||||
# Edit myprofile as needed
|
||||
conan install .. --profile=myprofile
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Comparison
|
||||
|
||||
Build time for clean build (approximate):
|
||||
|
||||
| Build System | Time | Notes |
|
||||
|--------------|------|-------|
|
||||
| Make | ~2s | Single-threaded by default |
|
||||
| Make -j8 | ~1s | With 8 parallel jobs |
|
||||
| CMake + Make | ~2s | Same as Make |
|
||||
| CMake + Ninja| ~0.5s| Fastest option |
|
||||
| Conan + CMake| ~3s | Additional dependency resolution |
|
||||
|
||||
*Times measured on a typical development machine. Your results may vary.*
|
||||
|
||||
---
|
||||
|
||||
## Future Plans
|
||||
|
||||
As MetalOS grows and adds dependencies (QT6, Mesa RADV), we recommend:
|
||||
|
||||
1. **Development**: CMake + Ninja (fastest iteration)
|
||||
2. **Dependency Management**: Conan (when dependencies are added)
|
||||
3. **CI/CD**: Keep Make for simplicity, or migrate to CMake
|
||||
4. **Distribution**: Create Conan packages for easy installation
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
- Check `docs/BUILD.md` for detailed build instructions
|
||||
- See `docs/DEVELOPMENT.md` for development workflow
|
||||
- Read individual Makefiles and CMakeLists.txt for specifics
|
||||
- Check `conanfile.py` comments for dependency information
|
||||
|
||||
---
|
||||
|
||||
**Note**: All build systems produce identical outputs. Choose based on your workflow and preferences!
|
||||
79
kernel/CMakeLists.txt
Normal file
79
kernel/CMakeLists.txt
Normal file
@@ -0,0 +1,79 @@
|
||||
# MetalOS Kernel CMakeLists.txt
|
||||
# Builds minimal kernel binary
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(MetalOS_Kernel C ASM)
|
||||
|
||||
# Source files
|
||||
set(KERNEL_SOURCES
|
||||
src/main.c
|
||||
)
|
||||
|
||||
# Find all source files in subdirectories
|
||||
file(GLOB_RECURSE CORE_SOURCES "src/core/*.c")
|
||||
file(GLOB_RECURSE HAL_SOURCES "src/hal/*.c")
|
||||
file(GLOB_RECURSE DRIVER_SOURCES "src/drivers/*.c")
|
||||
file(GLOB_RECURSE SYSCALL_SOURCES "src/syscall/*.c")
|
||||
|
||||
list(APPEND KERNEL_SOURCES
|
||||
${CORE_SOURCES}
|
||||
${HAL_SOURCES}
|
||||
${DRIVER_SOURCES}
|
||||
${SYSCALL_SOURCES}
|
||||
)
|
||||
|
||||
# Compiler flags for kernel
|
||||
set(KERNEL_CFLAGS
|
||||
-Wall
|
||||
-Wextra
|
||||
-Werror
|
||||
-ffreestanding
|
||||
-fno-stack-protector
|
||||
-mno-red-zone
|
||||
-mcmodel=large
|
||||
-O2
|
||||
)
|
||||
|
||||
# Create object library
|
||||
add_library(kernel_obj OBJECT ${KERNEL_SOURCES})
|
||||
target_include_directories(kernel_obj PRIVATE include)
|
||||
target_compile_options(kernel_obj PRIVATE ${KERNEL_CFLAGS})
|
||||
|
||||
# Create kernel binary
|
||||
add_executable(kernel_elf $<TARGET_OBJECTS:kernel_obj>)
|
||||
set_target_properties(kernel_elf PROPERTIES
|
||||
OUTPUT_NAME metalos.elf
|
||||
LINKER_LANGUAGE C
|
||||
)
|
||||
target_link_options(kernel_elf PRIVATE
|
||||
-nostdlib
|
||||
-T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld
|
||||
)
|
||||
|
||||
# Custom command to create flat binary
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/metalos.bin
|
||||
COMMAND ${CMAKE_OBJCOPY}
|
||||
-O binary
|
||||
$<TARGET_FILE:kernel_elf>
|
||||
${CMAKE_CURRENT_BINARY_DIR}/metalos.bin
|
||||
DEPENDS kernel_elf
|
||||
COMMENT "Creating kernel flat binary"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Custom target for the binary
|
||||
add_custom_target(kernel_bin ALL
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/metalos.bin
|
||||
)
|
||||
|
||||
# Install target
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/metalos.bin
|
||||
DESTINATION boot
|
||||
)
|
||||
|
||||
# Print status
|
||||
message(STATUS "Kernel configuration:")
|
||||
message(STATUS " Sources: ${KERNEL_SOURCES}")
|
||||
message(STATUS " Output: metalos.bin")
|
||||
47
tests/CMakeLists.txt
Normal file
47
tests/CMakeLists.txt
Normal file
@@ -0,0 +1,47 @@
|
||||
# MetalOS Tests CMakeLists.txt
|
||||
# Builds and runs unit tests
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(MetalOS_Tests C)
|
||||
|
||||
# Find all test source files
|
||||
file(GLOB TEST_SOURCES "unit/*.c")
|
||||
|
||||
# Include directories
|
||||
include_directories(
|
||||
include
|
||||
../bootloader/include
|
||||
../kernel/include
|
||||
)
|
||||
|
||||
# Create a test executable for each test file
|
||||
foreach(test_source ${TEST_SOURCES})
|
||||
# Get the test name from the file name
|
||||
get_filename_component(test_name ${test_source} NAME_WE)
|
||||
|
||||
# Create test executable
|
||||
add_executable(${test_name} ${test_source})
|
||||
|
||||
# Set compiler flags
|
||||
target_compile_options(${test_name} PRIVATE
|
||||
-Wall
|
||||
-Wextra
|
||||
-std=c11
|
||||
)
|
||||
|
||||
# Add as a test
|
||||
add_test(NAME ${test_name} COMMAND ${test_name})
|
||||
endforeach()
|
||||
|
||||
# Custom target to run all tests
|
||||
add_custom_target(run_tests
|
||||
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
|
||||
DEPENDS ${TEST_SOURCES}
|
||||
COMMENT "Running all tests"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
# Print status
|
||||
message(STATUS "Tests configuration:")
|
||||
message(STATUS " Test sources: ${TEST_SOURCES}")
|
||||
Reference in New Issue
Block a user