diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..b1e961c --- /dev/null +++ b/.clang-format @@ -0,0 +1,31 @@ +--- +Language: Cpp +BasedOnStyle: LLVM +AlwaysBreakTemplateDeclarations: Yes +BreakBeforeBraces: Attach +ColumnLimit: 160 +SpaceAfterTemplateKeyword: true +Standard: c++20 +TabWidth: 4 +IndentWidth: 4 +UseTab: Always +AllowShortEnumsOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortBlocksOnASingleLine: Always +AllowShortIfStatementsOnASingleLine: Always +AllowShortLoopsOnASingleLine: true +IndentRequires: true +IncludeCategories: + # Headers in <> with .h extension. + - Regex: '<([A-Za-z0-9\/-_])+\.h>' + Priority: 10 + # Headers in <> with .hpp extension. + - Regex: '<([A-Za-z0-9\/-_])+\.hpp>' + Priority: 20 + # Headers in <> without extension. + - Regex: '<([A-Za-z0-9\/-_])+>' + Priority: 30 +PointerAlignment: Left +QualifierAlignment: Right diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..899c4b7 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,21 @@ +--- +Checks: 'clang-analyzer-*, + concurrency-*, + cppcoreguidelines-*, + -cppcoreguidelines-non-private-member-variables-in-classes, + -cppcoreguidelines-avoid-magic-numbers, + -cppcoreguidelines-avoid-const-or-ref-data-members, + misc-*, + -misc-non-private-member-variables-in-classes, + -misc-no-recursion, + modernize-*, + -modernize-use-trailing-return-type, + performance-*, + portability-*, + readability-*, + -readability-identifier-length, + -readability-implicit-bool-conversion, + -readability-magic-numbers, + -readability-redundant-member-init, + -readability-uppercase-literal-suffix' +... diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c8d67b8 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +[*] +insert_final_newline = true +charset = utf-8 +indent_size = 4 +indent_style = tab +# Optional: git will commit as lf, this will only affect local files +end_of_line = lf + +[*.{py,md,yml,sh,cmake,json}] +indent_style = space +indent_size = 2 + +[*.{py,md,yml,sh,cmake,json}.in] +indent_style = space +indent_size = 2 + +[CMakeLists.txt] +indent_style = space +indent_size = 2 diff --git a/.github/format_check_diff.sh b/.github/format_check_diff.sh new file mode 100755 index 0000000..151a74a --- /dev/null +++ b/.github/format_check_diff.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +[[ ! $(git --version) ]] && exit 1 + +output=$(git diff) + +if [[ "$output" != "" ]]; then + echo -e "One or more source files are not formatted!\n\n$output\n" + echo -e "Using $(clang-format --version)\n" + exit 1 +fi + +echo "All source files are formatted" +exit diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ad9ddc2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,105 @@ +name: ci-pr +on: [pull_request, workflow_dispatch] +jobs: + format-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: format code + run: scripts/format_code.sh + - name: check diff + run: .github/format_check_diff.sh + x64-linux-gcc: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: init + run: uname -m; sudo apt update -yqq && sudo apt install -yqq ninja-build mesa-common-dev libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules + - name: configure + run: cmake -S . --preset=ninja-gcc -B build -DKVF_USE_FREETYPE=OFF -DGLFW_BUILD_X11=OFF -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 + - name: build debug + run: cmake --build build --config=Debug -- -v + - name: build release + run: cmake --build build --config=Release -- -v + - name: test debug + run: cd build && ctest -V -C Debug + - name: test release + run: cd build && ctest -V -C Release + x64-linux-clang: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: init + run: uname -m; sudo apt update -yqq && sudo apt install -yqq ninja-build clang-19 mesa-common-dev libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules + - name: configure + run: cmake -S . --preset=ninja-clang -B build -DKVF_USE_FREETYPE=OFF -DGLFW_BUILD_X11=OFF -DCMAKE_C_COMPILER=clang-19 -DCMAKE_CXX_COMPILER=clang++-19 + - name: build debug + run: cmake --build build --config=Debug -- -v + - name: build release + run: cmake --build build --config=Release -- -v + - name: test debug + run: cd build && ctest -V -C Debug + - name: test release + run: cd build && ctest -V -C Release + arm64-linux-gcc: + runs-on: ubuntu-24.04-arm + steps: + - uses: actions/checkout@v4 + - name: init + run: uname -m; sudo apt update -yqq && sudo apt install -yqq ninja-build mesa-common-dev libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules + - name: configure + run: cmake -S . --preset=ninja-gcc -B build -DKVF_USE_FREETYPE=OFF -DGLFW_BUILD_X11=OFF -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 + - name: build debug + run: cmake --build build --config=Debug -- -v + - name: build release + run: cmake --build build --config=Release -- -v + - name: test debug + run: cd build && ctest -V -C Debug + - name: test release + run: cd build && ctest -V -C Release + arm64-linux-clang: + runs-on: ubuntu-24.04-arm + steps: + - uses: actions/checkout@v4 + - name: init + run: uname -m; sudo apt update -yqq && sudo apt install -yqq ninja-build clang-19 mesa-common-dev libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules + - name: configure + run: cmake -S . --preset=ninja-clang -B build -DKVF_USE_FREETYPE=OFF -DGLFW_BUILD_X11=OFF -DCMAKE_C_COMPILER=clang-19 -DCMAKE_CXX_COMPILER=clang++-19 + - name: build debug + run: cmake --build build --config=Debug -- -v + - name: build release + run: cmake --build build --config=Release -- -v + - name: test debug + run: cd build && ctest -V -C Debug + - name: test release + run: cd build && ctest -V -C Release + x64-windows-vs22: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - name: configure + run: cmake -S . --preset=vs22 -B build -DKVF_USE_FREETYPE=OFF + - name: build debug + run: cmake --build build --config=Debug --parallel + - name: build release + run: cmake --build build --config=Release --parallel + - name: test debug + run: cd build && ctest -V -C Debug + - name: test release + run: cd build && ctest -V -C Release + x64-windows-clang: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - name: init + run: choco install ninja + - name: configure + run: cmake -S . --preset=ninja-clang -B build -DKVF_USE_FREETYPE=OFF + - name: build debug + run: cmake --build build --config=Debug -- -v + - name: build release + run: cmake --build build --config=Release -- -v + - name: test debug + run: cd build && ctest -V -C Debug + - name: test release + run: cd build && ctest -V -C Release diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e41828b --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +**/.vs/* +**/.vscode/* +build/* +out/* +.cache +.DS_Store + +CMakeSettings.json +compile_commands.json +/CMakeUserPresets.json + +imgui.ini +*debug.log diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..84f33cb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.24) + +project(miracle VERSION 0.1.0) + +set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_DEBUG_POSTFIX "-d") + +add_subdirectory(ext) + +add_executable(${PROJECT_NAME}) + +target_link_libraries(${PROJECT_NAME} PRIVATE + le2d +) + +target_include_directories(${PROJECT_NAME} PRIVATE + src +) + +file(GLOB_RECURSE sources LIST_DIRECTORIES false "src/*.[hc]pp") +target_sources(${PROJECT_NAME} PRIVATE + ${sources} +) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..d8e0236 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,250 @@ +{ + "version": 5, + "cmakeMinimumRequired": { + "major": 3, + "minor": 24, + "patch": 0 + }, + "configurePresets": [ + { + "name": "default", + "displayName": "Default Config", + "description": "Base configuration using Ninja Multi-config", + "generator": "Ninja Multi-Config", + "binaryDir": "${sourceDir}/out/default", + "cacheVariables": { + "CMAKE_EXPORT_COMPILE_COMMANDS": "ON" + } + }, + { + "name": "base-gcc", + "hidden": true, + "inherits": "default", + "cacheVariables": { + "CMAKE_C_COMPILER": "gcc", + "CMAKE_CXX_COMPILER": "g++" + } + }, + { + "name": "base-clang", + "hidden": true, + "inherits": "default", + "cacheVariables": { + "CMAKE_C_COMPILER": "clang", + "CMAKE_CXX_COMPILER": "clang++" + } + }, + { + "name": "base-msvc", + "hidden": true, + "inherits": "default", + "cacheVariables": { + "CMAKE_C_COMPILER": "cl", + "CMAKE_CXX_COMPILER": "cl" + } + }, + { + "name": "ninja-gcc", + "displayName": "Ninja GCC", + "description": "Build configuration using Ninja Multi-config / GCC", + "inherits": "base-gcc", + "binaryDir": "${sourceDir}/out/gcc", + "cacheVariables": { + "CMAKE_CXX_FLAGS_INIT": "-Wall -Wextra -Wpedantic -Wconversion -Werror=return-type", + "CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT": "-Werror", + "CMAKE_CXX_FLAGS_RELEASE_INIT": "-Werror" + } + }, + { + "name": "ninja-clang", + "displayName": "Ninja Clang", + "description": "Build configuration using Ninja Multi-config / Clang", + "inherits": "base-clang", + "binaryDir": "${sourceDir}/out/clang", + "cacheVariables": { + "CMAKE_CXX_FLAGS_INIT": "-Wall -Wextra -Wpedantic -Wconversion -Werror=return-type", + "CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT": "-Werror", + "CMAKE_CXX_FLAGS_RELEASE_INIT": "-Werror" + } + }, + { + "name": "ninja-msvc", + "displayName": "Ninja MSVC", + "description": "Build configuration using Ninja Multi-config / MSVC", + "inherits": "base-msvc", + "binaryDir": "${sourceDir}/out/msvc", + "cacheVariables": { + "CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT": "/WX", + "CMAKE_CXX_FLAGS_RELEASE_INIT": "/WX" + } + }, + { + "name": "ninja-ubsan", + "displayName": "Ninja UBSan", + "description": "UBSan build configuration using Ninja Multi-config", + "inherits": "default", + "binaryDir": "${sourceDir}/out/ubsan", + "cacheVariables": { + "CMAKE_CXX_FLAGS_INIT": "-fsanitize=undefined -Wall -Wextra -Wpedantic -Wconversion -Werror=return-type" + } + }, + { + "name": "ninja-asan", + "displayName": "Ninja ASan", + "description": "ASan build configuration using Ninja Multi-config", + "inherits": "default", + "binaryDir": "${sourceDir}/out/asan", + "cacheVariables": { + "CMAKE_CXX_FLAGS_INIT": "-fsanitize=address -Wall -Wextra -Wpedantic -Wconversion -Werror=return-type" + } + }, + { + "name": "ninja-msvc-asan", + "displayName": "Ninja MSVC ASan", + "description": "ASan build configuration using Ninja Multi-config", + "inherits": "base-msvc", + "binaryDir": "${sourceDir}/out/asan", + "cacheVariables": { + "CMAKE_CXX_FLAGS_INIT": "-fsanitize=address" + } + }, + { + "name": "ninja-tsan", + "displayName": "Ninja TSan", + "description": "TSan build configuration using Ninja Multi-config", + "inherits": "default", + "binaryDir": "${sourceDir}/out/tsan", + "cacheVariables": { + "CMAKE_CXX_FLAGS_INIT": "-fsanitize=thread -Wall -Wextra -Wpedantic -Wconversion -Werror=return-type" + } + }, + { + "name": "vs22", + "displayName": "Visual Studio 2022", + "description": "Build configuration using Visual Studio 17 (2022)", + "generator": "Visual Studio 17 2022", + "binaryDir": "${sourceDir}/out/vs", + "cacheVariables": { + "CMAKE_CXX_FLAGS_INIT": "/WX" + }, + "architecture": { + "value": "x64", + "strategy": "external" + } + } + ], + "buildPresets": [ + { + "name": "Debug", + "configurePreset": "default", + "configuration": "Debug" + }, + { + "name": "Release", + "configurePreset": "default", + "configuration": "Release" + }, + { + "name": "RelWithDebInfo", + "configurePreset": "default", + "configuration": "RelWithDebInfo" + }, + { + "name": "GCC Debug", + "configurePreset": "ninja-gcc", + "configuration": "Debug" + }, + { + "name": "GCC RelWithDebInfo", + "configurePreset": "ninja-gcc", + "configuration": "RelWithDebInfo" + }, + { + "name": "Clang Debug", + "configurePreset": "ninja-clang", + "configuration": "Debug" + }, + { + "name": "Clang RelWithDebInfo", + "configurePreset": "ninja-clang", + "configuration": "RelWithDebInfo" + }, + { + "name": "MSVC Debug", + "configurePreset": "ninja-msvc", + "configuration": "Debug" + }, + { + "name": "MSVC Release", + "configurePreset": "ninja-msvc", + "configuration": "Release" + }, + { + "name": "UBSan Debug", + "configurePreset": "ninja-ubsan", + "configuration": "Debug" + } + ], + "testPresets": [ + { + "name": "Debug", + "configurePreset": "default", + "configuration": "Debug", + "inheritConfigureEnvironment": true + }, + { + "name": "Release", + "configurePreset": "default", + "configuration": "Release", + "inheritConfigureEnvironment": true + }, + { + "name": "RelWithDebInfo", + "configurePreset": "default", + "configuration": "RelWithDebInfo", + "inheritConfigureEnvironment": true + }, + { + "name": "GCC Debug", + "configurePreset": "ninja-gcc", + "configuration": "Debug", + "inheritConfigureEnvironment": true + }, + { + "name": "GCC RelWithDebInfo", + "configurePreset": "ninja-gcc", + "configuration": "RelWithDebInfo", + "inheritConfigureEnvironment": true + }, + { + "name": "Clang Debug", + "configurePreset": "ninja-clang", + "configuration": "Debug", + "inheritConfigureEnvironment": true + }, + { + "name": "Clang RelWithDebInfo", + "configurePreset": "ninja-clang", + "configuration": "RelWithDebInfo", + "inheritConfigureEnvironment": true + }, + { + "name": "MSVC Debug", + "configurePreset": "ninja-msvc", + "configuration": "Debug", + "inheritConfigureEnvironment": true + }, + { + "name": "MSVC Release", + "configurePreset": "ninja-msvc", + "configuration": "Release", + "inheritConfigureEnvironment": true + }, + { + "name": "UBSan Debug", + "configurePreset": "ninja-ubsan", + "configuration": "Debug", + "inheritConfigureEnvironment": true + } + ] +} \ No newline at end of file diff --git a/ext/.gitignore b/ext/.gitignore new file mode 100644 index 0000000..8eba6c8 --- /dev/null +++ b/ext/.gitignore @@ -0,0 +1 @@ +src/ diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt new file mode 100644 index 0000000..c9492ab --- /dev/null +++ b/ext/CMakeLists.txt @@ -0,0 +1,4 @@ +file(ARCHIVE_EXTRACT INPUT "${CMAKE_CURRENT_SOURCE_DIR}/src.zip" DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}") + +message(STATUS "[le2d]") +add_subdirectory(src/le2d) diff --git a/ext/src.zip b/ext/src.zip new file mode 100644 index 0000000..a88489d Binary files /dev/null and b/ext/src.zip differ diff --git a/scripts/format_code.sh b/scripts/format_code.sh new file mode 100755 index 0000000..d1deef2 --- /dev/null +++ b/scripts/format_code.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +[[ ! $(clang-format --version) ]] && exit 1 + +if [[ ! -d ./src ]]; then + echo "Please run script from the project root" + exit 1 +fi + +files=$(find src -name "*.?pp") + +if [[ "$files" == "" ]]; then + echo "-- No source files found" + exit +fi + +clang-format -i $files || exit 1 +echo -e "-- Formatted Files:\n$files\n" + +exit diff --git a/src/app.cpp b/src/app.cpp new file mode 100644 index 0000000..2c7b1c0 --- /dev/null +++ b/src/app.cpp @@ -0,0 +1,22 @@ +#include +#include + +namespace miracle { +namespace { +constexpr auto context_ci = le::Context::CreateInfo{ + .window = le::WindowInfo{.size = {1280, 720}, .title = "miracle"}, +}; +} // namespace + +App::App() : m_context(context_ci) {} + +void App::run() { + while (m_context.is_running()) { + m_context.next_frame(); + + ImGui::ShowDemoWindow(); + + m_context.present(); + } +} +} // namespace miracle diff --git a/src/app.hpp b/src/app.hpp new file mode 100644 index 0000000..ca472af --- /dev/null +++ b/src/app.hpp @@ -0,0 +1,14 @@ +#pragma once +#include + +namespace miracle { +class App { + public: + explicit App(); + + void run(); + + private: + le::Context m_context; +}; +} // namespace miracle diff --git a/src/log.hpp b/src/log.hpp new file mode 100644 index 0000000..9c8a954 --- /dev/null +++ b/src/log.hpp @@ -0,0 +1,6 @@ +#pragma once +#include + +namespace miracle { +inline auto const log = klib::TaggedLogger{"miracle"}; +} // namespace miracle diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..5214501 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,15 @@ +#include +#include + +auto main() -> int { + try { + auto app = miracle::App{}; + app.run(); + } catch (std::exception const& e) { + miracle::log.error("PANIC: {}", e.what()); + return EXIT_FAILURE; + } catch (...) { + miracle::log.error("PANIC: unknown exception"); + return EXIT_FAILURE; + } +}