Compare commits

...

13 commits

Author SHA1 Message Date
6aa03cc05b squash wip
Some checks reported errors
continuous-integration/drone/pr Build was killed
2025-10-16 14:45:35 +03:30
ec5483d13f refactor(ci): fix shellcheck analysis
Some checks reported errors
continuous-integration/drone/push Build was killed
2025-10-16 14:42:23 +03:30
598e1b232d ci: add shell check 2025-10-16 14:41:33 +03:30
3f5a85197a style: format tools/cmake files 2025-10-16 14:41:33 +03:30
479a15bfd0 style: format shell scripts 2025-10-16 14:41:30 +03:30
30548ea4db ci: add shell_format check 2025-10-16 14:40:11 +03:30
9de1bc7ba7 chore: remove test.sh 2025-10-16 14:40:11 +03:30
4b5d380a0e style: apply cmake-format to all cmake files 2025-10-16 14:40:11 +03:30
2612a19f3c ci: add cmake_format check 2025-10-16 14:40:11 +03:30
bd8a111607 refactor: fix some static analysis errors 2025-10-16 14:40:11 +03:30
3066153d6c refactor: fix some static analyzer errors 2025-10-16 14:40:11 +03:30
d5dc37d081 chore: remove build_ci_images.sh 2025-10-16 14:40:11 +03:30
b393cbb31c ci(amd64/gcc/valgrind): fix valgrind errors (#58)
Some checks reported errors
continuous-integration/drone/push Build was killed
Reviewed-on: #58
Co-authored-by: light7734 <light7734@tuta.io>
Co-committed-by: light7734 <light7734@tuta.io>
2025-10-09 15:51:01 +00:00
48 changed files with 996 additions and 643 deletions

View file

@ -31,7 +31,7 @@ steps:
- ./tools/ci/amd64/gcc/unit_tests.sh - ./tools/ci/amd64/gcc/unit_tests.sh
- name: valgrind - name: valgrind
image: ci:latest image: ci:latest
pull: if-not-exists pull: if-not-exists
commands: commands:
- ./tools/ci/amd64/gcc/valgrind.sh - ./tools/ci/amd64/gcc/valgrind.sh
@ -55,7 +55,7 @@ steps:
- ./tools/ci/amd64/clang/coverage.sh - ./tools/ci/amd64/clang/coverage.sh
- name: leak sanitizer - name: leak sanitizer
image: ci:latest image: ci:latest
pull: if-not-exists pull: if-not-exists
commands: commands:
- ./tools/ci/amd64/clang/lsan.sh - ./tools/ci/amd64/clang/lsan.sh
@ -76,18 +76,36 @@ trigger:
steps: steps:
- name: clang tidy - name: clang tidy
image: ci:latest image: ci:latest
pull: if-not-exists pull: if-not-exists
privileged: true privileged: true
commands: commands:
- ./tools/ci/static_analysis/clang_tidy.sh - ./tools/ci/static_analysis/clang_tidy.sh
- name: shell check
image: ci:latest
pull: if-not-exists
commands:
- ./tools/ci/static_analysis/shell_check.sh
- name: clang format - name: clang format
image: ci:latest image: ci:latest
pull: if-not-exists pull: if-not-exists
commands: commands:
- ./tools/ci/static_analysis/clang_format.sh - ./tools/ci/static_analysis/clang_format.sh
- name: cmake format
image: ci:latest
pull: if-not-exists
commands:
- ./tools/ci/static_analysis/cmake_format.sh
- name: shell format
image: ci:latest
pull: if-not-exists
commands:
- ./tools/ci/static_analysis/shell_format.sh
--- ---
kind: pipeline kind: pipeline
type: docker type: docker
@ -137,3 +155,4 @@ steps:
- rm -rf /light_docs/* - rm -rf /light_docs/*
- mv ./html/* /light_docs/ - mv ./html/* /light_docs/

View file

@ -7,20 +7,20 @@ add_subdirectory(./time)
add_subdirectory(./logger) add_subdirectory(./logger)
add_subdirectory(./debug) add_subdirectory(./debug)
add_subdirectory(./math) add_subdirectory(./math)
# #
add_subdirectory(./asset_baker) add_subdirectory(./asset_baker)
add_subdirectory(./assets) add_subdirectory(./assets)
# #
add_subdirectory(./camera) add_subdirectory(./camera)
add_subdirectory(./input) add_subdirectory(./input)
# add_subdirectory(./ui) # add_subdirectory(./ui)
# #
add_subdirectory(./surface) add_subdirectory(./surface)
add_subdirectory(./renderer) add_subdirectory(./renderer)
add_subdirectory(./ecs) add_subdirectory(./ecs)
# #
add_subdirectory(./app) add_subdirectory(./app)
# apps # apps
add_subdirectory(./mirror) add_subdirectory(./mirror)
add_subdirectory(test) add_subdirectory(test)

View file

@ -1,2 +1,5 @@
add_library_module(app application.cpp) add_library_module(app application.cpp)
target_link_libraries(app PUBLIC memory PRIVATE lt_debug) target_link_libraries(
app
PUBLIC memory
PRIVATE lt_debug)

View file

@ -1,18 +1,6 @@
add_library_module(libasset_baker add_library_module(libasset_baker bakers.cpp)
bakers.cpp target_link_libraries(libasset_baker PUBLIC assets logger lt_debug tbb)
) add_test_module(libasset_baker bakers.test.cpp)
target_link_libraries(libasset_baker
PUBLIC
assets
logger
lt_debug
tbb
)
add_test_module(libasset_baker
bakers.test.cpp
)
add_executable_module(asset_baker add_executable_module(asset_baker entrypoint/baker.cpp)
entrypoint/baker.cpp
)
target_link_libraries(asset_baker PRIVATE libasset_baker) target_link_libraries(asset_baker PRIVATE libasset_baker)

View file

@ -1,7 +1,2 @@
#include <asset_baker/bakers.hpp> #include <asset_baker/bakers.hpp>
#include <test/test.hpp> #include <test/test.hpp>
using ::lt::test::Case;
using ::lt::test::Suite;
// TODO(Light): add asset baking tests!

View file

@ -1,14 +1,5 @@
add_library_module(assets add_library_module(assets shader.cpp)
shader.cpp
)
target_link_libraries( target_link_libraries(assets PUBLIC logger lt_debug)
assets
PUBLIC
logger
lt_debug
)
add_test_module(assets add_test_module(assets shader.test.cpp)
shader.test.cpp
)

View file

@ -2,18 +2,25 @@
namespace lt::assets { namespace lt::assets {
constexpr auto total_metadata_size = //
sizeof(AssetMetadata::type) //
+ sizeof(AssetMetadata::version) //
+ sizeof(ShaderAsset::Metadata::type) //
+ sizeof(BlobMetadata::tag) //
+ sizeof(BlobMetadata::offset) //
+ sizeof(BlobMetadata::compression_type) //
+ sizeof(BlobMetadata::compressed_size) //
+ sizeof(BlobMetadata::uncompressed_size);
ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path) ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path)
{ {
constexpr auto total_metadata_size = //
sizeof(AssetMetadata) //
+ sizeof(Metadata) //
+ sizeof(BlobMetadata);
ensure(m_stream.is_open(), "Failed to open shader asset at: {}", path.string()); ensure(m_stream.is_open(), "Failed to open shader asset at: {}", path.string());
const auto read = [this](auto &field) {
m_stream.read(std::bit_cast<char *>(&field), sizeof(field));
};
m_stream.seekg(0, std::ifstream::end); m_stream.seekg(0, std::ifstream::end);
const auto file_size = static_cast<size_t>(m_stream.tellg()); const auto file_size = static_cast<size_t>(m_stream.tellg());
ensure( ensure(
file_size > total_metadata_size, file_size > total_metadata_size,
"Failed to open shader asset at: {}, file smaller than metadata: {} < {}", "Failed to open shader asset at: {}, file smaller than metadata: {} < {}",
@ -22,12 +29,15 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path)
file_size file_size
); );
// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
m_stream.seekg(0, std::ifstream::beg); m_stream.seekg(0, std::ifstream::beg);
m_stream.read((char *)&m_asset_metadata, sizeof(m_asset_metadata)); read(m_asset_metadata.type);
m_stream.read((char *)&m_metadata, sizeof(m_metadata)); read(m_asset_metadata.version);
m_stream.read((char *)&m_code_blob_metadata, sizeof(m_code_blob_metadata)); read(m_metadata.type);
// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast) read(m_code_blob_metadata.tag);
read(m_code_blob_metadata.offset);
read(m_code_blob_metadata.compression_type);
read(m_code_blob_metadata.compressed_size);
read(m_code_blob_metadata.uncompressed_size);
ensure( ensure(
m_asset_metadata.type == asset_type_identifier, m_asset_metadata.type == asset_type_identifier,
@ -69,4 +79,70 @@ ShaderAsset::ShaderAsset(const std::filesystem::path &path): m_stream(path)
); );
} }
/* static */ void ShaderAsset::pack(
const std::filesystem::path &destination,
AssetMetadata asset_metadata,
Metadata metadata,
Blob code_blob
)
{
auto stream = std::ofstream {
destination,
std::ios::binary | std::ios::trunc,
};
const auto code_blob_metadata = BlobMetadata {
.tag = std::to_underlying(BlobTag::code),
.offset = total_metadata_size,
.compression_type = CompressionType::none,
.compressed_size = code_blob.size(),
.uncompressed_size = code_blob.size(),
};
ensure(stream.is_open(), "Failed to pack shader asset to {}", destination.string());
const auto write = [&stream](auto &field) {
stream.write(std::bit_cast<char *>(&field), sizeof(field));
};
write(asset_metadata.type);
write(asset_metadata.version);
write(metadata.type);
write(code_blob_metadata.tag);
write(code_blob_metadata.offset);
write(code_blob_metadata.compression_type);
write(code_blob_metadata.compressed_size);
write(code_blob_metadata.uncompressed_size);
stream.write(std::bit_cast<char *>(code_blob.data()), static_cast<long long>(code_blob.size()));
}
void ShaderAsset::unpack_to(BlobTag tag, std::span<std::byte> destination) const
{
ensure(tag == BlobTag::code, "Invalid blob tag for shader asset: {}", std::to_underlying(tag));
ensure(
destination.size() >= m_code_blob_metadata.uncompressed_size,
"Failed to unpack shader blob {} to destination ({}) of size {} since it's smaller "
"than the blobl's uncompressed size: {}",
std::to_underlying(tag),
std::bit_cast<size_t>(destination.data()),
destination.size(),
m_code_blob_metadata.uncompressed_size
);
m_stream.seekg(static_cast<long long>(m_code_blob_metadata.offset));
m_stream.read(
std::bit_cast<char *>(destination.data()),
static_cast<long long>(m_code_blob_metadata.uncompressed_size)
);
}
[[nodiscard]] auto ShaderAsset::unpack(BlobTag tag) const -> Blob
{
ensure(tag == BlobTag::code, "Invalid blob tag for shader asset: {}", std::to_underlying(tag));
auto blob = Blob(m_code_blob_metadata.uncompressed_size);
unpack_to(tag, blob);
return blob;
}
} // namespace lt::assets } // namespace lt::assets

