Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support C++ modules. #99

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ You can also build the sources on your own. Currently only MSVC builds under Win
In order for the project to be built, there are a few prerequisites that need to be present on your environment:

- [C++23 compatible compiler](https://en.cppreference.com/w/cpp/compiler_support/23): At the moment only MSVC fully supports the required features.
- [CMake](https://cmake.org/download/) (version 3.20 or higher). †
- [CMake](https://cmake.org/download/) (version 3.28 or higher). †
- Optional: [LunarG Vulkan SDK](https://vulkan.lunarg.com/) 1.3.204.1 or later (required to build the Vulkan backend).
- Optional: Custom [DXC](https://github.com/microsoft/DirectXShaderCompiler) build (required to build shaders for DirectX backend). ‡
- Optional: Windows 10 SDK 10.0.19041.0 or later (required to build DirectX backend).
- Optional: Windows 10 SDK 10.0.20348.0 or later (required to build DirectX backend).

† CMake 3.20 is part of Visual Studio 2019 version 16.10 and above. When using other compilers, CMake needs to be installed manually.
† CMake 3.28 is part of Visual Studio 2022 version 17.9 and above. When using other compilers, CMake needs to be installed manually.

‡ Note that the LunarG Vulkan SDK (1.3.204.1 and above) ships with a pre-built DXC binary, that supports DXIL and SPIR-V code generation and thus should be favored over the DXC binary shipped with the Windows SDK, which only supports DXIL.

Expand Down Expand Up @@ -116,7 +116,7 @@ You can customize the engine build, according to your specific needs. The most s
"version": 2,
"cmakeMinimumRequired": {
"major": 3,
"minor": 20,
"minor": 28,
"patch": 0
},
"configurePresets": [
Expand Down Expand Up @@ -150,7 +150,7 @@ For example, if you only want to build the Vulkan backend and samples and don't
"version": 2,
"cmakeMinimumRequired": {
"major": 3,
"minor": 20,
"minor": 28,
"patch": 0
},
"configurePresets": [
Expand Down
5 changes: 0 additions & 5 deletions src/AppModel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,6 @@ TARGET_LINK_LIBRARIES(${PROJECT_NAME}
PUBLIC LiteFX.Core LiteFX.Logging
)

# Re-use pre-compiled core header.
IF(BUILD_PRECOMPILED_HEADERS)
TARGET_PRECOMPILE_HEADERS(${PROJECT_NAME} REUSE_FROM LiteFX.Core)
ENDIF(BUILD_PRECOMPILED_HEADERS)

# Setup installer.
INSTALL(TARGETS ${PROJECT_NAME} EXPORT EXPORT LiteFX
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBRARY_DIR}
Expand Down
5 changes: 0 additions & 5 deletions src/Backends/DirectX12/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,6 @@ IF(DXIL_DLL)
INSTALL(FILES "${DXIL_DLL}" DESTINATION ${CMAKE_INSTALL_BINARY_DIR})
ENDIF(DXIL_DLL)

# Re-use pre-compiled core header.
IF(BUILD_PRECOMPILED_HEADERS)
TARGET_PRECOMPILE_HEADERS(${PROJECT_NAME} REUSE_FROM LiteFX.Core)
ENDIF(BUILD_PRECOMPILED_HEADERS)

# Setup installer.
INSTALL(TARGETS ${PROJECT_NAME} EXPORT EXPORT LiteFX
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBRARY_DIR}
Expand Down
10 changes: 2 additions & 8 deletions src/Backends/Vulkan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ MESSAGE(STATUS "Initializing: ${PROJECT_NAME}...")

# Resolve package dependencies.
FIND_PACKAGE(Vulkan REQUIRED)
FIND_PACKAGE(unofficial-vulkan-memory-allocator CONFIG REQUIRED)
FIND_PACKAGE(VulkanMemoryAllocator CONFIG REQUIRED)
FIND_PACKAGE(unofficial-spirv-reflect CONFIG REQUIRED)

# Collect header & source files.
Expand Down Expand Up @@ -85,7 +85,7 @@ TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME}
# Link project dependencies.
TARGET_LINK_LIBRARIES(${PROJECT_NAME}
PUBLIC LiteFX.Core LiteFX.Math LiteFX.Rendering LiteFX.AppModel Vulkan::Vulkan
PRIVATE unofficial::vulkan-memory-allocator::vulkan-memory-allocator unofficial::spirv-reflect::spirv-reflect
PRIVATE GPUOpen::VulkanMemoryAllocator unofficial::spirv-reflect::spirv-reflect
)

# Link against D3D12 to enable flip-model swap chains.
Expand All @@ -99,12 +99,6 @@ IF(BUILD_DIRECTX_12_BACKEND)
)
ENDIF(BUILD_DIRECTX_12_BACKEND)


# Re-use pre-compiled core header.
IF(BUILD_PRECOMPILED_HEADERS)
TARGET_PRECOMPILE_HEADERS(${PROJECT_NAME} REUSE_FROM LiteFX.Core)
ENDIF(BUILD_PRECOMPILED_HEADERS)

# Setup installer.
INSTALL(TARGETS ${PROJECT_NAME} EXPORT EXPORT LiteFX
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBRARY_DIR}
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
##### #####
###################################################################################################

CMAKE_MINIMUM_REQUIRED(VERSION 3.20)
CMAKE_MINIMUM_REQUIRED(VERSION 3.28)

# Check if the build dir does not match the source dir (disallow in-source builds).
IF("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
Expand Down
2 changes: 1 addition & 1 deletion src/CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"version": 2,
"cmakeMinimumRequired": {
"major": 3,
"minor": 20,
"minor": 28,
"patch": 0
},
"configurePresets": [
Expand Down
39 changes: 25 additions & 14 deletions src/Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,24 @@ CONFIGURE_FILE("core.tmpl" "${CMAKE_CURRENT_BINARY_DIR}/include/litefx/core.h")

# Collect header & source files.
SET(CORE_HEADERS
"include/litefx/containers.hpp"
"include/litefx/generator.hpp"
"include/litefx/string.hpp"
"include/litefx/traits.hpp"
"include/litefx/exceptions.hpp"
"include/litefx/litefx.h"
"include/litefx/common.h"
)

SET(CORE_SOURCES
"src/core.cpp"
"src/generator.hpp"
)

SET(CORE_MODULES
"modules/core.ixx"
"modules/alias.ixx"
"modules/string.ixx"
"modules/concepts.ixx"
"modules/exceptions.ixx"
"modules/enumerable.ixx"
"modules/pimpl.ixx"
"modules/builder.ixx"
"modules/resource.ixx"
)

ADD_LIBRARY(${PROJECT_NAME} SHARED
Expand All @@ -36,8 +44,14 @@ ADD_LIBRARY(${PROJECT_NAME} SHARED
"${CMAKE_CURRENT_BINARY_DIR}/include/litefx/core.h"
)

TARGET_SOURCES(${PROJECT_NAME}
PUBLIC
FILE_SET core_modules TYPE CXX_MODULES
FILES ${CORE_MODULES}
)

# Create source groups for better code organization.
SOURCE_GROUP(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${CORE_HEADERS} ${CORE_SOURCES})
SOURCE_GROUP(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${CORE_HEADERS} ${CORE_MODULES} ${CORE_SOURCES})

# Setup project properties. Relevant properties:
# - FOLDER: IDE folder (if supported).
Expand All @@ -52,7 +66,7 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES
DEFINE_SYMBOL ""
MAP_IMPORTED_CONFIG_RELWITHDEBINFO "Debug"
MAP_IMPORTED_CONFIG_MINSIZEREL "Release"
PUBLIC_HEADER "${CORE_HEADERS};${CMAKE_CURRENT_BINARY_DIR}/include/litefx/config.h;${CMAKE_CURRENT_BINARY_DIR}/include/litefx/version.h;${CMAKE_CURRENT_BINARY_DIR}/include/litefx/core.h"
PUBLIC_HEADER "${CMAKE_CURRENT_BINARY_DIR}/include/litefx/config.h;${CMAKE_CURRENT_BINARY_DIR}/include/litefx/version.h;${CMAKE_CURRENT_BINARY_DIR}/include/litefx/core.h"
)

TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME}
Expand All @@ -67,20 +81,17 @@ TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME}
# Link project dependencies.
TARGET_LINK_LIBRARIES(${PROJECT_NAME} PUBLIC fmt::fmt)

# Pre-compile core header.
IF(BUILD_PRECOMPILED_HEADERS)
TARGET_PRECOMPILE_HEADERS(${PROJECT_NAME} PRIVATE <litefx/core.h>)
ENDIF(BUILD_PRECOMPILED_HEADERS)

# Setup installer.
INSTALL(TARGETS ${PROJECT_NAME} EXPORT EXPORT LiteFX
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBRARY_DIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBRARY_DIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINARY_DIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDE_DIR}/litefx/
FILE_SET core_modules DESTINATION ${CMAKE_INSTALL_MODULE_DIR}
CXX_MODULES_BMI DESTINATION ${CMAKE_INSTALL_LIBRARY_DIR}/modules
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDE_DIR}
)

# Export config.
INSTALL(EXPORT LiteFX DESTINATION ${CMAKE_INSTALL_EXPORT_DIR})
INSTALL(EXPORT LiteFX DESTINATION ${CMAKE_INSTALL_EXPORT_DIR} CXX_MODULES_DIRECTORY ${CMAKE_INSTALL_EXPORT_DIR}/modules)
EXPORT(TARGETS ${PROJECT_NAME} FILE LiteFXCoreConfig.cmake)
3 changes: 1 addition & 2 deletions src/Core/core.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@
# include <Windows.h>
#endif

#include <litefx/containers.hpp>
#include <litefx/traits.hpp>
#include <litefx/common.h>
2 changes: 1 addition & 1 deletion src/Core/include/litefx/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
*.h
!containers.h
!common.h
!litefx.h
44 changes: 44 additions & 0 deletions src/Core/include/litefx/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#pragma once

#ifndef DEFINE_EXCEPTION
# define DEFINE_EXCEPTION(name, base) \
class name : public ExceptionBase<base, name> { \
public: \
using ExceptionBase<base, name>::ExceptionBase; \
}
#endif // DEFINE_EXCEPTION

#ifndef LITEFX_BUILDER
# define LITEFX_BUILDER(BuilderType) \
public: \
using builder_type = BuilderType; \
friend class BuilderType;
#endif // LITEFX_BUILDER

#ifndef LITEFX_DEFINE_FLAGS
# define LITEFX_DEFINE_FLAGS(T) \
inline T operator| (const T lhs, const T rhs) { using _base_t = std::underlying_type_t<T>; return static_cast<T>(static_cast<_base_t>(lhs) | static_cast<_base_t>(rhs)); } \
inline T& operator|= (T& lhs, const T& rhs) { lhs = lhs | rhs; return lhs; } \
inline T operator& (const T lhs, const T rhs) { using _base_t = std::underlying_type_t<T>; return static_cast<T>(static_cast<_base_t>(lhs) & static_cast<_base_t>(rhs)); } \
inline T& operator&= (T& lhs, const T& rhs) { lhs = lhs & rhs; return lhs; }
#endif // LITEFX_DEFINE_FLAGS

#ifndef LITEFX_FLAG_IS_SET
# define LITEFX_FLAG_IS_SET(val, flag) \
static_cast<bool>((std::to_underlying(val) & std::to_underlying(flag)) == std::to_underlying(flag))
#endif // LITEFX_FLAG_IS_SET

/// <summary>
/// Declares the implementation for the public interface of a class.
/// </summary>
/// <remarks>
/// A class can access the instance of the implementation instance using the pointer `m_impl` after declaring the implementation
/// using this macro.
/// </remarks>
/// <seealso cref="Implement" />
#ifndef LITEFX_IMPLEMENTATION
# define LITEFX_IMPLEMENTATION(impl) \
private: \
class impl; \
PimplPtr<impl> m_impl;
#endif // LITEFX_IMPLEMENTATION
Loading