diff options
| author | Levent Kaya <levent@dev> | 2025-11-06 01:53:21 +0300 |
|---|---|---|
| committer | Levent Kaya <levent@dev> | 2025-11-06 01:53:21 +0300 |
| commit | 2140653c001a2ac415fb717d48ca2b55ff2aa037 (patch) | |
| tree | 5dfc3697eee8aca4308aded02c95c2a32bccf509 | |
| parent | f6f40266ba57ab2df99b897c375f85f0a8a97856 (diff) | |
[feature] basic demo screen
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | CMakeLists.txt | 259 | ||||
| -rwxr-xr-x | build.sh | 427 | ||||
| -rw-r--r-- | cmake/compiler_warnings.cmake | 7 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 75 | ||||
| -rw-r--r-- | src/main.cpp | 114 | ||||
| -rw-r--r-- | tests/CMakeLists.txt | 49 |
7 files changed, 812 insertions, 121 deletions
@@ -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 "") @@ -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) |