View file

@ -40,10 +40,15 @@ Suite packing = "shader_pack"_suite = [] {
dummy_blob.emplace_back(static_cast<std::byte>(idx)); dummy_blob.emplace_back(static_cast<std::byte>(idx));
} }
const auto expected_size = // const auto expected_size = //
sizeof(AssetMetadata) // sizeof(AssetMetadata::type) //
+ sizeof(ShaderAsset::Metadata) // + sizeof(AssetMetadata::version) //
+ sizeof(BlobMetadata) // + sizeof(ShaderAsset::Metadata::type) //
+ sizeof(BlobMetadata::tag) //
+ sizeof(BlobMetadata::offset) //
+ sizeof(BlobMetadata::compression_type) //
+ sizeof(BlobMetadata::compressed_size) //
+ sizeof(BlobMetadata::uncompressed_size) //
+ dummy_blob.size(); + dummy_blob.size();
ShaderAsset::pack( ShaderAsset::pack(

View file

@ -32,33 +32,14 @@ public:
AssetMetadata asset_metadata, AssetMetadata asset_metadata,
Metadata metadata, Metadata metadata,
Blob code_blob Blob code_blob
) );
{
auto stream = std::ofstream {
destination,
std::ios::binary | std::ios::trunc,
};
ensure(stream.is_open(), "Failed to pack shader asset to {}", destination.string());
// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
stream.write((char *)&asset_metadata, sizeof(asset_metadata));
stream.write((char *)&metadata, sizeof(metadata));
auto code_blob_metadata = BlobMetadata {
.tag = std::to_underlying(BlobTag::code),
.offset = static_cast<size_t>(stream.tellp()) + sizeof(BlobMetadata),
.compression_type = CompressionType::none,
.compressed_size = code_blob.size(),
.uncompressed_size = code_blob.size(),
};
stream.write((char *)&code_blob_metadata, sizeof(BlobMetadata));
stream.write((char *)code_blob.data(), static_cast<long long>(code_blob.size()));
// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
}
ShaderAsset(const std::filesystem::path &path); ShaderAsset(const std::filesystem::path &path);
void unpack_to(BlobTag tag, std::span<std::byte> destination) const;
[[nodiscard]] auto unpack(BlobTag tag) const -> Blob;
[[nodiscard]] auto get_asset_metadata() const -> const AssetMetadata & [[nodiscard]] auto get_asset_metadata() const -> const AssetMetadata &
{ {
return m_asset_metadata; return m_asset_metadata;
@ -80,45 +61,6 @@ public:
return m_code_blob_metadata; return m_code_blob_metadata;
} }
void unpack_to(BlobTag tag, std::span<std::byte> destination) const
{
ensure(
tag == BlobTag::code,
"Invalid blob tag for shader asset: {}",
std::to_underlying(tag)
);
ensure(
destination.size() >= m_code_blob_metadata.uncompressed_size,
"Failed to unpack shader blob {} to destination ({}) of size {} since it's smaller "
"than the blobl's uncompressed size: {}",
std::to_underlying(tag),
(size_t)(destination.data()), // NOLINT(cppcoreguidelines-pro-type-cstyle-cast)
destination.size(),
m_code_blob_metadata.uncompressed_size
);
m_stream.seekg(static_cast<long long>(m_code_blob_metadata.offset));
m_stream.read(
(char *)destination.data(), // NOLINT(cppcoreguidelines-pro-type-cstyle-cast)
static_cast<long long>(m_code_blob_metadata.uncompressed_size)
);
}
[[nodiscard]] auto unpack(BlobTag tag) const -> Blob
{
ensure(
tag == BlobTag::code,
"Invalid blob tag for shader asset: {}",
std::to_underlying(tag)
);
auto blob = Blob(m_code_blob_metadata.uncompressed_size);
unpack_to(tag, blob);
return blob;
}
private: private:
AssetMetadata m_asset_metadata {}; AssetMetadata m_asset_metadata {};

View file

@ -1,3 +1,4 @@
add_library_module(lt_debug instrumentor.cpp) add_library_module(lt_debug instrumentor.cpp)
target_link_libraries(lt_debug PUBLIC logger) target_link_libraries(lt_debug PUBLIC logger)
target_precompile_headers(lt_debug PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/private/pch.hpp) target_precompile_headers(lt_debug PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/private/pch.hpp)

View file

@ -8,7 +8,6 @@ using lt::test::expect_unreachable;
using lt::test::Suite; using lt::test::Suite;
using lt::test::expect_eq; using lt::test::expect_eq;
using lt::test::expect_ne;
using lt::test::expect_false; using lt::test::expect_false;
using lt::test::expect_true; using lt::test::expect_true;

View file

@ -1,21 +1,9 @@
add_library_module(libmirror add_library_module(libmirror)
) target_link_libraries(libmirror INTERFACE app time input surface renderer)
target_link_libraries(
libmirror
INTERFACE
app
time
input
surface
renderer
)
add_test_module(libmirror add_test_module(
layers/editor_layer.test.cpp libmirror layers/editor_layer.test.cpp panels/asset_browser.test.cpp
panels/asset_browser.test.cpp panels/properties.test.cpp panels/scene_hierarchy.test.cpp)
panels/properties.test.cpp
panels/scene_hierarchy.test.cpp
)
add_executable_module(mirror entrypoint/mirror.cpp) add_executable_module(mirror entrypoint/mirror.cpp)
target_link_libraries(mirror PRIVATE libmirror input) target_link_libraries(mirror PRIVATE libmirror input)

View file

