diff --git a/.drone.yml b/.drone.yml index 47b08fa..36a95bb 100644 --- a/.drone.yml +++ b/.drone.yml @@ -2,121 +2,12 @@ kind: pipeline type: docker name: linux_amd64 -environment: - CONAN_REVISIONS_ENABLED: "1" - platform: os: linux arch: amd64 -volumes: -- name: dockersock - host: - path: /var/run/docker.sock - -- name: py - temp: {} - -- name: conan - host: - path: /root/.conan2/ - - -services: - - name: docker - image: docker:dind - privileged: true - volumes: - - name: dockersock - path: /var/run/ - steps: - - name: build image - image: docker:latest - volumes: - - name: dockersock - path: /var/run/docker.sock - commands: - - until docker info; do echo "Waiting for Docker daemon..."; sleep 1; done - - docker build -t ubuntu_amd64 -f ./tools/docker/linux_amd64 . - - docker images - - - name: environment info - image: ubuntu_amd64:latest + - name: clang format + image: alpine_amd64__clang_format pull: if-not-exists - volumes: - - name: py - path: /opt/venv/ - - commands: - - . /opt/venv/bin/activate - - whoami - - uname -a - - pip --version - - python3 --version - - conan --version - - cmake --version - - gcc --version - - g++ --version - - clang --version - - clang++ --version - - clang-tidy --version - - - name: build gcc - image: ubuntu_amd64:latest - pull: if-not-exists - volumes: - - name: py - path: /opt/venv/ - - name: conan - path: /root/.conan2 - - commands: - - . /opt/venv/bin/activate - - rm -rvf ./build - - export CC=$(which gcc) - - export CXX=$(which g++) - - - conan install . --build=missing --profile:build="$(pwd)/tools/conan/profiles/linux_gcc_amd64" --profile:host="$(pwd)/tools/conan/profiles/linux_gcc_amd64" - - conan build . --profile:build="$(pwd)/tools/conan/profiles/linux_gcc_amd64" --profile:host="$(pwd)/tools/conan/profiles/linux_gcc_amd64" - - - ./build/Release/modules/light/light - - - name: build clang - image: ubuntu_amd64:latest - pull: if-not-exists - volumes: - - name: py - path: /opt/venv/ - - name: conan - path: /root/.conan2 - - commands: - - . /opt/venv/bin/activate - - rm -rvf ./build - - export CC=$(which clang) - - export CXX=$(which clang++) - - - conan install . --build=missing --profile:build="$(pwd)/tools/conan/profiles/linux_clang_amd64" --profile:host="$(pwd)/tools/conan/profiles/linux_clang_amd64" - - conan build . --profile:build="$(pwd)/tools/conan/profiles/linux_clang_amd64" --profile:host="$(pwd)/tools/conan/profiles/linux_clang_amd64" - - - ./build/Release/modules/light/light - - - name: static analysis - image: ubuntu_amd64:latest - pull: if-not-exists - commands: - - echo "[TODO] Implement static analysis" - - - name: run tests - image: ubuntu_amd64:latest - pull: if-not-exists - commands: - - echo "[TODO] Implement tests" - - ./build/Release/modules/light/light - - - name: report coverage - image: ubuntu_amd64:latest - pull: if-not-exists - commands: - - echo "[TODO] Implement coverage report" + commands: $(git rev-parse --show-toplevel)/tools/ci/alpine_amd64/script.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index f1f2028..5bf29bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,9 @@ cmake_minimum_required(VERSION 3.16 FATAL_ERROR) project("light" LANGUAGES CXX) include(tools/cmake/preliminary.cmake) +include(tools/cmake/module_macros.cmake) -set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD 26) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_option(ENABLE_SANITIZERS "Enables fsan sanitizers") diff --git a/CMakeUserPresets.json b/CMakeUserPresets.json new file mode 100644 index 0000000..32e012f --- /dev/null +++ b/CMakeUserPresets.json @@ -0,0 +1,9 @@ +{ + "version": 4, + "vendor": { + "conan": {} + }, + "include": [ + "build/Debug/generators/CMakePresets.json" + ] +} \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 2ce0b43..1615b91 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,3 +1,4 @@ .. toctree:: ./architecture.rst + ./philosophy.rst diff --git a/docs/philosophy.rst b/docs/philosophy.rst new file mode 100644 index 0000000..3aef06f --- /dev/null +++ b/docs/philosophy.rst @@ -0,0 +1,6 @@ +Philosophy +========================= + + +Code is documentation +------------------------ diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index a0025dd..32e8ee6 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -1,2 +1,3 @@ -add_subdirectory(utilities/preliminary) -add_subdirectory(light) +add_subdirectory(pch) + +add_subdirectory(engine) diff --git a/modules/ecs/private/sparse_set.hpp b/modules/ecs/private/sparse_set.hpp new file mode 100644 index 0000000..da57c56 --- /dev/null +++ b/modules/ecs/private/sparse_set.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace lt::ecs { + + +} diff --git a/modules/engine/CMakeLists.txt b/modules/engine/CMakeLists.txt new file mode 100644 index 0000000..583ef13 --- /dev/null +++ b/modules/engine/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(engine ${CMAKE_CURRENT_SOURCE_DIR}/private/entrypoint.cpp) +target_link_libraries(engine PRIVATE pch) diff --git a/modules/engine/private/entrypoint.cpp b/modules/engine/private/entrypoint.cpp new file mode 100644 index 0000000..21bc165 --- /dev/null +++ b/modules/engine/private/entrypoint.cpp @@ -0,0 +1,17 @@ +auto main() -> int32_t +try +{ + std::cout << "Light built and ran fine..."; + + return 0; +} +catch (const std::exception &exp) +{ + std::cout << "\n\nUnhandled std exception: " << exp.what() << std::endl; // NOLINT + return -1; +} +catch (...) +{ + std::cout << "\n\nUnhandled exception" << std::endl; // NOLINT + return -1; +} diff --git a/modules/light/CMakeLists.txt b/modules/light/CMakeLists.txt deleted file mode 100644 index 75d113c..0000000 --- a/modules/light/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_executable(light ${CMAKE_CURRENT_SOURCE_DIR}/src/entrypoint.cpp) - -target_link_libraries(light PRIVATE preliminary) diff --git a/modules/light/src/entrypoint.cpp b/modules/light/src/entrypoint.cpp deleted file mode 100644 index dd06efd..0000000 --- a/modules/light/src/entrypoint.cpp +++ /dev/null @@ -1,6 +0,0 @@ -auto main() -> lt::i32 -{ - std::cout << "Light built and ran fine..."; - - return 0; -} diff --git a/modules/pch/CMakeLists.txt b/modules/pch/CMakeLists.txt new file mode 100644 index 0000000..cf130c1 --- /dev/null +++ b/modules/pch/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library_module(universal_pch) +target_precompile_headers(universal_pch INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/public/pch/pch.hpp) diff --git a/modules/pch/public/pch/error_handling/checks.hpp b/modules/pch/public/pch/error_handling/checks.hpp new file mode 100644 index 0000000..6147626 --- /dev/null +++ b/modules/pch/public/pch/error_handling/checks.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include +#include + +namespace lt { + +namespace details { + +inline void throw_if_false(bool condition, std::source_location location) +{ + if (!condition) + { + throw Error { "Failed runtime assertion", location }; + } +} + +} // namespace details + +/** Throws lt::Error if \a condition is false, otherwise returns without side-effects. + * + * @throws lt::Error + * + * @note Only runs when LIGHT_ENABLE_CHECK is enabled, which is enabled by default on debug builds. + * + * @warn The successful execution of the contract of the using code should NOT depend on the + * execution of this function as it may or may NOT be executed--based on project configuration. + */ +inline void check(bool condition, std::source_location location = std::source_location::current()) +{ + if constexpr (light_enabled_check) + { + details::throw_if_false(condition, location); + } +} + +/** Throws lt::Error if \a condition is false, otherwise returns without side-effects. + * + * @throws lt::Error + * + * @note Only runs when LIGHT_ENABLE_ENSURE is enabled, which is enabled by default on debug and + * release builds. + * + * @warn The successful execution of the contract of the using code should NOT depend on the + * execution of this function as it may or may NOT be executed--based on project configuration. + */ +inline void ensure(bool condition, std::source_location location = std::source_location::current()) +{ + if constexpr (light_enabled_ensure) + { + details::throw_if_false(condition, location); + } +} + +} // namespace lt diff --git a/modules/pch/public/pch/error_handling/types.hpp b/modules/pch/public/pch/error_handling/types.hpp new file mode 100644 index 0000000..158e642 --- /dev/null +++ b/modules/pch/public/pch/error_handling/types.hpp @@ -0,0 +1,32 @@ +#pragma once + +namespace lt { + +class Error: public std::exception +{ +public: + Error(std::string_view reason, std::source_location location): m_reason(reason) + { + std::ignore = location; + } + + Error(const Error &prev, std::string_view reason, std::source_location location) + : m_reason(reason) + { + std::ignore = location; + std::ignore = prev; + } + + [[nodiscard]] auto what() const noexcept -> const char * override + { + return ""; + } + +private: + std::string m_reason; +}; + +template +using Expected = std::expected; + +} // namespace lt diff --git a/modules/pch/public/pch/module_configs.hpp b/modules/pch/public/pch/module_configs.hpp new file mode 100644 index 0000000..a10766a --- /dev/null +++ b/modules/pch/public/pch/module_configs.hpp @@ -0,0 +1,15 @@ +namespace lt { + +#ifdef LIGHT_ENABLE_CHECK +constexpr bool light_enabled_check = true; +#else +constexpr bool light_enabled_check = false; +#endif + +#ifdef LIGHT_ENABLE_ENSURE +constexpr bool light_enabled_ensure = true; +#else +constexpr bool light_enabled_ensure = false; +#endif + +} // namespace lt diff --git a/modules/pch/public/pch/pch.hpp b/modules/pch/public/pch/pch.hpp new file mode 100644 index 0000000..2f8a0dc --- /dev/null +++ b/modules/pch/public/pch/pch.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include + +/* error_handling */ +#include +#include diff --git a/modules/utilities/preliminary/src/pch.hpp b/modules/pch/public/pch/std_headers.hpp similarity index 93% rename from modules/utilities/preliminary/src/pch.hpp rename to modules/pch/public/pch/std_headers.hpp index 4145db8..ee52730 100644 --- a/modules/utilities/preliminary/src/pch.hpp +++ b/modules/pch/public/pch/std_headers.hpp @@ -1,6 +1,4 @@ -#pragma once - -#include +// NOLINTBEGIN /* utilities */ #include @@ -10,6 +8,8 @@ #include #include #include +#include +#include #include #include #include @@ -64,3 +64,5 @@ /* filesystem */ #include + +// NOLINTEND diff --git a/modules/light/.gitkeep b/modules/renderer/CMakeLists.txt similarity index 100% rename from modules/light/.gitkeep rename to modules/renderer/CMakeLists.txt diff --git a/modules/renderer/private/impls/vulkan/context.hpp b/modules/renderer/private/impls/vulkan/context.hpp new file mode 100644 index 0000000..2a747b4 --- /dev/null +++ b/modules/renderer/private/impls/vulkan/context.hpp @@ -0,0 +1,7 @@ +namespace lt::render::vk { + +struct Context +{ +}; + +} // namespace lt::render::vk diff --git a/modules/utilities/preliminary/CMakeLists.txt b/modules/utilities/preliminary/CMakeLists.txt deleted file mode 100644 index 680a173..0000000 --- a/modules/utilities/preliminary/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_library(preliminary INTERFACE) -target_precompile_headers(preliminary INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src/pch.hpp) -target_include_directories(preliminary INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include/) diff --git a/modules/utilities/preliminary/include/preliminary/types.hpp b/modules/utilities/preliminary/include/preliminary/types.hpp deleted file mode 100644 index d104ec7..0000000 --- a/modules/utilities/preliminary/include/preliminary/types.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -#include - -namespace lt { - -using i8 = int8_t; -using i16 = int16_t; -using i32 = int32_t; -using i64 = int64_t; - -using u8 = uint8_t; -using u16 = uint16_t; -using u32 = uint32_t; -using u64 = uint64_t; - -template -using vec = std::vector; - -} // namespace lt diff --git a/tools/ci/alpine_amd64/clang_format/Dockerfile b/tools/ci/alpine_amd64/clang_format/Dockerfile new file mode 100644 index 0000000..08de23e --- /dev/null +++ b/tools/ci/alpine_amd64/clang_format/Dockerfile @@ -0,0 +1,4 @@ +FROM alpine:latest + +RUN apk add --no-cache \ + clang-extra-tools diff --git a/tools/ci/alpine_amd64/clang_format/profile_build b/tools/ci/alpine_amd64/clang_format/profile_build new file mode 100644 index 0000000..e69de29 diff --git a/tools/ci/alpine_amd64/clang_format/profile_host b/tools/ci/alpine_amd64/clang_format/profile_host new file mode 100644 index 0000000..e69de29 diff --git a/tools/ci/alpine_amd64/clang_format/script.sh b/tools/ci/alpine_amd64/clang_format/script.sh new file mode 100755 index 0000000..fc209f3 --- /dev/null +++ b/tools/ci/alpine_amd64/clang_format/script.sh @@ -0,0 +1,13 @@ +set -e +cd $(git rev-parse --show-toplevel) + +find ./modules -name '*.?pp' | while read -r file; do +echo "Checking format for $file" +if ! clang-format --dry-run --Werror "$file"; then + echo "❌ Formatting issue detected in $file" + exit 1 +fi +done + +echo "✅ All files are properly formatted" +exit 0 diff --git a/tools/ci/alpine_amd64/install_images.sh b/tools/ci/alpine_amd64/install_images.sh new file mode 100755 index 0000000..6e5b90c --- /dev/null +++ b/tools/ci/alpine_amd64/install_images.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +ALPINE_AMD64=$(git rev-parse --show-toplevel)/tools/ci/alpine_amd64/ + +cd ${ALPINE_AMD64}/clang_format/ +docker build -t alpine_amd64__clang_format diff --git a/tools/cmake/module_macros.cmake b/tools/cmake/module_macros.cmake new file mode 100644 index 0000000..2c446c0 --- /dev/null +++ b/tools/cmake/module_macros.cmake @@ -0,0 +1,34 @@ +macro (add_library_module libname) + if ("${ARGN}" STREQUAL "") # Header only library + message("Adding INTERFACE library ${libname}") + add_library(${libname} INTERFACE) + target_include_directories(${libname} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/public) + + # Do not link universal_pch against universal_pch :D + if (NOT ${libname} STREQUAL "universal_pch") + target_link_libraries(${libname} INTERFACE universal_pch) + endif () + + else () # Compiled library + set(source_files) + set(source_directory "${CMAKE_CURRENT_SOURCE_DIR}/private") + foreach (source_file ${ARGN}) + list(APPEND source_files "${source_directory}/${source_file}") + endforeach () + + message("Adding library ${libname} with source files: ${source_files}") + add_library(${libname} ${source_files}) + target_include_directories(${libname} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/public) + target_include_directories(${libname} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/private) + target_compile_options(${libname} PRIVATE ${WARNING_FLAGS}) + + # Do not link universal_pch against universal_pch :D + if (NOT ${libname} STREQUAL "universal_pch") + target_link_libraries(${libname} PUBLIC universal_pch) + endif () + endif () + + if (ENABLE_STATIC_ANALYSIS) + set_target_properties(${libname} PROPERTIES CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}") + endif () +endmacro () diff --git a/tools/docker/linux_amd64 b/tools/docker/linux_amd64 deleted file mode 100644 index a4c04a1..0000000 --- a/tools/docker/linux_amd64 +++ /dev/null @@ -1,16 +0,0 @@ -FROM ubuntu:latest - -RUN apt update -RUN apt-get install -y \ - build-essential \ - cmake \ - clang \ - clang-tidy \ - gcc \ - g++ \ - python3 \ - python3-pip \ - python3.12-venv - -RUN python3 -m venv /opt/venv -RUN . /opt/venv/bin/activate && pip install conan==2.5.0