summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLevent Kaya <levent@dev>2025-11-06 01:53:21 +0300
committerLevent Kaya <levent@dev>2025-11-06 01:53:21 +0300
commit2140653c001a2ac415fb717d48ca2b55ff2aa037 (patch)
tree5dfc3697eee8aca4308aded02c95c2a32bccf509
parentf6f40266ba57ab2df99b897c375f85f0a8a97856 (diff)
[feature] basic demo screen
-rw-r--r--.gitignore2
-rw-r--r--CMakeLists.txt259
-rwxr-xr-xbuild.sh427
-rw-r--r--cmake/compiler_warnings.cmake7
-rw-r--r--src/CMakeLists.txt75
-rw-r--r--src/main.cpp114
-rw-r--r--tests/CMakeLists.txt49
7 files changed, 812 insertions, 121 deletions
diff --git a/.gitignore b/.gitignore
index 000c70c..c504c0a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,5 @@ Makefile
# OS
.DS_Store
+
+external/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3669e77..0db7d1a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,30 +1,253 @@
cmake_minimum_required(VERSION 3.15)
-project(boltdbg VERSION 0.1.0 LANGUAGES C CXX)
-# Load BoltDBG option definitions first
-list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
-include(BoltDbgOptions)
+# ============================================================================
+# Project Definition
+# ============================================================================
+project(BoltDBG
+ VERSION 0.1.0
+ DESCRIPTION "Modern C++ Debugger with GUI"
+ LANGUAGES C CXX
+)
+
+# ============================================================================
+# C++ Standard
+# ============================================================================
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
-# Some basic options
-set(CMAKE_CXX_STANDARD 23)
set(CMAKE_C_STANDARD 11)
+set(CMAKE_C_STANDARD_REQUIRED ON)
-# include helper modules
-include(compiler_warnings)
-include(Sanitizer)
-include(PlatformConfig)
-#include(CodeStyle)
+# Export compile commands for IDE support
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
-# src
-add_subdirectory(src)
+# Make builds more robust when mixing static/shared libs
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+# ============================================================================
+# Options
+# ============================================================================
+option(BOLTDBG_BUILD_TESTS "Build test suite" OFF)
+option(BOLTDBG_BUILD_EXAMPLES "Build examples" OFF)
+option(BOLTDBG_USE_SYSTEM_LIBS "Prefer system libraries" ON)
+option(BOLTDBG_ENABLE_ASAN "Enable Address Sanitizer" OFF)
+option(BOLTDBG_ENABLE_UBSAN "Enable UB Sanitizer" OFF)
+option(BOLTDBG_ENABLE_TSAN "Enable Thread Sanitizer" OFF)
-# add optional format targets if enabled
-if (BOLTDBG_ENABLE_FORMAT_TARGET)
- #add_clang_format_target(boltdbg)
+# ============================================================================
+# CMake Modules Path
+# ============================================================================
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
+# Include compiler warnings if available
+if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/CompilerWarnings.cmake")
+ include(CompilerWarnings)
endif()
-# Tests
-if (BOLTDBG_BUILD_TESTS)
+# Include sanitizers if available
+if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Sanitizers.cmake")
+ include(Sanitizers)
+endif()
+
+# ============================================================================
+# Basic packages
+# ============================================================================
+# Threads (pthread) is commonly required for libraries and linking
+find_package(Threads REQUIRED)
+
+# ============================================================================
+# Dependencies (FetchContent)
+# ============================================================================
+include(FetchContent)
+
+# --- GLFW ---
+if(BOLTDBG_USE_SYSTEM_LIBS)
+ find_package(glfw3 3.3 QUIET)
+endif()
+
+if(NOT TARGET glfw AND NOT TARGET glfw3::glfw3)
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/external/glfw/CMakeLists.txt")
+ message(STATUS "Using vendored GLFW from external/glfw")
+ set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
+ set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
+ set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
+ set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)
+ add_subdirectory(external/glfw)
+ else()
+ message(STATUS "Fetching GLFW via FetchContent")
+ FetchContent_Declare(
+ glfw
+ GIT_REPOSITORY https://github.com/glfw/glfw.git
+ GIT_TAG 3.3.8
+ GIT_SHALLOW TRUE
+ )
+ set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
+ set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
+ set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
+ FetchContent_MakeAvailable(glfw)
+ endif()
+endif()
+
+# Create alias if needed
+if(TARGET glfw3::glfw3 AND NOT TARGET glfw)
+ add_library(glfw ALIAS glfw3::glfw3)
+endif()
+
+# --- spdlog ---
+if(BOLTDBG_USE_SYSTEM_LIBS)
+ find_package(spdlog 1.11 QUIET)
+endif()
+
+if(NOT TARGET spdlog::spdlog)
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/external/spdlog/CMakeLists.txt")
+ message(STATUS "Using vendored spdlog from external/spdlog")
+ add_subdirectory(external/spdlog)
+ else()
+ message(STATUS "Fetching spdlog via FetchContent")
+ FetchContent_Declare(
+ spdlog
+ GIT_REPOSITORY https://github.com/gabime/spdlog.git
+ GIT_TAG v1.11.0
+ GIT_SHALLOW TRUE
+ )
+ FetchContent_MakeAvailable(spdlog)
+ endif()
+endif()
+
+# --- ImGui ---
+if(NOT TARGET imgui)
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/external/imgui/imgui.cpp")
+ message(STATUS "Using vendored ImGui from external/imgui")
+ set(IMGUI_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/imgui")
+ else()
+ message(STATUS "Fetching ImGui via FetchContent")
+ FetchContent_Declare(
+ imgui
+ GIT_REPOSITORY https://github.com/ocornut/imgui.git
+ GIT_TAG v1.89.8
+ GIT_SHALLOW TRUE
+ )
+ FetchContent_MakeAvailable(imgui)
+ set(IMGUI_DIR ${imgui_SOURCE_DIR})
+ endif()
+
+ # Create ImGui library target
+ add_library(imgui STATIC
+ ${IMGUI_DIR}/imgui.cpp
+ ${IMGUI_DIR}/imgui_demo.cpp
+ ${IMGUI_DIR}/imgui_draw.cpp
+ ${IMGUI_DIR}/imgui_tables.cpp
+ ${IMGUI_DIR}/imgui_widgets.cpp
+ ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp
+ ${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp
+ )
+ target_include_directories(imgui PUBLIC
+ ${IMGUI_DIR}
+ ${IMGUI_DIR}/backends
+ )
+
+ # Link libraries imgui backend needs — glad/glfw/OpenGL/Threads
+ # Note: glad and platform libs may be created later; using PUBLIC allows consumers to pick them up.
+ # We'll append actual platform libs after platform-detection block below.
+endif()
+
+# --- GLAD ---
+if(NOT TARGET glad)
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/external/glad/src/glad.c")
+ message(STATUS "Using vendored GLAD from external/glad")
+ set(GLAD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/glad")
+ # Create GLAD library target manually
+ add_library(glad STATIC ${GLAD_DIR}/src/glad.c)
+ target_include_directories(glad PUBLIC ${GLAD_DIR}/include)
+ else()
+ message(STATUS "Fetching GLAD via FetchContent")
+ FetchContent_Declare(
+ glad
+ GIT_REPOSITORY https://github.com/Dav1dde/glad.git
+ GIT_TAG v0.1.36
+ GIT_SHALLOW TRUE
+ )
+ FetchContent_MakeAvailable(glad)
+ # GLAD's CMakeLists.txt typically creates the 'glad' target automatically.
+ endif()
+endif()
+
+# ============================================================================
+# Platform-specific OpenGL and platform libs
+# ============================================================================
+set(PLATFORM_LIBS "")
+if(APPLE)
+ find_library(COCOA_FRAMEWORK Cocoa REQUIRED)
+ find_library(IOKIT_FRAMEWORK IOKit REQUIRED)
+ find_library(COREVIDEO_FRAMEWORK CoreVideo REQUIRED)
+ find_library(OPENGL_FRAMEWORK OpenGL REQUIRED)
+ list(APPEND PLATFORM_LIBS ${COCOA_FRAMEWORK} ${IOKIT_FRAMEWORK} ${COREVIDEO_FRAMEWORK} ${OPENGL_FRAMEWORK})
+elseif(WIN32)
+ list(APPEND PLATFORM_LIBS opengl32)
+else()
+ # Unix/Linux
+ find_package(OpenGL REQUIRED)
+ list(APPEND PLATFORM_LIBS OpenGL::GL ${CMAKE_DL_LIBS})
+ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ list(APPEND PLATFORM_LIBS pthread)
+ endif()
+endif()
+
+# Now that PLATFORM_LIBS and glad exist, make sure imgui links them
+if(TARGET imgui)
+ # link what we have: glfw, glad, platform libs, threads
+ # Use PRIVATE here because imgui's public headers don't require these symbols, but keep PUBLIC if consumers need transitive link.
+ # Use PUBLIC to be safe for consumers (exe targets).
+ target_link_libraries(imgui PUBLIC glfw)
+ if(TARGET glad)
+ target_link_libraries(imgui PUBLIC glad)
+ endif()
+ # PLATFORM_LIBS may contain import targets or plain names; link them too
+ if(PLATFORM_LIBS)
+ target_link_libraries(imgui PUBLIC ${PLATFORM_LIBS})
+ endif()
+ # Threads
+ target_link_libraries(imgui PUBLIC Threads::Threads)
+endif()
+
+# ============================================================================
+# Subdirectories
+# ============================================================================
+# Add src (this file should contain project targets like executable/library)
+add_subdirectory(src)
+
+# Tests and examples
+if(BOLTDBG_BUILD_TESTS AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/CMakeLists.txt")
enable_testing()
add_subdirectory(tests)
endif()
+
+if(BOLTDBG_BUILD_EXAMPLES AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/examples/CMakeLists.txt")
+ add_subdirectory(examples)
+endif()
+
+# ============================================================================
+# Sanitizers flags summary (if your included Sanitizers.cmake sets flags, keep it)
+# (Sanitizers.cmake is optional and included at top if exists)
+# ============================================================================
+
+# ============================================================================
+# Summary
+# ============================================================================
+message(STATUS "")
+message(STATUS "========================================")
+message(STATUS " BoltDBG ${PROJECT_VERSION}")
+message(STATUS "========================================")
+message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
+message(STATUS "C++ compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
+message(STATUS "")
+message(STATUS "Options:")
+message(STATUS " Build tests: ${BOLTDBG_BUILD_TESTS}")
+message(STATUS " Build examples: ${BOLTDBG_BUILD_EXAMPLES}")
+message(STATUS " System libs: ${BOLTDBG_USE_SYSTEM_LIBS}")
+message(STATUS " ASAN: ${BOLTDBG_ENABLE_ASAN}")
+message(STATUS " UBSAN: ${BOLTDBG_ENABLE_UBSAN}")
+message(STATUS " TSAN: ${BOLTDBG_ENABLE_TSAN}")
+message(STATUS "========================================")
+message(STATUS "")
diff --git a/build.sh b/build.sh
index f9a5a9e..339b19a 100755
--- a/build.sh
+++ b/build.sh
@@ -1,101 +1,374 @@
#!/usr/bin/env bash
-# run.sh - simple build+test helper for BoltDBG
+# build.sh - Professional build script for BoltDBG (improved)
+#
# Usage:
-# ./run.sh # default: Debug build, ASAN off, run tests
-# BUILD_TYPE=Release ./run.sh
-# ASAN=ON ./run.sh
-# CLEAN=1 ./run.sh # remove build/ then do everything
-# INSTALL=1 ./run.sh # run `cmake --install` after build
+# ./build.sh # Debug build (preset: debug)
+# ./build.sh --preset release # Release build
+# ./build.sh --preset debug-asan # Debug with ASAN
+# ./build.sh --clean # Clean build
+# ./build.sh --install # Build and install
+# ./build.sh --format # Format code before build
+# ./build.sh --help # Show help
#
+# Environment variables:
+# CMAKE_PRESET - CMake preset to use (default: debug)
+# JOBS - Number of parallel jobs (default: auto -> detected)
+# BUILD_DIR - Build directory (default: build/<preset>)
+# INSTALL_PREFIX - Install prefix (default: /usr/local)
+
set -euo pipefail
-# Defaults (can be overridden by environment variables)
-: "${BUILD_TYPE:=Debug}"
-: "${ASAN:=OFF}" # ON or OFF
-: "${CLEAN:=0}" # 1 to remove build dir first
-: "${JOBS:=auto}" # number of parallel build jobs; auto = detect
-: "${INSTALL:=0}" # 1 to install after build
-: "${CMAKE_EXTRA_ARGS:=""}" # any extra args for cmake
-
-# Detect number of processors
-if [ "$JOBS" = "auto" ]; then
- if command -v nproc >/dev/null 2>&1; then
- JOBS=$(nproc)
- elif [ "$(uname)" = "Darwin" ] && command -v sysctl >/dev/null 2>&1; then
- JOBS=$(sysctl -n hw.ncpu)
- else
+# ============================================================================
+# Configuration
+# ============================================================================
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+ROOT_DIR="${SCRIPT_DIR}"
+
+# Defaults (can be overridden by env)
+: "${CMAKE_PRESET:=debug}"
+: "${JOBS:=auto}"
+: "${INSTALL_PREFIX:=/usr/local}"
+: "${VERBOSE:=0}"
+
+# Flags
+CLEAN_BUILD=1
+RUN_INSTALL=0
+RUN_TESTS=0
+RUN_FORMAT=0
+SHOW_HELP=0
+
+# ============================================================================
+# Colors and Formatting
+# ============================================================================
+
+if [[ -t 1 ]]; then
+ RED='\033[0;31m'
+ GREEN='\033[0;32m'
+ YELLOW='\033[1;33m'
+ BLUE='\033[0;34m'
+ BOLD='\033[1m'
+ NC='\033[0m' # No Color
+else
+ RED=''
+ GREEN=''
+ YELLOW=''
+ BLUE=''
+ BOLD=''
+ NC=''
+fi
+
+# ============================================================================
+# Helper Functions
+# ============================================================================
+
+log_info() { echo -e "${BLUE}[INFO]${NC} $*"; }
+log_success() { echo -e "${GREEN}[SUCCESS]${NC} $*"; }
+log_warning() { echo -e "${YELLOW}[WARNING]${NC} $*"; }
+log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
+log_header() {
+ echo
+ echo -e "${BOLD}========================================${NC}"
+ echo -e "${BOLD}$*${NC}"
+ echo -e "${BOLD}========================================${NC}"
+}
+
+require_cmd() {
+ if ! command -v "$1" >/dev/null 2>&1; then
+ log_error "Required command '$1' not found. Please install it."
+ exit 2
+ fi
+}
+
+detect_jobs() {
+ if [[ "${JOBS}" == "auto" ]]; then
+ if command -v nproc >/dev/null 2>&1; then
+ JOBS="$(nproc)"
+ elif [[ "$(uname)" == "Darwin" ]] && command -v sysctl >/dev/null 2>&1; then
+ JOBS="$(sysctl -n hw.ncpu)"
+ else
+ JOBS=2
+ fi
+ fi
+ # ensure integer
+ if ! [[ "${JOBS}" =~ ^[0-9]+$ ]]; then
JOBS=2
fi
+}
+
+show_help() {
+ cat << EOF
+${BOLD}BoltDBG Build Script${NC}
+
+USAGE:
+ $0 [OPTIONS]
+
+OPTIONS:
+ --preset PRESET CMake preset (debug, release, debug-asan, etc.)
+ --clean Remove build directory before building
+ --install Install after building
+ --no-tests Skip running tests
+ --format Run code formatter before building
+ --jobs N Number of parallel build jobs (default: auto)
+ --prefix PATH Installation prefix (default: /usr/local)
+ --verbose Enable verbose output
+ --help Show this help message
+
+PRESETS:
+ debug Debug build with symbols
+ release Optimized release build
+ debug-asan Debug with Address Sanitizer
+ debug-ubsan Debug with UB Sanitizer
+ debug-tsan Debug with Thread Sanitizer
+ ci CI/CD build configuration
+
+EXAMPLES:
+ $0 # Basic debug build
+ $0 --preset release # Release build
+ $0 --preset debug-asan --clean # Clean ASAN build
+ $0 --install --prefix ~/local # Build and install to ~/local
+ $0 --format --preset release # Format then build release
+
+EOF
+ exit 0
+}
+
+# ============================================================================
+# Argument Parsing
+# ============================================================================
+
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ --preset)
+ CMAKE_PRESET="${2:-}"
+ shift 2
+ ;;
+ --clean)
+ CLEAN_BUILD=1
+ shift
+ ;;
+ --install)
+ RUN_INSTALL=1
+ shift
+ ;;
+ --no-tests)
+ RUN_TESTS=0
+ shift
+ ;;
+ --format)
+ RUN_FORMAT=1
+ shift
+ ;;
+ --jobs)
+ JOBS="${2:-}"
+ shift 2
+ ;;
+ --prefix)
+ INSTALL_PREFIX="${2:-}"
+ shift 2
+ ;;
+ --verbose)
+ VERBOSE=1
+ shift
+ ;;
+ --help|-h)
+ SHOW_HELP=1
+ shift
+ ;;
+ *)
+ log_error "Unknown option: $1"
+ echo "Use --help for usage information"
+ exit 1
+ ;;
+ esac
+done
+
+if [[ $SHOW_HELP -eq 1 ]]; then
+ show_help
fi
-ROOT_DIR="$(cd "$(dirname "$0")" && pwd)"
-BUILD_DIR="${ROOT_DIR}/build"
-
-echo "=== BoltDBG build helper ==="
-echo "Root: ${ROOT_DIR}"
-echo "Build dir: ${BUILD_DIR}"
-echo "Build type: ${BUILD_TYPE}"
-echo "ASAN: ${ASAN}"
-echo "Jobs: ${JOBS}"
-echo "Clean: ${CLEAN}"
-echo "Install: ${INSTALL}"
-echo "Extra args: ${CMAKE_EXTRA_ARGS}"
-echo
+# ============================================================================
+# Prerequisites
+# ============================================================================
+
+require_cmd cmake
+require_cmd git
+
+detect_jobs
+
+BUILD_DIR="${ROOT_DIR}/build/${CMAKE_PRESET}"
+
+# ============================================================================
+# Main Build Process
+# ============================================================================
+
+log_header "BoltDBG Build Configuration"
+log_info "Root directory: ${ROOT_DIR}"
+log_info "Build directory: ${BUILD_DIR}"
+log_info "CMake preset: ${CMAKE_PRESET}"
+log_info "Parallel jobs: ${JOBS}"
+log_info "Install prefix: ${INSTALL_PREFIX}"
+log_info "Clean build: ${CLEAN_BUILD}"
+log_info "Run tests: ${RUN_TESTS}"
+log_info "Run install: ${RUN_INSTALL}"
+
+# Step 1: Code formatting (optional)
+if [[ $RUN_FORMAT -eq 1 ]]; then
+ log_header "Step 1/6: Code Formatting"
+ if [[ -f "${ROOT_DIR}/scripts/format.sh" ]]; then
+ "${ROOT_DIR}/scripts/format.sh"
+ log_success "Code formatted"
+ else
+ log_warning "scripts/format.sh not found, skipping formatting"
+ fi
+else
+ log_info "Skipping code formatting (use --format to enable)"
+fi
-# Step 0: optionally clean
-if [ "${CLEAN}" = "1" ]; then
- echo "[1/6] Cleaning build directory..."
- rm -rf "${BUILD_DIR}"
+# Step 2: Fetch dependencies (optional helper)
+# If you use submodules or have a fetch script, run it here.
+if [[ -f "${ROOT_DIR}/scripts/fetch_deps.sh" ]]; then
+ log_header "Step 2/6: Fetch Dependencies"
+ "${ROOT_DIR}/scripts/fetch_deps.sh" || {
+ log_warning "fetch_deps.sh failed or returned non-zero, continuing anyway"
+ }
+else
+ log_info "No fetch_deps.sh found — relying on CMake FetchContent or vendored deps"
fi
-# Step 1: init/update submodules (if any)
-if [ -f .gitmodules ]; then
- echo "[2/6] Initializing/updating git submodules..."
- git submodule sync --recursive || true
- git submodule update --init --recursive --depth 1 || true
+# Step 3: Clean (optional)
+if [[ $CLEAN_BUILD -eq 1 ]]; then
+ log_header "Step 3/6: Clean Build Directory"
+ if [[ -d "${BUILD_DIR}" ]]; then
+ log_info "Removing ${BUILD_DIR}..."
+ rm -rf "${BUILD_DIR}"
+ log_success "Build directory cleaned"
+ else
+ log_info "Build directory does not exist, nothing to clean"
+ fi
else
- echo "[2/6] No .gitmodules found — skipping submodule init."
+ log_info "Using existing build directory (use --clean for fresh build)"
fi
-# Step 2: create build dir
-echo "[3/6] Preparing build directory..."
+# Step 4: Configure
+log_header "Step 4/6: CMake Configure"
mkdir -p "${BUILD_DIR}"
-cd "${BUILD_DIR}"
-
-# Step 3: run cmake configure
-echo "[4/6] Configuring with CMake..."
-cmake \
- -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
- -DBOLTDBG_ENABLE_ASAN="${ASAN}" \
- ${CMAKE_EXTRA_ARGS} \
- "${ROOT_DIR}"
-
-# Step 4: build
-echo "[5/6] Building (parallel jobs: ${JOBS})..."
-# Use cmake --build for multi-config generators as well
-cmake --build . -- -j"${JOBS}"
-
-# Step 5: run tests (if enabled in CMake)
-if cmake --build . --target help | grep -q "RUN_TESTS" || true; then
- echo "[6/6] Running ctest (if any tests present)..."
- # Prefer ctest binary if available
+
+# If CMakePresets.json exists, prefer using presets. Otherwise fallback to manual args.
+CMAKE_CONF_ARGS=()
+CMAKE_CONF_ARGS+=("-DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX}")
+
+if [[ "${VERBOSE}" -eq 1 ]]; then
+ CMAKE_CONF_ARGS+=("-DCMAKE_VERBOSE_MAKEFILE=ON")
+fi
+
+if [[ -f "${ROOT_DIR}/CMakePresets.json" ]]; then
+ # Use preset; need to call with -S and -B for predictable behavior
+ log_info "Found CMakePresets.json — configuring with preset '${CMAKE_PRESET}'"
+ cmake -S "${ROOT_DIR}" -B "${BUILD_DIR}" --preset "${CMAKE_PRESET}" "${CMAKE_CONF_ARGS[@]}"
+else
+ # Fallback: map simple preset names to CMAKE_BUILD_TYPE and sanitizer flags
+ log_info "No CMakePresets.json — using fallback configure for preset '${CMAKE_PRESET}'"
+ case "${CMAKE_PRESET}" in
+ debug)
+ CMAKE_CONF_ARGS+=("-DCMAKE_BUILD_TYPE=Debug")
+ ;;
+ release)
+ CMAKE_CONF_ARGS+=("-DCMAKE_BUILD_TYPE=Release")
+ ;;
+ debug-asan)
+ CMAKE_CONF_ARGS+=("-DCMAKE_BUILD_TYPE=Debug" "-DBOLTDBG_ENABLE_ASAN=ON")
+ ;;
+ debug-ubsan)
+ CMAKE_CONF_ARGS+=("-DCMAKE_BUILD_TYPE=Debug" "-DBOLTDBG_ENABLE_UBSAN=ON")
+ ;;
+ debug-tsan)
+ CMAKE_CONF_ARGS+=("-DCMAKE_BUILD_TYPE=Debug" "-DBOLTDBG_ENABLE_TSAN=ON")
+ ;;
+ ci)
+ CMAKE_CONF_ARGS+=("-DCMAKE_BUILD_TYPE=RelWithDebInfo")
+ ;;
+ *)
+ # default fallback
+ CMAKE_CONF_ARGS+=("-DCMAKE_BUILD_TYPE=Debug")
+ log_warning "Unknown preset '${CMAKE_PRESET}', falling back to Debug build type"
+ ;;
+ esac
+
+ # Run configure explicitly with -S and -B
+ log_info "Running: cmake -S ${ROOT_DIR} -B ${BUILD_DIR} ${CMAKE_CONF_ARGS[*]}"
+ cmake -S "${ROOT_DIR}" -B "${BUILD_DIR}" "${CMAKE_CONF_ARGS[@]}"
+fi
+
+log_success "Configuration complete"
+
+# Step 5: Build
+log_header "Step 5/6: Build"
+
+# Build args for cmake --build
+CMAKE_BUILD_ARGS=(--build "${BUILD_DIR}" --parallel "${JOBS}")
+if [[ "${VERBOSE}" -eq 1 ]]; then
+ CMAKE_BUILD_ARGS+=(--verbose)
+fi
+
+log_info "Running: cmake ${CMAKE_BUILD_ARGS[*]}"
+cmake "${CMAKE_BUILD_ARGS[@]}"
+log_success "Build complete"
+
+# Step 6: Tests
+if [[ $RUN_TESTS -eq 1 ]]; then
+ log_header "Step 6/6: Run Tests"
if command -v ctest >/dev/null 2>&1; then
- ctest --output-on-failure -j "${JOBS}" || {
- echo "Some tests failed."
- # do not exit immediately so user sees build artifacts; still return non-zero
- exit 1
- }
+ (
+ cd "${BUILD_DIR}"
+ if ! ctest --output-on-failure --parallel "${JOBS}"; then
+ log_error "Some tests failed"
+ exit 1
+ fi
+ )
+ log_success "All tests passed"
else
- echo "ctest not found; skipping tests."
+ log_warning "ctest not found, skipping tests"
fi
else
- echo "[6/6] No tests target detected; skipping ctest."
+ log_info "Skipping tests (use --no-tests to enable)"
+fi
+
+# Optional: Install
+if [[ $RUN_INSTALL -eq 1 ]]; then
+ log_header "Installing"
+ cmake --install "${BUILD_DIR}" --prefix "${INSTALL_PREFIX}"
+ log_success "Installation complete to ${INSTALL_PREFIX}"
+fi
+
+# ============================================================================
+# Summary
+# ============================================================================
+
+log_header "Build Complete"
+
+# Try to guess executable path, but don't assume too much
+POSSIBLE_BIN="${BUILD_DIR}/src/boltdbg"
+if [[ -x "${POSSIBLE_BIN}" ]]; then
+ log_success "Executable: ${POSSIBLE_BIN}"
+else
+ log_info "Executable not found at ${POSSIBLE_BIN}. Check your targets inside ${BUILD_DIR}"
+ log_info "You can inspect build tree or run: cmake --build ${BUILD_DIR} --target <your-target>"
fi
-# Optional install
-if [ "${INSTALL}" = "1" ]; then
- echo "[+] Installing to CMAKE_INSTALL_PREFIX..."
- cmake --install . --prefix "${CMAKE_INSTALL_PREFIX:-/usr/local}"
+if [[ $RUN_INSTALL -eq 1 ]]; then
+ log_success "Installed to: ${INSTALL_PREFIX}/bin/ (if install step created it)"
fi
-echo "=== Build finished successfully ==="
+echo
+log_info "To run the application (if present):"
+echo " ${POSSIBLE_BIN}"
+echo
+log_info "To run tests manually:"
+echo " cd ${BUILD_DIR} && ctest --output-on-failure"
+echo
+log_info "To install manually:"
+echo " cmake --install ${BUILD_DIR} --prefix ${INSTALL_PREFIX}"
+echo
+
+exit 0
diff --git a/cmake/compiler_warnings.cmake b/cmake/compiler_warnings.cmake
deleted file mode 100644
index bc557eb..0000000
--- a/cmake/compiler_warnings.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-function(set_project_warnings target)
- if (MSVC)
- target_compile_options(${target} PRIVATE /W4 /permissive-)
- else()
- target_compile_options(${target} PRIVATE -Wall -Wextra -Wpedantic -Werror)
- endif()
-endfunction()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 34791b0..9875cd7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,5 +1,72 @@
-add_library(libboltdbg INTERFACE)
-target_include_directories(libboltdbg INTERFACE ${CMAKE_SOURCE_DIR}/include)
+# src/CMakeLists.txt
+cmake_minimum_required(VERSION 3.15) # local guard if included standalone
-add_executable(boltdbg main.cpp)
-target_link_libraries(boltdbg PRIVATE libboltdbg)
+# Collect core sources (placeholder + real sources later)
+set(BOLTDBG_CORE_SOURCES
+ dummy.cpp # placeholder; replace/add real core sources here
+ # src/core/debugger.cpp
+ # src/core/process.cpp
+)
+
+# Application executable
+add_executable(boltdbg
+ main.cpp
+ ${BOLTDBG_CORE_SOURCES}
+)
+
+# Public include dirs (so main and core can include project headers)
+target_include_directories(boltdbg PRIVATE ${CMAKE_SOURCE_DIR}/include)
+
+# Ensure imgui include dirs available for includes like "imgui.h" and "backends/..."
+target_include_directories(boltdbg PRIVATE
+ ${CMAKE_SOURCE_DIR}/external/imgui
+ ${CMAKE_SOURCE_DIR}/external/imgui/backends
+)
+
+# Link imgui (various targets depending on provider)
+if (TARGET imgui)
+ target_link_libraries(boltdbg PRIVATE imgui)
+elseif (TARGET imgui::imgui)
+ target_link_libraries(boltdbg PRIVATE imgui::imgui)
+endif()
+
+# GLFW linking: prefer config target then vendor
+if (TARGET GLFW::GLFW)
+ target_link_libraries(boltdbg PRIVATE GLFW::GLFW)
+elseif (TARGET glfw)
+ target_link_libraries(boltdbg PRIVATE glfw)
+endif()
+
+# glad (loader)
+if (TARGET glad::glad)
+ target_link_libraries(boltdbg PRIVATE glad::glad)
+elseif (TARGET glad)
+ target_link_libraries(boltdbg PRIVATE glad)
+endif()
+
+# spdlog
+if (TARGET spdlog::spdlog)
+ target_link_libraries(boltdbg PRIVATE spdlog::spdlog)
+elseif (TARGET spdlog)
+ target_link_libraries(boltdbg PRIVATE spdlog)
+endif()
+
+# Platform OpenGL libs
+if (APPLE)
+ find_library(COCOA_FRAMEWORK Cocoa REQUIRED)
+ find_library(IOKIT_FRAMEWORK IOKit REQUIRED)
+ find_library(COREVIDEO_FRAMEWORK CoreVideo REQUIRED)
+ find_library(OPENGL_FRAMEWORK OpenGL REQUIRED)
+ target_link_libraries(boltdbg PRIVATE ${COCOA_FRAMEWORK} ${IOKIT_FRAMEWORK} ${COREVIDEO_FRAMEWORK} ${OPENGL_FRAMEWORK})
+elseif (WIN32)
+ target_link_libraries(boltdbg PRIVATE opengl32)
+else()
+ find_package(OpenGL REQUIRED)
+ target_link_libraries(boltdbg PRIVATE OpenGL::GL dl pthread)
+endif()
+
+# Optional: apply project warning settings if you created compiler_warnings.cmake
+if (EXISTS "${CMAKE_SOURCE_DIR}/cmake/compiler_warnings.cmake")
+ include(${CMAKE_SOURCE_DIR}/cmake/compiler_warnings.cmake)
+ set_project_warnings(boltdbg)
+endif()
diff --git a/src/main.cpp b/src/main.cpp
index 7bd7cfb..0a23004 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,6 +1,118 @@
+// src/main.cpp
#include <iostream>
+// spdlog
+#include <spdlog/spdlog.h>
+
+// Prevent GLFW from including OpenGL headers (so glad can provide them)
+#define GLFW_INCLUDE_NONE
+#include <GLFW/glfw3.h>
+
+// GL loader (glad) - include after GLFW_INCLUDE_NONE so glad can provide GL headers
+#if __has_include("glad/glad.h")
+#include <glad/glad.h>
+#define HAVE_GLAD 1
+#else
+#define HAVE_GLAD 0
+#endif
+
+// Now include ImGui and its backends (they expect glfw + GL loader to be present)
+#include "imgui.h"
+#include "backends/imgui_impl_glfw.h"
+#include "backends/imgui_impl_opengl3.h"
+
int main(int argc, char** argv) {
- std::cout << "BoltDBG (bootstrap) v0.1.0\n";
+ // init logger
+ try {
+ spdlog::set_level(spdlog::level::info);
+ spdlog::info("BoltDBG demo starting (spdlog initialized).");
+ } catch (const std::exception &e) {
+ std::cerr << "spdlog init failed: " << e.what() << std::endl;
+ }
+
+ if (!glfwInit()) {
+ spdlog::error("Failed to initialize GLFW");
+ return 1;
+ }
+
+ // GL settings (3.3 core as example)
+ const char* glsl_version = "#version 330";
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
+#if __APPLE__
+ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+#endif
+
+ GLFWwindow* window = glfwCreateWindow(1280, 720, "BoltDBG - ImGui + spdlog demo", NULL, NULL);
+ if (!window) {
+ spdlog::error("Failed to create GLFW window");
+ glfwTerminate();
+ return 1;
+ }
+ glfwMakeContextCurrent(window);
+ glfwSwapInterval(1);
+
+#if HAVE_GLAD
+ if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
+ spdlog::error("Failed to initialize GLAD");
+ return 1;
+ }
+#else
+ spdlog::warn("GLAD not detected at compile-time. If you experience GL symbol errors, add glad.");
+#endif
+
+ // ImGui init
+ IMGUI_CHECKVERSION();
+ ImGui::CreateContext();
+ ImGuiIO &io = ImGui::GetIO(); (void)io;
+ ImGui::StyleColorsDark();
+
+ ImGui_ImplGlfw_InitForOpenGL(window, true);
+ ImGui_ImplOpenGL3_Init(glsl_version);
+
+ spdlog::info("Entering main loop.");
+
+ bool show_demo = false;
+ int click_count = 0;
+
+ while (!glfwWindowShouldClose(window)) {
+ glfwPollEvents();
+
+ ImGui_ImplOpenGL3_NewFrame();
+ ImGui_ImplGlfw_NewFrame();
+ ImGui::NewFrame();
+
+ ImGui::Begin("BoltDBG - Demo");
+ ImGui::Text("Hello from BoltDBG demo!");
+ if (ImGui::Button("Log info with spdlog")) {
+ click_count++;
+ spdlog::info("Button clicked {} times", click_count);
+ }
+ ImGui::Text("Click count: %d", click_count);
+ ImGui::End();
+
+ if (show_demo) ImGui::ShowDemoWindow(&show_demo);
+
+ ImGui::Render();
+ int display_w, display_h;
+ glfwGetFramebufferSize(window, &display_w, &display_h);
+ glViewport(0, 0, display_w, display_h);
+ glClearColor(0.1f, 0.12f, 0.14f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
+
+ glfwSwapBuffers(window);
+ }
+
+ // cleanup
+ ImGui_ImplOpenGL3_Shutdown();
+ ImGui_ImplGlfw_Shutdown();
+ ImGui::DestroyContext();
+
+ glfwDestroyWindow(window);
+ glfwTerminate();
+
+ spdlog::info("BoltDBG demo exiting.");
return 0;
}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 67baeda..416a3e5 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,20 +1,41 @@
-# Unit tests for BoltDBG
+# tests/CMakeLists.txt
+# Build tests as an executable and reuse boltdbg_core object files.
-# Optionally enable sanitizers for test builds
-if(BOLTDBG_ENABLE_ASAN)
- add_compile_options(-fsanitize=address -fno-omit-frame-pointer)
- add_link_options(-fsanitize=address)
-endif()
+# Simple pattern: expect tests/*.cpp (you can change glob as needed)
+file(GLOB TEST_SOURCES CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
-# Collect test sources
-set(TEST_SOURCES
- test_main.cpp
- test_logger.cpp
-)
+if(NOT TEST_SOURCES)
+ message(STATUS "No test sources found in ${CMAKE_CURRENT_SOURCE_DIR}, skipping tests.")
+ return()
+endif()
+# Create tests executable (link object files from boltdbg_core so no separate lib is needed)
add_executable(boltdbg_tests ${TEST_SOURCES})
-target_include_directories(boltdbg_tests PRIVATE ${CMAKE_SOURCE_DIR}/include)
-target_link_libraries(boltdbg_tests PRIVATE libboltdbg)
-# If using CTest (already enabled from top-level)
+# Make sure boltdbg_core target exists (error early if not)
+
+
+# Link dependencies used by tests (gtest or other test frameworks). Example: if you use Threads and platform libs:
+if(TARGET spdlog::spdlog)
+ target_link_libraries(boltdbg_tests PRIVATE spdlog::spdlog)
+endif()
+if(TARGET imgui)
+ target_link_libraries(boltdbg_tests PRIVATE imgui)
+endif()
+if(TARGET glad)
+ target_link_libraries(boltdbg_tests PRIVATE glad)
+endif()
+if(DEFINED PLATFORM_LIBS AND PLATFORM_LIBS)
+ target_link_libraries(boltdbg_tests PRIVATE ${PLATFORM_LIBS})
+endif()
+if(TARGET Threads::Threads)
+ target_link_libraries(boltdbg_tests PRIVATE Threads::Threads)
+endif()
+
+# If you use a test framework (e.g. GoogleTest), link it here
+# find_package(GTest REQUIRED)
+# target_link_libraries(boltdbg_tests PRIVATE GTest::gtest_main)
+
+# Register test
+enable_testing()
add_test(NAME boltdbg_tests COMMAND boltdbg_tests)