@ -24,6 +24,10 @@ void renderer_callback(
std::any &user_data std::any &user_data
) )
{ {
std::ignore = message_severity;
std::ignore = message_type;
std::ignore = user_data;
log_dbg("RENDERER CALLBACK: {}", data.message); log_dbg("RENDERER CALLBACK: {}", data.message);
} }
@ -204,7 +208,6 @@ public:
); );
auto entity = ecs::Entity { m_editor_registry, m_window }; auto entity = ecs::Entity { m_editor_registry, m_window };
memory::Ref<app::SystemStats> system_stats = nullptr;
m_renderer_system = std::make_shared<renderer::System>(renderer::System::CreateInfo { m_renderer_system = std::make_shared<renderer::System>(renderer::System::CreateInfo {
.config = { .target_api = renderer::Api::vulkan, .max_frames_in_flight = 3u }, .config = { .target_api = renderer::Api::vulkan, .max_frames_in_flight = 3u },

View file

@ -1,6 +1,6 @@
add_library_module(renderer add_library_module(
renderer
system.cpp system.cpp
# Vulkan - backend # Vulkan - backend
backend/vk/messenger.cpp backend/vk/messenger.cpp
backend/vk/context/device.cpp backend/vk/context/device.cpp
@ -18,27 +18,17 @@ add_library_module(renderer
frontend/context/surface.cpp frontend/context/surface.cpp
frontend/context/swapchain.cpp frontend/context/swapchain.cpp
frontend/renderer/renderer.cpp frontend/renderer/renderer.cpp
frontend/renderer/pass.cpp frontend/renderer/pass.cpp)
)
target_link_libraries(renderer target_link_libraries(
PUBLIC renderer
app PUBLIC app ecs memory assets time bitwise
ecs PRIVATE surface pthread)
memory
assets
time
bitwise
PRIVATE
surface
pthread
)
add_test_module(renderer add_test_module(
renderer
test/utils.cpp test/utils.cpp
system.test.cpp system.test.cpp
# general backend tests through the frontend # general backend tests through the frontend
frontend/messenger.test.cpp frontend/messenger.test.cpp
frontend/context/surface.test.cpp frontend/context/surface.test.cpp
@ -46,17 +36,9 @@ add_test_module(renderer
frontend/context/swapchain.test.cpp frontend/context/swapchain.test.cpp
frontend/renderer/pass.test.cpp frontend/renderer/pass.test.cpp
frontend/renderer/renderer.test.cpp frontend/renderer/renderer.test.cpp
# backend specific tests -- vk # backend specific tests -- vk
backend/vk/context/instance.test.cpp backend/vk/context/instance.test.cpp
# backend specific tests -- dx backend specific tests -- mt
# backend specific tests -- dx
# backend specific tests -- mt
)
target_link_libraries(renderer_tests
PRIVATE
surface
pthread
) )
target_link_libraries(renderer_tests PRIVATE surface pthread)

View file

@ -112,7 +112,7 @@ Instance::~Instance()
unload_library(); unload_library();
} }
void Instance::initialize_instance() __attribute__((no_sanitize("memory"))) void Instance::initialize_instance()
{ {
auto app_info = VkApplicationInfo { auto app_info = VkApplicationInfo {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
@ -217,6 +217,7 @@ void Instance::initialize_instance()
vkc(vk_enumerate_instance_extension_properties(nullptr, &count, nullptr)); vkc(vk_enumerate_instance_extension_properties(nullptr, &count, nullptr));
auto extensions = std::vector<VkExtensionProperties>(count); auto extensions = std::vector<VkExtensionProperties>(count);
memset(extensions.data(), 0, extensions.size() * sizeof(VkExtensionProperties));
vkc(vk_enumerate_instance_extension_properties(nullptr, &count, extensions.data())); vkc(vk_enumerate_instance_extension_properties(nullptr, &count, extensions.data()));
// log_inf("Available vulkan instance extensions:"); // log_inf("Available vulkan instance extensions:");
@ -230,9 +231,9 @@ void Instance::initialize_instance()
ensure(m_instance, "Failed to create vulkan instance"); ensure(m_instance, "Failed to create vulkan instance");
} }
void Instance::load_library() __attribute__((no_sanitize("memory"))) void Instance::load_library()
{ {
constexpr auto runtime_loader_flags = RTLD_NOW | RTLD_DEEPBIND | RTLD_LOCAL | RTLD_NODELETE; constexpr auto runtime_loader_flags = RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE;
library = dlopen("libvulkan.so.1", runtime_loader_flags); library = dlopen("libvulkan.so.1", runtime_loader_flags);
if (!library) if (!library)
{ {
@ -247,7 +248,7 @@ void Instance::load_library()
ensure(vk_get_instance_proc_address, "Failed to load vulkan function: vkGetInstanceProcAddr"); ensure(vk_get_instance_proc_address, "Failed to load vulkan function: vkGetInstanceProcAddr");
} }
void Instance::unload_library() __attribute__((no_sanitize("memory"))) void Instance::unload_library()
{ {
if (!library) if (!library)
{ {
@ -262,7 +263,7 @@ void Instance::unload_library()
// library = nullptr; // library = nullptr;
} }
void Instance::load_global_functions() __attribute__((no_sanitize("memory"))) void Instance::load_global_functions()
{ {
constexpr auto load_fn = []<typename T>(T &pfn, const char *fn_name) { constexpr auto load_fn = []<typename T>(T &pfn, const char *fn_name) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
@ -276,7 +277,7 @@ void Instance::load_global_functions()
load_fn(vk_enumerate_instance_layer_properties, "vkEnumerateInstanceLayerProperties"); load_fn(vk_enumerate_instance_layer_properties, "vkEnumerateInstanceLayerProperties");
} }
void Instance::load_instance_functions() __attribute__((no_sanitize("memory"))) void Instance::load_instance_functions()
{ {
const auto load_fn = [&]<typename T>(T &pfn, const char *fn_name) { const auto load_fn = [&]<typename T>(T &pfn, const char *fn_name) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
@ -320,7 +321,7 @@ void Instance::load_instance_functions()
load_fn(vk_destroy_surface_khr, "vkDestroySurfaceKHR"); load_fn(vk_destroy_surface_khr, "vkDestroySurfaceKHR");
} }
void Instance::load_device_functions_impl(VkDevice device) __attribute__((no_sanitize("memory"))) void Instance::load_device_functions_impl(VkDevice device)
{ {
const auto load_fn = [&]<typename T>(T &pfn, const char *fn_name) { const auto load_fn = [&]<typename T>(T &pfn, const char *fn_name) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)

View file

@ -64,17 +64,17 @@ private:
Instance(); Instance();
void initialize_instance(); __attribute__((no_sanitize("memory"))) void initialize_instance();
void load_library(); __attribute__((no_sanitize("memory"))) void load_library();
void unload_library(); __attribute__((no_sanitize("memory"))) void unload_library();
void load_global_functions(); __attribute__((no_sanitize("memory"))) void load_global_functions();
void load_instance_functions(); __attribute__((no_sanitize("memory"))) void load_instance_functions();
void load_device_functions_impl(VkDevice device); __attribute__((no_sanitize("memory"))) void load_device_functions_impl(VkDevice device);
VkInstance m_instance = VK_NULL_HANDLE; VkInstance m_instance = VK_NULL_HANDLE;

View file

@ -10,15 +10,16 @@ Pass::Pass(
const lt::assets::ShaderAsset &vertex_shader, const lt::assets::ShaderAsset &vertex_shader,
const lt::assets::ShaderAsset &fragment_shader const lt::assets::ShaderAsset &fragment_shader
) )
: m_device(static_cast<Device *>(device)), m_layout(m_device->create_pipeline_layout( : m_device(static_cast<Device *>(device))
VkPipelineLayoutCreateInfo { , m_layout(m_device->create_pipeline_layout(
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, VkPipelineLayoutCreateInfo {
.setLayoutCount = 0u, .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pSetLayouts = nullptr, .setLayoutCount = 0u,
.pushConstantRangeCount = 0u, .pSetLayouts = nullptr,
.pPushConstantRanges = nullptr, .pushConstantRangeCount = 0u,
} .pPushConstantRanges = nullptr,
)) }
))
{ {
auto *vertex_module = create_module( auto *vertex_module = create_module(
vertex_shader.unpack(lt::assets::ShaderAsset::BlobTag::code) vertex_shader.unpack(lt::assets::ShaderAsset::BlobTag::code)
@ -111,7 +112,6 @@ Pass::Pass(
.blendConstants = { 0.0f, 0.0, 0.0, 0.0 }, .blendConstants = { 0.0f, 0.0, 0.0, 0.0 },
}; };
auto attachment_description = VkAttachmentDescription { auto attachment_description = VkAttachmentDescription {
.format = static_cast<Swapchain *>(swapchain)->get_format(), .format = static_cast<Swapchain *>(swapchain)->get_format(),

View file

@ -46,8 +46,7 @@ System::System(CreateInfo info)
) }; ) };
} }
System::~System() System::~System() = default;
= default;
void System::on_register() void System::on_register()
{ {

View file

@ -1,2 +1,3 @@
add_library(std INTERFACE) add_library(std INTERFACE)
target_precompile_headers(std INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/public/pch.hpp) target_precompile_headers(std INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/public/pch.hpp)

View file

@ -14,7 +14,6 @@
#include <cfenv> #include <cfenv>
#include <cfloat> #include <cfloat>
#include <cinttypes> #include <cinttypes>
#include <ciso646>
#include <climits> #include <climits>
#include <clocale> #include <clocale>
#include <cmath> #include <cmath>

View file

@ -1,4 +1,4 @@
if (NOT WIN32) if(NOT WIN32)
add_library_module(surface linux/system.cpp) add_library_module(surface linux/system.cpp)
target_link_libraries(surface PRIVATE X11) target_link_libraries(surface PRIVATE X11)
@ -7,17 +7,10 @@ else(WIN32)
endif() endif()
target_link_libraries(surface PUBLIC target_link_libraries(
ecs surface
app PUBLIC ecs app math memory tbb
math PRIVATE logger lt_debug time)
memory
tbb
PRIVATE
logger
lt_debug
time
)
add_test_module(surface system.test.cpp) add_test_module(surface system.test.cpp)
add_fuzz_module(surface system.fuzz.cpp) add_fuzz_module(surface system.fuzz.cpp)

View file

@ -11,14 +11,19 @@
#include <X11/keysym.h> #include <X11/keysym.h>
#include <X11/keysymdef.h> #include <X11/keysymdef.h>
//
#include <sanitizer/msan_interface.h>
namespace lt::surface { namespace lt::surface {
template<int EventType> template<int EventType>
int XEventTypeEquals(Display *, XEvent *event, XPointer winptr) auto XEventTypeEquals(Display *display, XEvent *event, char *winptr) -> int
{ {
std::ignore = display;
return ( return (
event->type == EventType event->type == EventType
&& *(reinterpret_cast<Window *>(winptr)) == reinterpret_cast<XAnyEvent *>(event)->window && *(std::bit_cast<const Window *>(winptr))
== std::bit_cast<const XAnyEvent *>(event)->window
); );
} }
@ -100,7 +105,10 @@ void System::on_unregister()
{ {
} }
void System::create_surface_component(ecs::EntityId entity, SurfaceComponent::CreateInfo info) __attribute__((no_sanitize_memory)) void System::create_surface_component(
ecs::EntityId entity,
SurfaceComponent::CreateInfo info
)
try try
{ {
auto &component = m_registry->add<SurfaceComponent>(entity, info); auto &component = m_registry->add<SurfaceComponent>(entity, info);
@ -160,9 +168,14 @@ try
XSetWMProtocols(display, main_window, &surface.m_native_data.wm_delete_message, 1); XSetWMProtocols(display, main_window, &surface.m_native_data.wm_delete_message, 1);
// code to remove decoration // code to remove decoration
auto hints = std::array<unsigned char, 5> { 2, 0, 0, 0, 0 }; auto hints = std::array<const unsigned char, 5> { 2, 0, 0, 0, 0 };
const auto motif_hints = XInternAtom(display, "_MOTIF_WM_HINTS", False); const auto motif_hints = XInternAtom(display, "_MOTIF_WM_HINTS", False);
#if defined(__clang__) && __has_feature(memory_sanitizer)
auto bytes = (size_t)(1u) * (size_t)hints.size();
__msan_unpoison((void *)hints.data(), bytes);
#endif
XChangeProperty( XChangeProperty(
display, display,
surface.m_native_data.window, surface.m_native_data.window,
@ -331,7 +344,10 @@ void System::modify_title(SurfaceComponent &surface, const ModifyTitleRequest &r
XStoreName(display, window, request.title.c_str()); XStoreName(display, window, request.title.c_str());
} }
void System::modify_resolution(SurfaceComponent &surface, const ModifyResolutionRequest &request) __attribute__((no_sanitize("memory"))) void System::modify_resolution(
SurfaceComponent &surface,
const ModifyResolutionRequest &request
)
{ {
// surface.m_resolution = request.resolution; // surface.m_resolution = request.resolution;
@ -340,7 +356,7 @@ void System::modify_resolution(SurfaceComponent &surface, const ModifyResolution
// XResizeWindow(display, window, width, height); // XResizeWindow(display, window, width, height);
// get baseline serial number for X requests generated from XResizeWindow // get baseline serial number for X requests generated from XResizeWindow
uint64_t serial = NextRequest(display); auto serial = NextRequest(display);
// request a new window size from the X server // request a new window size from the X server
XResizeWindow(display, window, static_cast<uint32_t>(width), static_cast<uint32_t>(height)); XResizeWindow(display, window, static_cast<uint32_t>(width), static_cast<uint32_t>(height));
@ -396,7 +412,7 @@ void System::modify_position(SurfaceComponent &surface, const ModifyPositionRequ
const auto &[x, y] = request.position; const auto &[x, y] = request.position;
// get baseline serial number for X requests generated from XResizeWindow // get baseline serial number for X requests generated from XResizeWindow
uint64_t serial = NextRequest(display); auto serial = NextRequest(display);
XMoveWindow(display, window, static_cast<int>(x), static_cast<int>(y)); XMoveWindow(display, window, static_cast<int>(x), static_cast<int>(y));
// flush output queue and wait for X server to processes the request // flush output queue and wait for X server to processes the request

View file

@ -16,7 +16,6 @@ using test::expect_eq;
using test::expect_ne; using test::expect_ne;
using test::expect_not_nullptr; using test::expect_not_nullptr;
using test::expect_throw; using test::expect_throw;
using test::expect_true;
using test::Suite; using test::Suite;
[[nodiscard]] auto tick_info() -> app::TickInfo [[nodiscard]] auto tick_info() -> app::TickInfo

View file

@ -4,10 +4,7 @@
namespace lt::surface { namespace lt::surface {
System::System( System::System(memory::Ref<ecs::Registry> registry, memory::Ref<app::EventMediator> event_mediator)
memory::Ref<ecs::Registry> registry,
memory::Ref<app::EventMediator> event_mediator
)
: m_registry(std::move(registry)) : m_registry(std::move(registry))
, m_event_mediator(std::move(event_mediator)) , m_event_mediator(std::move(event_mediator))
{ {

View file

@ -27,7 +27,10 @@ public:
void on_unregister() override; void on_unregister() override;
void create_surface_component(ecs::EntityId entity, SurfaceComponent::CreateInfo info); __attribute__((no_sanitize("memory"))) void create_surface_component(
ecs::EntityId entity,
SurfaceComponent::CreateInfo info
);
void tick(app::TickInfo tick) override; void tick(app::TickInfo tick) override;
@ -45,12 +48,12 @@ private:
void modify_title(struct SurfaceComponent &surface, const struct ModifyTitleRequest &request); void modify_title(struct SurfaceComponent &surface, const struct ModifyTitleRequest &request);
void modify_resolution( __attribute__((no_sanitize("memory"))) void modify_resolution(
struct SurfaceComponent &surface, struct SurfaceComponent &surface,
const struct ModifyResolutionRequest &request const struct ModifyResolutionRequest &request
); );
void modify_position( __attribute__((no_sanitize("memory"))) void modify_position(
struct SurfaceComponent &surface, struct SurfaceComponent &surface,
const struct ModifyPositionRequest &request const struct ModifyPositionRequest &request
); );

View file

@ -1,38 +0,0 @@
#!/bin/bash
find . -type f \( -name "*.cpp" -o -name "*.hpp" \) -print0 | while IFS= read -r -d '' file; do
scope=false
ref=false
if grep -Eq "Scope\s*<" "$file"; then
scope=true
sed -i -E 's/(Scope)(\s*<)/memory::\1\2/g' "$file"
fi
if grep -Eq "Ref\s*<" "$file"; then
ref=true
sed -i -E 's/(Ref)(\s*<)/memory::\1\2/g' "$file"
fi
if grep -Eq "\bcreate_scope\b" "$file"; then
scope=true
sed -i -E 's/\b(create_scope)\b/memory::\1/g' "$file"
fi
if grep -Eq "\bcreate_ref\b" "$file"; then
ref=true
sed -i -E 's/\b(create_ref)\b/memory::\1/g' "$file"
fi
if $scope || $ref; then
includes=""
$scope && includes+="#include <memory/scope.hpp>\n"
$ref && includes+="#include <memory/reference.hpp>\n"
tmp=$(mktemp)
if [[ "$file" =~ \.hpp$ ]] && pragma_line=$(grep -En -m1 '^#pragma once' "$file" | cut -d: -f1); then
insert_line=$((pragma_line + 2))
else
insert_line=1
fi
head -n $((insert_line - 1)) "$file" > "$tmp"
echo -e "$includes" >> "$tmp"
tail -n +$insert_line "$file" >> "$tmp"
mv "$tmp" "$file"
clang-format -i "$file"
fi
done

View file

@ -1,7 +1,7 @@
add_library_module(test test.cpp entrypoint.cpp) add_library_module(test test.cpp entrypoint.cpp)
add_library_module(fuzz_test test.cpp fuzz.cpp) add_library_module(fuzz_test test.cpp fuzz.cpp)
target_link_libraries(test PUBLIC tbb) target_link_libraries(test PUBLIC tbb logger)
target_link_libraries(fuzz_test PUBLIC tbb) target_link_libraries(fuzz_test PUBLIC tbb logger)
add_test_module(test test.test.cpp) add_test_module(test test.test.cpp)

View file

@ -1,3 +1,4 @@
#include <logger/logger.hpp>
#include <test/test.hpp> #include <test/test.hpp>
using namespace ::lt::test; using namespace ::lt::test;
@ -84,14 +85,14 @@ try
} }
catch (const std::exception &exp) catch (const std::exception &exp)
{ {
std::println("Terminated due to uncaught exception:"); log_crt("Terminated due to uncaught exception:");
std::println("\twhat: {}", exp.what()); log_crt("\twhat: {}", exp.what());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
catch (...) catch (...)
{ {
std::println("Terminated due to uncaught non-std exception!"); log_crt("Terminated due to uncaught non-std exception!");
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View file

@ -1,4 +1,3 @@
add_library_module(time timer.cpp) add_library_module(time timer.cpp)
target_link_libraries(time PUBLIC tbb) target_link_libraries(time PUBLIC tbb)
add_test_module(time timer.test.cpp) add_test_module(time timer.test.cpp)

View file

@ -4,7 +4,6 @@
#include <ui/ui.hpp> #include <ui/ui.hpp>
#ifdef LIGHT_PLATFORM_WINDOWS #ifdef LIGHT_PLATFORM_WINDOWS
#include <renderer/dx/shared_context.hpp>
#include <renderer/dx/user_interface.hpp> #include <renderer/dx/user_interface.hpp>
#endif #endif
@ -14,7 +13,6 @@
#include <input/events/keyboard.hpp> #include <input/events/keyboard.hpp>
#include <input/events/mouse.hpp> #include <input/events/mouse.hpp>
#include <input/key_codes.hpp> #include <input/key_codes.hpp>
#include <renderer/graphics_context.hpp>
#include <utility> #include <utility>
@ -27,8 +25,7 @@ namespace lt {
UserInterface *UserInterface::s_context = nullptr; UserInterface *UserInterface::s_context = nullptr;
auto UserInterface::create(memory::Ref<SharedContext> sharedContext) auto UserInterface::create(memory::Ref<SharedContext> sharedContext) -> memory::Scope<UserInterface>
-> memory::Scope<UserInterface>
{ {
auto scopeUserInterface = memory::Scope<UserInterface> { nullptr }; auto scopeUserInterface = memory::Scope<UserInterface> { nullptr };

View file

@ -11,8 +11,7 @@ class SharedContext;
class UserInterface class UserInterface
{ {
public: public:
static auto create(memory::Ref<SharedContext> sharedContext) static auto create(memory::Ref<SharedContext> sharedContext) -> memory::Scope<UserInterface>;
-> memory::Scope<UserInterface>;
static void dockspace_begin(); static void dockspace_begin();

View file

@ -1,99 +1,301 @@
FROM archlinux:latest FROM archlinux:latest
## Configurations ##
RUN \
mkdir /msan \
&& echo 'src:*' > /msan/ignorelist_all_sources \
&& sed -i 's/^#ParallelDownloads = .*/ParallelDownloads = 8/' /etc/pacman.conf \
&& echo 'NoExtract = usr/share/{man,doc,info}/*' >> /etc/pacman.conf
## Packages ## ## Packages ##
RUN \ RUN \
sed -i 's/^#ParallelDownloads = .*/ParallelDownloads = 8/' /etc/pacman.conf \ pacman -Syyu --noconfirm --needed --disable-download-timeout \
&& echo 'NoExtract = usr/share/{man,doc,info}/*' >> /etc/pacman.conf \ afl++ \
&& pacman -Syyu --noconfirm --needed --disable-download-timeout \ afl-utils \
afl++ \ base-devel \
afl-utils \ bash \
base-devel \ cbindgen \
bash \ clang \
clang \ cmake \
cmake \ curl \
curl \ debuginfod \
expat \ directx-headers \
gcc \ elfutils \
gdb \ expat \
git \ gcc \
glm \ gcc-libs \
libc++ \ gdb \
libinput \ git \
libpciaccess \ glibc \
libpng \ glm \
libunwind \ glslang \
libx11 \ libc++ \
libxcb \ libclc \
libxcursor \ libdrm \
libxi \ libelf \
libxinerama \ libglvnd \
libxpresent \ libinput \
libxrandr \ libpciaccess \
lz4 \ libpng \
mesa \ libunwind \
mold \ libva \
ninja \ libx11 \
python \ libxcb \
python-distlib \ libxdamage \
python-distutils-extra \ libxext \
python-jsonschema \ libxfixes \
qt5-base \ libxi \
qt6-base \ libxinerama \
valgrind \ libxml2 \
vulkan-headers \ libxpresent \
vulkan-icd-loader \ libxrandr \
vulkan-tools \ libxshmfence \
vulkan-validation-layers \ libxxf86vm \
wayland \ lm_sensors \
wayland-protocols \ llvm \
wget \ lz4 \
xcb-util \ meson \
xcb-util-cursor \ mold \
xcb-util-keysyms \ ninja \
xcb-util-wm \ python \
xorg-server-xvfb \ python-distlib \
xorg-util-macros \ python-distutils-extra \
xtrans \ python-jsonschema \
zlib \ python-mako \
zstd \ python-packaging \
python-ply \
python-pyaml \
qt5-base \
qt6-base \
rust \
rust-bindgen \
spirv-llvm-translator \
spirv-tools \
systemd-libs \
valgrind \
vulkan-headers \
vulkan-icd-loader \
vulkan-tools \
vulkan-validation-layers \
wayland \
wayland-protocols \
wget \
xcb-proto \
xcb-util \
xcb-util-cursor \
xcb-util-keysyms \
xcb-util-wm \
xorg-server-xvfb \
xorg-util-macros \
xorgproto \
xtrans \
zlib \
zstd \
&& pacman -Scc --noconfirm && pacman -Scc --noconfirm
## Sanitizers ## ## Libc++ ##
RUN \ RUN \
git clone --depth=1 https://github.com/llvm/llvm-project.git -b llvmorg-20.1.8 \ git clone \
&& mkdir llvm-project/build-lsan llvm-project/build-msan \ --branch llvmorg-20.1.8 \
--depth=1 \
https://github.com/llvm/llvm-project.git
RUN cd llvm-project/ \
\ \
&& cd llvm-project/build-lsan \ && cmake \
&& cmake -G Ninja \ -S ./runtimes \
-DCMAKE_BUILD_TYPE=Release \ -B ./build-lsan \
-DCMAKE_LINKER_TYPE="MOLD" \ -G Ninja \
-DCMAKE_INSTALL_PREFIX=/libcxx_lsan \ -D CMAKE_LINKER_TYPE="MOLD" \
-DCMAKE_C_COMPILER=clang \ -D CMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_COMPILER=clang++ \ -D CMAKE_INSTALL_PREFIX=/libcxx_lsan \
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ -D CMAKE_C_COMPILER=$(which clang) \
-DLLVM_ENABLE_PIC=ON \ -D CMAKE_CXX_COMPILER=$(which clang++) \
-DLIBCXX_INSTALL_MODULES=ON \ -D LLVM_ENABLE_PROJECTS="clang;compiler-rt" \
-DLIBCXXABI_USE_LLVM_UNWINDER=OFF \ -D LLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
-DLLVM_USE_SANITIZER=Leaks \ -D LLVM_TARGETS_TO_BUILD="X86;SPIRV" \
../runtimes \ -D LLVM_ENABLE_PIC=ON \
&& ninja cxx cxxabi \ -D LIBCXX_INSTALL_MODULES=ON \
&& ninja install-cxx install-cxxabi \ -D LIBCXXABI_USE_LLVM_UNWINDER=OFF \
-D LLVM_USE_SANITIZER=Leaks \
&& cd ./build-lsan/ && ninja cxx cxxabi && ninja install-cxx install-cxxabi && cd ../ \
\ \
&& cd ../build-msan \ && cmake \
&& cmake -G Ninja \ -S ./runtimes \
-DCMAKE_BUILD_TYPE=Release \ -B ./build-msan \
-DCMAKE_LINKER_TYPE="MOLD" \ -G Ninja \
-DCMAKE_INSTALL_PREFIX=/libcxx_msan \ -D CMAKE_LINKER_TYPE="MOLD" \
-DCMAKE_C_COMPILER=clang \ -D CMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_COMPILER=clang++ \ -D CMAKE_INSTALL_PREFIX=/libcxx_msan \
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ -D CMAKE_C_COMPILER=$(which clang) \
-DLLVM_ENABLE_PIC=ON \ -D CMAKE_CXX_COMPILER=$(which clang++) \
-DLIBCXX_INSTALL_MODULES=ON \ -D LLVM_ENABLE_PROJECTS="clang;compiler-rt" \
-DLIBCXXABI_USE_LLVM_UNWINDER=OFF \ -D LLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
-DLLVM_USE_SANITIZER=MemoryWithOrigins \ -D LLVM_TARGETS_TO_BUILD="X86;SPIRV" \
../runtimes \ -D LLVM_ENABLE_PIC=ON \
&& ninja cxx cxxabi \ -D LIBCXX_INSTALL_MODULES=ON \
&& ninja install-cxx install-cxxabi \ -D LIBCXXABI_USE_LLVM_UNWINDER=OFF \
\ -D LLVM_USE_SANITIZER=MemoryWithOrigins \
&& cd ../.. \ && cd ./build-msan/ && ninja cxx cxxabi && ninja install-cxx install-cxxabi && cd ../
&& rm -rf llvm-project
## libxcb ##
RUN \
wget https://x.org/releases/individual/lib/libxcb-1.17.0.tar.xz \
&& tar xf libxcb-1.17.0.tar.xz \
&& cd libxcb-1.17.0 \
&& export CC=clang \
&& export CFLAGS=" \
-fsanitize=memory \
-fsanitize-memory-track-origins \
-fsanitize-ignorelist=/msan/ignorelist_all_sources \
-fno-omit-frame-pointer \
-g \
-fPIC" \
&& export LDFLAGS=" \
-fsanitize=memory \
-fsanitize-memory-track-origins \
-fsanitize-ignorelist=/msan/ignorelist_all_sources \
-fno-omit-frame-pointer \
-g \
-fPIC" \
&& ./configure \
--prefix=/msan \
--disable-static \
--without-doxygen \
&& make && make install \
&& cd .. && rm -rf libxcb-1.17.0 libxcb-1.17.0.tar.xz
## libx11 ##
RUN \
wget https://x.org/releases/individual/lib/libX11-1.8.12.tar.xz \
&& tar xf libX11-1.8.12.tar.xz \
&& cd libX11-1.8.12 \
&& export CC=clang \
&& export CFLAGS=" \
-fsanitize=memory \
-fsanitize-memory-track-origins \
-fsanitize-ignorelist=/msan/ignorelist_all_sources \
-fno-omit-frame-pointer \
-g \
-fPIC" \
&& export LDFLAGS=" \
-fsanitize=memory \
-fsanitize-memory-track-origins \
-fsanitize-ignorelist=/msan/ignorelist_all_sources \
-fno-omit-frame-pointer \
-g \
-fPIC" \
&& export PKG_CONFIG_PATH=/msan/lib/pkgconfig:$PKG_CONFIG_PATH \
&& ./configure \
--prefix=/msan \
--disable-static \
&& make && make install \
&& cd .. && rm -rf libX11-1.8.12 libX11-1.8.12.tar.xz
RUN wget 'https://sdk.lunarg.com/sdk/download/1.4.328.1/linux/vulkansdk-linux-x86_64-1.4.328.1.tar.xz'
RUN tar xf vulkansdk-linux-x86_64-1.4.328.1.tar.xz
## Vulkan SDK ##
RUN \
cd /1.4.328.1 \
&& chmod +x ./vulkansdk \
&& chmod +x ./setup-env.sh \
&& export CC="$(which clang)" \
&& export CXX="$(which clang++)" \
&& export CXXFLAGS="\
-fsanitize=memory \
-fsanitize-memory-track-origins \
-fsanitize-ignorelist=/msan/ignorelist_all_sources \
-fno-omit-frame-pointer \
-g \
-std=c++23 \
-nostdinc++ \
-isystem /libcxx_msan/include/c++/v1/"\
&& export CFLAGS="\
-fsanitize=memory \
-fsanitize-memory-track-origins \
-fno-omit-frame-pointer \
-g" \
&& export LDFLAGS="\
-fsanitize=memory \
-fsanitize-memory-track-origins \
-fsanitize-ignorelist=/msan/ignorelist_all_sources \
-g \
-std=c++23 \
-L/msan/lib -Wl,-rpath,/msan/lib \
-L/libcxx_msan/lib -Wl,-rpath,/libcxx_msan/lib \
-lc++ \
-lc++abi" \
&& ./vulkansdk \
--debug \
--numjobs `nproc` \
vulkan-loader
## Mesa ##
RUN git clone \
--branch='25.2'\
--depth=1 \
https://gitlab.freedesktop.org/mesa/mesa.git
RUN \
export CXX=$(which clang++) \
&& export CC=$(which clang) \
&& export CXXFLAGS="\
-fsanitize=memory \
-fsanitize-memory-track-origins \
-fno-omit-frame-pointer \
-g \
-nostdinc++ \
-isystem /libcxx_msan/include/c++/v1/"\
&& export CFLAGS="\
-fsanitize=memory \
-fsanitize-memory-track-origins \
-fno-omit-frame-pointer \
-g" \
&& export LDFLAGS="\
-fsanitize=memory \
-fsanitize-memory-track-origins \
-g \
-L/msan/lib -Wl,-rpath,/msan/lib \
-L/libcxx_msan/lib -Wl,-rpath,/libcxx_msan/lib \
-lc++ \
-lc++abi" \
&& meson setup ./ _build \
-D build-tests=false \
-D enable-glcpp-tests=false \
-D build-radv-tests=false \
-D build-aco-tests=false \
-D install-intel-gpu-tests=false \
-D gallium-mediafoundation-test=false \
-D android-libbacktrace=disabled \
-D split-debug=disabled \
-D b_ndebug=true \
-D b_lto=false \
-D egl=enabled \
-D gallium-drivers=r300,r600,radeonsi,nouveau,virgl,svga,softpipe,llvmpipe,i915,iris,crocus,zink \
-D gallium-extra-hud=true \
-D gallium-rusticl=true \
-D gallium-va=enabled \
-D gbm=enabled \
-D gles1=disabled \
-D gles2=enabled \
-D glvnd=enabled \
-D glx=dri \
-D libunwind=enabled \
-D llvm=enabled \
-D lmsensors=disabled \
-D microsoft-clc=disabled \
-D platforms=x11,wayland \
-D valgrind=disabled \
-D video-codecs=all \
-D vulkan-drivers=amd,intel,intel_hasvk,swrast,virtio,nouveau \
-D vulkan-layers=device-select,intel-nullhw,overlay \
-D tools='' \
-D zstd=enabled \
-D buildtype=plain \
-D prefix=/usr \
-D sysconfdir=/etc \
--wrap-mode=nofallback \
--force-fallback-for=syn,paste,rustc-hash \
&& ninja -C _build

View file

@ -1,50 +1,59 @@
#!/bin/bash #!/bin/bash
set -e set -euo pipefail
cd $(git rev-parse --show-toplevel)/ cd "$(git rev-parse --show-toplevel)/"
rm -rf ./build && mkdir build/
CC=$(which clang)
export CC
CXX=$(which clang++)
export CXX
DISPLAY=:99
export DISPLAY
Xvfb :99 -screen 0 1024x768x16 & Xvfb :99 -screen 0 1024x768x16 &
export CXX=$(which clang++)
export CC=$(which clang)
export DISPLAY=:99
cmake . \ cmake \
-Bbuild \ -S . \
-GNinja \ -B build \
-DCMAKE_LINKER_TYPE=MOLD \ -G Ninja \
-DENABLE_UNIT_TESTS=ON \ -D CMAKE_LINKER_TYPE=MOLD \
-DENABLE_LLVM_COVERAGE=ON \ -D ENABLE_UNIT_TESTS=ON \
-DCMAKE_BUILD_TYPE=Release \ -D ENABLE_LLVM_COVERAGE=ON \
-DCMAKE_CXX_FLAGS="-std=c++23 -stdlib=libc++ -g -fno-omit-frame-pointer" \ -D CMAKE_BUILD_TYPE=Release \
&& cmake --build ./build -j `nproc` -D CMAKE_CXX_FLAGS="-std=c++23 -stdlib=libc++ -g -fno-omit-frame-pointer"
mkdir -p ./build/coverage/ cmake --build ./build -j"$(nproc)"
for test in $(find ./build -type f -name '*_tests' -executable); do
export LLVM_PROFILE_FILE="./build/coverage/$(basename "$(dirname "$test")").profraw";
echo ${LLVM_PROFILE_FILE} >> ./build/coverage/list;
mkdir -p ./build/coverage/
while IFS= read -r -d '' test; do
LLVM_PROFILE_FILE="./build/coverage/$(basename "$(dirname "$test")").profraw"
export LLVM_PROFILE_FILE
echo "${LLVM_PROFILE_FILE}" >>./build/coverage/list
gdb \ gdb \
--return-child-result \ --return-child-result \
-ex='set confirm off' \ -ex='set confirm off' \
-ex='set pagination off' \ -ex='set pagination off' \
-ex='run' \ -ex='run' \
-ex='bt full' \ -ex='bt full' \
-ex='quit' \ -ex='quit' \
-q \ -q \
"$test" "$test"
done done < <(find ./build -type f -name '*_tests' -executable -print0)
llvm-profdata merge --input-files './build/coverage/list' -o "./build/coverage/merged.profdata" llvm-profdata merge --input-files './build/coverage/list' -o "./build/coverage/merged.profdata"
find ./build/modules -type f -name "*.profraw" -exec rm -fv {} + find ./build/modules -type f -name "*.profraw" -exec rm -fv {} +
LLVM_COV_SHOW=$(llvm-cov show \ LLVM_COV_SHOW=$(
llvm-cov show \
-instr-profile='./build/coverage/merged.profdata' \ -instr-profile='./build/coverage/merged.profdata' \
$(find ./build -type f -name '*_tests' -executable -exec printf -- '-object %s ' {} \;) \ "$(find ./build -type f -name '*_tests' -executable -exec printf -- '-object %s ' {} \;)" \
$(find ./build -type f -name '*\.a' -exec printf -- '-object %s ' {} \;) \ "$(find ./build -type f -name '*\.a' -exec printf -- '-object %s ' {} \;)" \
-ignore-filename-regex='\.test\.cpp$' \ -ignore-filename-regex='\.test\.cpp$' \
-ignore-filename-regex='\.fuzz\.cpp$' -ignore-filename-regex='\.fuzz\.cpp$'
) )
echo "${LLVM_COV_SHOW}" > './build/coverage/coverage.txt' echo "${LLVM_COV_SHOW}" >'./build/coverage/coverage.txt'
cd ./build/coverage/ && wget -qO- "https://codecov.io/bash" | bash cd ./build/coverage/ && wget -qO- "https://codecov.io/bash" | bash

View file

@ -1,21 +1,33 @@
#!/bin/bash #!/bin/bash
set -e set -euo pipefail
cd $(git rev-parse --show-toplevel)/ cd "$(git rev-parse --show-toplevel)/"
rm -rf ./build && mkdir build/
CC=$(which clang)
export CC
CXX=$(which clang++)
export CXX
DISPLAY=:99
export DISPLAY
LSAN_OPTIONS="suppressions=$(git rev-parse --show-toplevel)/tools/ci/amd64/clang/lsan.supp:fast_unwind_on_malloc=0:verbosity=1:report_objects=1"
export LSAN_OPTIONS
LSAN_SYMBOLIZER_PATH="$(which llvm-symbolizer)"
export LSAN_SYMBOLIZER_PATH
Xvfb :99 -screen 0 1024x768x16 & Xvfb :99 -screen 0 1024x768x16 &
export CXX=$(which clang++)
export CC=$(which clang)
export DISPLAY=:99
cmake . \ cmake \
-Bbuild \ -S . \
-GNinja \ -B build \
-DCMAKE_LINKER_TYPE=MOLD \ -G Ninja \
-DENABLE_UNIT_TESTS=ON \ -D CMAKE_LINKER_TYPE=MOLD \
-DCMAKE_BUILD_TYPE=Debug \ -D ENABLE_UNIT_TESTS=ON \
-DCMAKE_CXX_FLAGS=" \ -D CMAKE_BUILD_TYPE=Release \
-D CMAKE_CXX_FLAGS=" \
-fsanitize=leak \ -fsanitize=leak \
-fno-common \ -fno-common \
-g \ -g \
@ -23,17 +35,16 @@ cmake . \
-std=c++23 \ -std=c++23 \
-nostdinc++ \ -nostdinc++ \
-isystem /libcxx_lsan/include/c++/v1/" \ -isystem /libcxx_lsan/include/c++/v1/" \
-DCMAKE_EXE_LINKER_FLAGS=" \ -D CMAKE_EXE_LINKER_FLAGS=" \
-fsanitize=leak \ -fsanitize=leak \
-L/libcxx_lsan/lib \ -L/libcxx_lsan/lib \
-lc++ \ -lc++ \
-lc++abi \ -lc++abi \
-Wl,-rpath,/libcxx_lsan/lib" \ -Wl,-rpath,/libcxx_lsan/lib"
&& cmake --build ./build --target='renderer_tests' -j`nproc`
export LSAN_OPTIONS="suppressions=$(git rev-parse --show-toplevel)/tools/ci/amd64/clang/lsan.supp:fast_unwind_on_malloc=0:verbosity=1:report_objects=1" cmake --build ./build --target='renderer_tests' -j"$(nproc)"
export LSAN_SYMBOLIZER_PATH="$(which llvm-symbolizer)"
for test in $(find ./build -type f -name '*_tests' -executable); do while IFS= read -r -d '' test; do
echo "Running $test" echo "Running $test"
"$test" "$test"
done done < <(find ./build -type f -name '*_tests' -executable -print0)

View file

@ -1,21 +1,27 @@
#!/bin/bash #!/bin/bash
set -e set -euo pipefail
cd $(git rev-parse --show-toplevel)/ cd "$(git rev-parse --show-toplevel)/"
rm -rf ./build && mkdir build/
CC=$(which clang)
export CC
CXX=$(which clang++)
export CXX
DISPLAY=:99
export DISPLAY
Xvfb :99 -screen 0 1024x768x16 & Xvfb :99 -screen 0 1024x768x16 &
export CXX=$(which clang++)
export CC=$(which clang)
export DISPLAY=:99
cmake . \ cmake \
-Bbuild \ -S . \
-GNinja \ -B build \
-DCMAKE_LINKER_TYPE=MOLD \ -G Ninja \
-DENABLE_UNIT_TESTS=ON \ -D CMAKE_LINKER_TYPE=MOLD \
-DCMAKE_BUILD_TYPE=Release \ -D ENABLE_UNIT_TESTS=ON \
-DCMAKE_CXX_FLAGS=" \ -D CMAKE_BUILD_TYPE=Release \
-D CMAKE_CXX_FLAGS=" \
-fsanitize=memory \ -fsanitize=memory \
-fsanitize-memory-track-origins \ -fsanitize-memory-track-origins \
-g \ -g \
@ -23,16 +29,17 @@ cmake . \
-std=c++23 \ -std=c++23 \
-nostdinc++ \ -nostdinc++ \
-isystem /libcxx_msan/include/c++/v1/" \ -isystem /libcxx_msan/include/c++/v1/" \
-DCMAKE_EXE_LINKER_FLAGS=" \ -D CMAKE_EXE_LINKER_FLAGS=" \
-fsanitize=memory \ -fsanitize=memory \
-fsanitize-memory-track-origins \ -fsanitize-memory-track-origins \
-L/libcxx_msan/lib \ -L/libcxx_msan/lib \
-lc++ \ -lc++ \
-lc++abi \ -lc++abi \
-Wl,-rpath,/libcxx_msan/lib" \ -Wl,-rpath,/libcxx_msan/lib"
&& cmake --build ./build -j`nproc`
for test in $(find ./build -type f -name '*_tests' -executable); do cmake --build ./build -j"$(nproc)"
echo "Running $test"
"$test" while IFS= read -r -d '' test; do
done echo "Running $test"
"$test"
done < <(find ./build -type f -name '*_tests' -executable -print0)

View file

@ -0,0 +1,3 @@
src:*
obj:*
fun:*

View file

@ -1,33 +1,41 @@
#!/bin/bash #!/bin/bash
set -e set -euo pipefail
cd $(git rev-parse --show-toplevel)/ cd "$(git rev-parse --show-toplevel)/"
rm -rf ./build && mkdir build/
CC=$(which gcc)
export CC
CXX=$(which g++)
export CXX
DISPLAY=:99
export DISPLAY
Xvfb :99 -screen 0 1024x768x16 & Xvfb :99 -screen 0 1024x768x16 &
export CXX=$(which g++)
export CC=$(which gcc)
export DISPLAY=:99
# gcc uses libstdc++ by default # gcc uses libstdc++ by default
cmake . \ cmake \
-Bbuild \ -S . \
-GNinja \ -B build \
-DCMAKE_LINKER_TYPE=MOLD \ -G Ninja \
-DENABLE_UNIT_TESTS=ON \ -D CMAKE_LINKER_TYPE=MOLD \
-DCMAKE_BUILD_TYPE=Release \ -D ENABLE_UNIT_TESTS=ON \
-DCMAKE_CXX_FLAGS="-std=c++23 -g -fno-omit-frame-pointer" \ -D CMAKE_BUILD_TYPE=Release \
&& cmake --build ./build -j `nproc` -D CMAKE_CXX_FLAGS="-std=c++23 -g -fno-omit-frame-pointer"
for test in $(find ./build -type f -name '*_tests' -executable); do cmake --build ./build -j"$(nproc)"
while IFS= read -r -d '' test; do
echo "Running $test" echo "Running $test"
gdb \ gdb \
--return-child-result \ --return-child-result \
-ex='set confirm off' \ -ex='set confirm off' \
-ex='set pagination off' \ -ex='set pagination off' \
-ex='run' \ -ex='run' \
-ex='bt full' \ -ex='bt full' \
-ex='quit' \ -ex='quit' \
-q \ -q \
"$test" "$test"
done
done < <(find ./build -type f -name '*_tests' -executable -print0)

View file

@ -1,35 +1,45 @@
#!/bin/bash #!/bin/bash
export DEBUGINFOD_URLS="https://debuginfod.archlinux.org/" set -euo pipefail
cd "$(git rev-parse --show-toplevel)/"
set -e CC=$(which gcc)
cd $(git rev-parse --show-toplevel)/ export CC
rm -rf ./build && mkdir build/
CXX=$(which g++)
export CXX
DISPLAY=:99
export DISPLAY
DEBUGINFOD_URLS="https://debuginfod.archlinux.org/"
export DEBUGINFOD_URLS
Xvfb :99 -screen 0 1024x768x16 & Xvfb :99 -screen 0 1024x768x16 &
export CXX=$(which g++)
export CC=$(which gcc)
export DISPLAY=:99
# gcc uses libstdc++ by default # gcc uses libstdc++ by default
cmake . \ cmake \
-Bbuild \ -S . \
-GNinja \ -B build \
-DCMAKE_LINKER_TYPE=MOLD \ -G Ninja \
-DENABLE_UNIT_TESTS=ON \ -D CMAKE_LINKER_TYPE=MOLD \
-DCMAKE_BUILD_TYPE=Release \ -D ENABLE_UNIT_TESTS=ON \
-DCMAKE_CXX_FLAGS="-std=c++23 -g -fno-omit-frame-pointer" \ -D CMAKE_BUILD_TYPE=Release \
&& cmake --build ./build -j `nproc` -D CMAKE_CXX_FLAGS="-std=c++23 -fno-omit-frame-pointer -fno-common -g"
for test in $(find ./build -type f -name '*_tests' -executable); do cmake --build ./build -j"$(nproc)"
while IFS= read -r -d '' test; do
echo "Running $test" echo "Running $test"
valgrind \ valgrind \
--leak-check=full \ --leak-check=full \
--show-leak-kinds=all \ --show-leak-kinds=all \
--track-origins=yes \ --track-origins=yes \
--verbose \ --verbose \
--num-callers=50 \ --num-callers=50 \
--gen-suppressions=all \ --gen-suppressions=all \
--suppressions='./tools/ci/amd64/gcc/valgrind.supp' \ --suppressions='./tools/ci/amd64/gcc/valgrind.supp' \
--error-exitcode=255 ${test} || exit 1 --error-exitcode=255 "${test}" || exit 1
done
done < <(find ./build -type f -name '*_tests' -executable -print0)

View file

@ -1,3 +1,130 @@
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: indirect
fun:calloc
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
fun:_ZNK2lt8renderer2vk6Device17destroy_swapchainEP16VkSwapchainKHR_T
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
fun:_ZNK2lt8renderer2vk6Device17destroy_swapchainEP16VkSwapchainKHR_T
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:_dbus_strdup
fun:UnknownInlinedFun
fun:UnknownInlinedFun
fun:internal_bus_get
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
fun:UnknownInlinedFun
fun:UnknownInlinedFun
fun:loader_icd_scan
fun:UnknownInlinedFun
fun:UnknownInlinedFun
fun:terminator_EnumerateInstanceExtensionProperties
fun:vkEnumerateInstanceExtensionProperties
}
{
<insert_a_suppression_name_here>
Memcheck:Cond
obj:/usr/lib/libnvidia-glvkspirv.so.580.95.05
obj:/usr/lib/libnvidia-glvkspirv.so.580.95.05
obj:/usr/lib/libnvidia-glvkspirv.so.580.95.05
fun:_nv002nvvm
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:malloc
fun:_dl_close_worker
fun:_dl_close
fun:_dl_catch_exception
fun:_dl_catch_error
fun:_dlerror_run
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
fun:~Swapchain
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: indirect
fun:calloc
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
obj:*
fun:~Swapchain
}
{ {
<insert_a_suppression_name_here> <insert_a_suppression_name_here>
Memcheck:Param Memcheck:Param

View file

@ -1,19 +1,19 @@
#!/bin/bash #!/bin/bash
set -e set -euo pipefail
cd $(git rev-parse --show-toplevel)/ cd "$(git rev-parse --show-toplevel)/"
has_fomatting_issues=0 has_fomatting_issues=0
for file in $(find ./modules -name '*.?pp'); do while IFS= read -r -d '' file; do
echo "Checking format for $file" echo "Checking format for $file"
if ! clang-format --dry-run --Werror "$file"; then
echo "❌ Formatting issue detected in $file" if ! clang-format --dry-run --Werror "$file"; then
has_fomatting_issues=1 echo "❌ Formatting issue detected in $file"
fi has_fomatting_issues=1
done fi
done < <(find ./modules -name '*.?pp' -print0)
if [ "$has_fomatting_issues" -eq 0 ]; then if [ "$has_fomatting_issues" -eq 0 ]; then
echo "✅ All files are properly formatted! Well done! ^~^" echo "✅ All files are properly formatted! Well done! ^~^"
fi fi
exit ${has_fomatting_issues} exit ${has_fomatting_issues}

View file

@ -1,17 +1,22 @@
#!/bin/bash #!/bin/bash
set -e set -euo pipefail
cd $(git rev-parse --show-toplevel)/ cd "$(git rev-parse --show-toplevel)/"
rm -rf ./build && mkdir build/ && cd build
export CC=$(which clang) CC=$(which clang)
export CXX=$(which clang++) export CC
cmake .. \ CXX=$(which clang++)
-G Ninja \ export CXX
-DCMAKE_LINKER_TYPE=MOLD \
-DENABLE_UNIT_TESTS=ON \ cmake \
-DENABLE_STATIC_ANALYSIS=ON \ -S . \
-DCMAKE_BUILD_TYPE=Release \ -B build \
-DCMAKE_CXX_FLAGS="-std=c++23 -stdlib=libc++" \ -G Ninja \
&& cmake --build . -j `nproc` -D CMAKE_LINKER_TYPE=MOLD \
-D ENABLE_UNIT_TESTS=ON \
-D ENABLE_STATIC_ANALYSIS=ON \
-D CMAKE_BUILD_TYPE=Release \
-D CMAKE_CXX_FLAGS="-std=c++23 -stdlib=libc++"
cmake --build . -j"$(nproc)"

View file

@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(git rev-parse --show-toplevel)/"
has_formatting_issues=0
while IFS= read -r -d '' file; do
echo "Checking format for $file"
if ! cmake-format --check "$file"; then
echo "❌ Formatting issue detected in $file"
has_formatting_issues=1
fi
done < <(find ./modules ./tools/cmake -type f \( -name 'CMakeLists.txt' -o -name '*.cmake' \) -print0)
if [ "$has_formatting_issues" -ne 0 ]; then
echo "✅ All files are properly formatted! Well done! ^~^"
fi
exit ${has_formatting_issues}

View file

@ -0,0 +1,19 @@
#!/bin/bash
set -euo pipefail
cd "$(git rev-parse --show-toplevel)/"
has_shellcheck_issues=0
while IFS= read -r -d '' file; do
echo "Checking shell script $file"
if ! shellcheck "$file"; then
echo "❌ Shellcheck issue detected in $file"
has_shellcheck_issues=1
fi
done < <(find ./modules ./tools -name '*.sh' -print0)
if [ "$has_shellcheck_issues" -eq 0 ]; then
echo "✅ All files are properly shellchecked! Well done! ^~^"
fi
exit ${has_shellcheck_issues}

View file

@ -0,0 +1,19 @@
#!/bin/bash
set -euo pipefail
cd "$(git rev-parse --show-toplevel)/"
has_fomatting_issues=0
while IFS= read -r -d '' file; do
echo "Checking format for $file"
if ! shfmt -i 4 -ci -d "$file"; then
echo "❌ Formatting issue detected in $file"
has_fomatting_issues=1
fi
done < <(find ./modules ./tools -name '*.sh' -print0)
if [ "$has_fomatting_issues" -eq 0 ]; then
echo "✅ All files are properly formatted! Well done! ^~^"
fi
exit ${has_fomatting_issues}

View file

@ -1,5 +1,5 @@
if(WIN32) if(WIN32)
add_compile_definitions(LIGHT_PLATFORM_WINDOWS) add_compile_definitions(LIGHT_PLATFORM_WINDOWS)
elseif(UNIX) elseif(UNIX)
add_compile_definitions(LIGHT_PLATFORM_LINUX) add_compile_definitions(LIGHT_PLATFORM_LINUX)
endif() endif()

View file

@ -1,157 +1,140 @@
function (add_library_module libname) function(add_library_module libname)
set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes") set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes")
file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}") file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}")
file(CREATE_LINK file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/public/"
"${CMAKE_CURRENT_SOURCE_DIR}/public/" "${PUBLIC_INCLUDE_DIR}/${libname}" SYMBOLIC)
"${PUBLIC_INCLUDE_DIR}/${libname}"
SYMBOLIC
)
if ("${ARGN}" STREQUAL "") # Header only library if("${ARGN}" STREQUAL "") # Header only library
message("Adding INTERFACE library ${libname}") message("Adding INTERFACE library ${libname}")
add_library(${libname} INTERFACE) add_library(${libname} INTERFACE)
target_include_directories(${libname} INTERFACE ${PUBLIC_INCLUDE_DIR}) target_include_directories(${libname} INTERFACE ${PUBLIC_INCLUDE_DIR})
target_link_libraries(${libname} INTERFACE std) target_link_libraries(${libname} INTERFACE std)
else () # Compiled library else() # Compiled library
set(source_files) set(source_files)
set(source_directory "${CMAKE_CURRENT_SOURCE_DIR}/private") set(source_directory "${CMAKE_CURRENT_SOURCE_DIR}/private")
foreach (source_file ${ARGN}) foreach(source_file ${ARGN})
list(APPEND source_files "${source_directory}/${source_file}") list(APPEND source_files "${source_directory}/${source_file}")
endforeach () endforeach()
message("Adding library ${libname} with source files: ${source_files}") message("Adding library ${libname} with source files: ${source_files}")
add_library(${libname} ${source_files}) add_library(${libname} ${source_files})
set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes") set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes")
file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}") file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}")
file(CREATE_LINK file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/private/"
"${CMAKE_CURRENT_SOURCE_DIR}/private/" "${PRIVATE_INCLUDE_DIR}/${libname}" SYMBOLIC)
"${PRIVATE_INCLUDE_DIR}/${libname}"
SYMBOLIC
)
target_include_directories(${libname} target_include_directories(
${libname}
PUBLIC ${PUBLIC_INCLUDE_DIR} PUBLIC ${PUBLIC_INCLUDE_DIR}
PRIVATE ${PRIVATE_INCLUDE_DIR} PRIVATE ${PRIVATE_INCLUDE_DIR})
)
target_link_libraries(${libname} PUBLIC std) target_link_libraries(${libname} PUBLIC std)
endif () endif()
endfunction () endfunction()
function (add_executable_module exename) function(add_executable_module exename)
set(source_files) set(source_files)
set(source_directory "${CMAKE_CURRENT_SOURCE_DIR}/private") set(source_directory "${CMAKE_CURRENT_SOURCE_DIR}/private")
foreach (source_file ${ARGN}) foreach(source_file ${ARGN})
list(APPEND source_files "${source_directory}/${source_file}") list(APPEND source_files "${source_directory}/${source_file}")
endforeach () endforeach()
message("Adding executable ${exename} with source files: ${source_files}") message("Adding executable ${exename} with source files: ${source_files}")
set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes") set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes")
file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}") file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}")
file(CREATE_LINK file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/public/"
"${CMAKE_CURRENT_SOURCE_DIR}/public/" "${PUBLIC_INCLUDE_DIR}/${exename}" SYMBOLIC)
"${PUBLIC_INCLUDE_DIR}/${exename}"
SYMBOLIC
)
set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes") set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes")
file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}") file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}")
file(CREATE_LINK file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/private/"
"${CMAKE_CURRENT_SOURCE_DIR}/private/" "${PRIVATE_INCLUDE_DIR}${exename}" SYMBOLIC)
"${PRIVATE_INCLUDE_DIR}${exename}"
SYMBOLIC
)
add_executable(${exename} ${source_files}) add_executable(${exename} ${source_files})
target_link_libraries(${exename} PRIVATE std) target_link_libraries(${exename} PRIVATE std)
target_include_directories(${exename} PRIVATE ${PUBLIC_INCLUDE_DIR} ${PRIVATE_INCLUDE_DIR}) target_include_directories(${exename} PRIVATE ${PUBLIC_INCLUDE_DIR}
endfunction () ${PRIVATE_INCLUDE_DIR})
endfunction()
function (add_test_module target_lib_name) function(add_test_module target_lib_name)
if (NOT ${ENABLE_UNIT_TESTS}) if(NOT ${ENABLE_UNIT_TESTS})
return() return()
endif () endif()
set(source_files) set(source_files)
set(source_directory "${CMAKE_CURRENT_SOURCE_DIR}/private") set(source_directory "${CMAKE_CURRENT_SOURCE_DIR}/private")
foreach (source_file ${ARGN}) foreach(source_file ${ARGN})
list(APPEND source_files "${source_directory}/${source_file}") list(APPEND source_files "${source_directory}/${source_file}")
endforeach () endforeach()
message("Adding test executable ${target_lib_name}_tests with source files: ${source_files}") message(
"Adding test executable ${target_lib_name}_tests with source files: ${source_files}"
)
set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes") set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes")
file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}") file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}")
file(CREATE_LINK file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/public/"
"${CMAKE_CURRENT_SOURCE_DIR}/public/" "${PUBLIC_INCLUDE_DIR}/${target_lib_name}" SYMBOLIC)
"${PUBLIC_INCLUDE_DIR}/${target_lib_name}"
SYMBOLIC
)
set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes") set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes")
file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}") file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}")
file(CREATE_LINK file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/private/"
"${CMAKE_CURRENT_SOURCE_DIR}/private/" "${PRIVATE_INCLUDE_DIR}/${target_lib_name}" SYMBOLIC)
"${PRIVATE_INCLUDE_DIR}/${target_lib_name}"
SYMBOLIC
)
add_executable(${target_lib_name}_tests ${source_files}) add_executable(${target_lib_name}_tests ${source_files})
target_link_libraries(${target_lib_name}_tests PRIVATE ${target_lib_name} std test) target_link_libraries(${target_lib_name}_tests PRIVATE ${target_lib_name}
target_include_directories(${target_lib_name}_tests std test)
target_include_directories(
${target_lib_name}_tests
PRIVATE ${PUBLIC_INCLUDE_DIR} PRIVATE ${PUBLIC_INCLUDE_DIR}
PRIVATE ${PRIVATE_INCLUDE_DIR} PRIVATE ${PRIVATE_INCLUDE_DIR})
) endfunction()
endfunction ()
function (add_fuzz_module target_lib_name) function(add_fuzz_module target_lib_name)
if (NOT ${ENABLE_FUZZ_TESTS}) if(NOT ${ENABLE_FUZZ_TESTS})
return() return()
endif () endif()
set(source_files) set(source_files)
set(source_directory "${CMAKE_CURRENT_SOURCE_DIR}/private") set(source_directory "${CMAKE_CURRENT_SOURCE_DIR}/private")
foreach (source_file ${ARGN}) foreach(source_file ${ARGN})
list(APPEND source_files "${source_directory}/${source_file}") list(APPEND source_files "${source_directory}/${source_file}")
endforeach () endforeach()
message("Adding fuzz executable ${target_lib_name}_fuzz with source files: ${source_files}") message(
"Adding fuzz executable ${target_lib_name}_fuzz with source files: ${source_files}"
)
set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes") set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes")
file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}") file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}")
file(CREATE_LINK file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/public/"
"${CMAKE_CURRENT_SOURCE_DIR}/public/" "${PUBLIC_INCLUDE_DIR}/${target_lib_name}" SYMBOLIC)
"${PUBLIC_INCLUDE_DIR}/${target_lib_name}"
SYMBOLIC
)
set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes") set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes")
file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}") file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}")
file(CREATE_LINK file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/private/"
"${CMAKE_CURRENT_SOURCE_DIR}/private/" "${PRIVATE_INCLUDE_DIR}/${target_lib_name}" SYMBOLIC)
"${PRIVATE_INCLUDE_DIR}/${target_lib_name}"
SYMBOLIC
)
add_executable(${target_lib_name}_fuzz ${source_files}) add_executable(${target_lib_name}_fuzz ${source_files})
target_link_libraries(${target_lib_name}_fuzz PRIVATE ${target_lib_name} std fuzz_test) target_link_libraries(${target_lib_name}_fuzz PRIVATE ${target_lib_name}
std fuzz_test)
target_link_options(${target_lib_name}_fuzz PRIVATE -fsanitize=fuzzer) target_link_options(${target_lib_name}_fuzz PRIVATE -fsanitize=fuzzer)
target_compile_options(${target_lib_name}_fuzz PRIVATE -fsanitize=fuzzer) target_compile_options(${target_lib_name}_fuzz PRIVATE -fsanitize=fuzzer)
target_include_directories(${target_lib_name}_fuzz target_include_directories(
${target_lib_name}_fuzz
PRIVATE ${PUBLIC_INCLUDE_DIR} PRIVATE ${PUBLIC_INCLUDE_DIR}
PRIVATE ${PRIVATE_INCLUDE_DIR} PRIVATE ${PRIVATE_INCLUDE_DIR})
) endfunction()
endfunction ()
function (add_option option help) function(add_option option help)
option(${option} ${help}) option(${option} ${help})
if (${option}) if(${option})
message(STATUS "${option}: ON") message(STATUS "${option}: ON")
add_compile_definitions(${option}=1) add_compile_definitions(${option}=1)
else () else()
message(STATUS "${option}: OFF") message(STATUS "${option}: OFF")
endif () endif()
endfunction () endfunction()

View file

@ -1,32 +1,41 @@
add_option(ENABLE_UNIT_TESTS "Enables the building of the unit test modules") add_option(ENABLE_UNIT_TESTS "Enables the building of the unit test modules")
add_option(ENABLE_FUZZ_TESTS "Enables the building of the fuzz test modules") add_option(ENABLE_FUZZ_TESTS "Enables the building of the fuzz test modules")
add_option(ENABLE_STATIC_ANALYSIS "Makes the clang-tidy checks mandatory for compilation") add_option(ENABLE_STATIC_ANALYSIS
add_option(ENABLE_LLVM_COVERAGE "Enables the code coverage instrumentation for clang") "Makes the clang-tidy checks mandatory for compilation")
add_option(ENABLE_LLVM_COVERAGE
"Enables the code coverage instrumentation for clang")
if (ENABLE_STATIC_ANALYSIS) if(ENABLE_STATIC_ANALYSIS)
set(CMAKE_CXX_CLANG_TIDY "clang-tidy;--warnings-as-errors=*;--allow-no-checks") set(CMAKE_CXX_CLANG_TIDY
endif () "clang-tidy;--warnings-as-errors=*;--allow-no-checks")
endif()
if(ENABLE_LLVM_COVERAGE) if(ENABLE_LLVM_COVERAGE)
include(CheckCXXSourceCompiles) include(CheckCXXSourceCompiles)
if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
message(FATAL_ERROR "ENABLE_LLVM_COVERAGE only supports the clang compiler") message(
endif () FATAL_ERROR "ENABLE_LLVM_COVERAGE only supports the clang compiler")
endif()
# Check for libc++ # Check for libc++
check_cxx_source_compiles(" check_cxx_source_compiles(
"
#include <string> #include <string>
#ifdef _LIBCPP_VERSION #ifdef _LIBCPP_VERSION
int main() { return 0; } int main() { return 0; }
#else #else
#error Not using libc++ #error Not using libc++
#endif #endif
" USING_LIBCXX) "
USING_LIBCXX)
if(NOT USING_LIBCXX) if(NOT USING_LIBCXX)
message(FATAL_ERROR "ENABLE_LLVM_COVERAGE requires libc++, please compile with -stdlib=libc++") message(
FATAL_ERROR
"ENABLE_LLVM_COVERAGE requires libc++, please compile with -stdlib=libc++"
)
endif() endif()
add_compile_options(-fprofile-instr-generate -fcoverage-mapping) add_compile_options(-fprofile-instr-generate -fcoverage-mapping)
add_link_options(-fprofile-instr-generate -fcoverage-mapping) add_link_options(-fprofile-instr-generate -fcoverage-mapping)
endif () endif()

View file

@ -1,36 +0,0 @@
#!/bin/bash
set -e
CI_DIR="$(git rev-parse --show-toplevel)/tools/ci/"
echo "===========[ amd64_clang ]==========="]
echo "==> Building amd64_clang_coverage..."
docker build -t amd64_clang_coverage -f $CI_DIR/amd64/clang/coverage.dockerfile .
echo "...DONE <=="
echo "==> Building amd64_clang_lsan..."
docker build -t amd64_clang_lsan -f $CI_DIR/amd64/clang/lsan.dockerfile .
echo "...DONE <=="
echo "==> Building image: amd64_clang_msan"
docker build -t amd64_clang_msan -f $CI_DIR/amd64/clang/msan.dockerfile .
echo "...DONE <=="
echo "==> Building image: clang_format"
docker build -t clang_format -f $CI_DIR/static_analysis/clang_format.dockerfile .
echo "...DONE <=="
echo "==> Building image: static_analysis"
docker build -t clang_tidy -f $CI_DIR/static_analysis/clang_tidy.dockerfile .
echo "...DONE <=="
echo "===========[ amd64_gcc ]==========="]
echo "==> Building image: amd64_gcc_unit_tests"
docker build -t amd64_gcc_unit_tests -f $CI_DIR/amd64/gcc/unit_tests.dockerfile .
echo "...DONE <=="
echo "==> Building image: amd64_gcc_valgrind"
docker build -t amd64_gcc_valgrind -f $CI_DIR/amd64/gcc/valgrind.dockerfile .
echo "...DONE <=="
echo "WOOOOOOOOOOOOOOOOH!!! DONE :D"