Compare commits

..

15 commits
v0.0.1 ... main

Author SHA1 Message Date
8e48a3992b
ci: remove debug comand
Some checks are pending
continuous-integration/drone/push Build is running
2025-09-14 23:26:41 +03:30
6f007c47ed
feat: windows support for surface module
Some checks failed
continuous-integration/drone/push Build is failing
2025-09-10 15:24:42 +03:30
9b0acc1cc3
ci: modify amd64/gcc/valgrind script
Some checks failed
continuous-integration/drone/push Build is failing
2025-09-10 15:18:26 +03:30
ad5d961d33
ci: set DEBUGINFO_URLS in amd64/gcc/valgrind script
Some checks failed
continuous-integration/drone/push Build is failing
2025-09-10 15:06:49 +03:30
38e1131513
ci: fix silly mistake on amd64/gcc/unit_tests.sh
Some checks failed
continuous-integration/drone/push Build is failing
2025-09-10 14:31:02 +03:30
3564400000
ci: fix gcc unit tests script
Some checks failed
continuous-integration/drone/push Build is failing
2025-09-10 14:26:08 +03:30
4d0a7f9b45
fix: compilation error on gcc
Some checks failed
continuous-integration/drone/push Build is failing
2025-09-10 13:16:14 +03:30
961111c5da
fix: some tests failing due to repeated glfwInit/glfwTerminate
Some checks failed
continuous-integration/drone/push Build is failing
2025-09-09 17:19:31 +03:30
ab44e4da0a
ci: add x-virtual-frame-buffer to lsan & msan scripts
Some checks failed
continuous-integration/drone/push Build is failing
2025-09-09 13:42:22 +03:30
55eb785682
ci: made coverage.sh start virtual x server
Some checks failed
continuous-integration/drone/push Build is failing
2025-09-07 20:27:46 +03:30
f9c5057146
ci: revert setting display env var manually
Some checks reported errors
continuous-integration/drone/push Build was killed
2025-09-07 19:47:16 +03:30
4a7a220af8
fix: missing display env var
Some checks reported errors
continuous-integration/drone/push Build was killed
2025-09-05 12:21:44 +03:30
a43243ca3f
build: differentiate between test types
Some checks reported errors
continuous-integration/drone/push Build was killed
fix: #41
2025-09-05 12:15:40 +03:30
5d30a56e22
revert: uncommenting the whole .drone.yml
Some checks reported errors
continuous-integration/drone/push Build was killed
2025-09-05 11:36:29 +03:30
51e044065a ci: documentation pipelines (#39)
All checks were successful
continuous-integration/drone/push Build is passing
fix: #36
fix: #37
Co-authored-by: light7734 <light7734@tuta.io>
Co-committed-by: light7734 <light7734@tuta.io>
2025-08-23 11:36:02 +00:00
15 changed files with 517 additions and 119 deletions

View file

@ -1,94 +1,94 @@
# --- ---
# kind: pipeline kind: pipeline
# type: exec type: exec
# name: amd64 — msvc name: amd64 — msvc
# trigger: trigger:
# branch: branch:
# - main - main
# platform: platform:
# os: windows os: windows
# arch: amd64 arch: amd64
#
# steps:
# - name: unit tests
# shell: powershell
# commands:
# - ./tools/ci/amd64/msvc/unit_tests.ps1
#
# ---
# kind: pipeline
# type: docker
# name: amd64 — gcc
# trigger:
# branch:
# - main
#
# steps:
# - name: unit tests
# image: amd64_gcc_unit_tests:latest
# pull: if-not-exists
# commands:
# - ./tools/ci/amd64/gcc/unit_tests.sh
#
# - name: valgrind
# image: amd64_gcc_valgrind:latest
# pull: if-not-exists
# commands:
# - ./tools/ci/amd64/gcc/valgrind.sh
#
# ---
# kind: pipeline
# type: docker
# name: amd64 — clang
# trigger:
# branch:
# - main
#
# steps:
# - name: code coverage
# image: amd64_clang_coverage:latest
# pull: if-not-exists
# environment:
# CODECOV_TOKEN:
# from_secret: CODECOV_TOKEN
# commands:
# - ./tools/ci/amd64/clang/coverage.sh
#
# - name: leak sanitizer
# image: amd64_clang_lsan:latest
# pull: if-not-exists
# commands:
# - ./tools/ci/amd64/clang/lsan.sh
#
# - name: memory sanitizer
# image: amd64_clang_msan:latest
# pull: if-not-exists
# commands:
# - ./tools/ci/amd64/clang/msan.sh
#
# ---
# kind: pipeline
# type: docker
# name: static analysis
# trigger:
# branch:
# - main
#
# steps:
# - name: clang tidy
# image: clang_tidy:latest
# pull: if-not-exists
# privileged: true
# commands:
# - ./tools/ci/static_analysis/clang_tidy.sh
#
# - name: clang format
# image: clang_format:latest
# pull: if-not-exists
# commands:
# - ./tools/ci/static_analysis/clang_format.sh
# --- steps:
- name: unit tests
shell: powershell
commands:
- ./tools/ci/amd64/msvc/unit_tests.ps1
---
kind: pipeline
type: docker
name: amd64 — gcc
trigger:
branch:
- main
steps:
- name: unit tests
image: amd64_gcc_unit_tests:latest
pull: if-not-exists
commands:
- ./tools/ci/amd64/gcc/unit_tests.sh
- name: valgrind
image: amd64_gcc_valgrind:latest
pull: if-not-exists
commands:
- ./tools/ci/amd64/gcc/valgrind.sh
---
kind: pipeline
type: docker
name: amd64 — clang
trigger:
branch:
- main
steps:
- name: code coverage
image: amd64_clang_coverage:latest
pull: if-not-exists
environment:
CODECOV_TOKEN:
from_secret: CODECOV_TOKEN
commands:
- ./tools/ci/amd64/clang/coverage.sh
- name: leak sanitizer
image: amd64_clang_lsan:latest
pull: if-not-exists
commands:
- ./tools/ci/amd64/clang/lsan.sh
- name: memory sanitizer
image: amd64_clang_msan:latest
pull: if-not-exists
commands:
- ./tools/ci/amd64/clang/msan.sh
---
kind: pipeline
type: docker
name: static analysis
trigger:
branch:
- main
steps:
- name: clang tidy
image: clang_tidy:latest
pull: if-not-exists
privileged: true
commands:
- ./tools/ci/static_analysis/clang_tidy.sh
- name: clang format
image: clang_format:latest
pull: if-not-exists
commands:
- ./tools/ci/static_analysis/clang_format.sh
---
kind: pipeline kind: pipeline
type: docker type: docker
name: documentation — development name: documentation — development
@ -129,7 +129,6 @@ steps:
image: documentation:latest image: documentation:latest
pull: if-not-exists pull: if-not-exists
commands: commands:
- pwd
- cd docs - cd docs
- mkdir generated - mkdir generated
- touch generated/changelogs.rst - touch generated/changelogs.rst

View file

@ -8,7 +8,8 @@ include(${CMAKE_DIR}/functions.cmake)
include(${CMAKE_DIR}/definitions.cmake) include(${CMAKE_DIR}/definitions.cmake)
include(${CMAKE_DIR}/dependencies.cmake) include(${CMAKE_DIR}/dependencies.cmake)
add_option(ENABLE_TESTS "Enables the building of the 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_STATIC_ANALYSIS "Makes clang-tidy checks mandatory for compilation") add_option(ENABLE_STATIC_ANALYSIS "Makes clang-tidy checks mandatory for compilation")
if (ENABLE_STATIC_ANALYSIS) if (ENABLE_STATIC_ANALYSIS)

View file

@ -11,7 +11,8 @@ class LightRecipe(ConanFile):
generators = "CMakeDeps" generators = "CMakeDeps"
options = { options = {
"enable_tests": [True, False], "enable_unit_tests": [True, False],
"enable_fuzz_tests": [True, False],
"enable_llvm_coverage": [True, False], "enable_llvm_coverage": [True, False],
"enable_static_analysis": [True, False], "enable_static_analysis": [True, False],
"use_mold": [True, False], "use_mold": [True, False],
@ -19,7 +20,8 @@ class LightRecipe(ConanFile):
} }
default_options = { default_options = {
"enable_tests": True, "enable_unit_tests": True,
"enable_fuzz_tests": False,
"enable_llvm_coverage": False, "enable_llvm_coverage": False,
"enable_static_analysis": False, "enable_static_analysis": False,
"use_mold": False, "use_mold": False,
@ -46,7 +48,8 @@ class LightRecipe(ConanFile):
tc.cache_variables["CMAKE_LINKER_TYPE"] = "MOLD" tc.cache_variables["CMAKE_LINKER_TYPE"] = "MOLD"
tc.cache_variables["CMAKE_EXPORT_COMPILE_COMMANDS"] = self.options.export_compile_commands tc.cache_variables["CMAKE_EXPORT_COMPILE_COMMANDS"] = self.options.export_compile_commands
tc.cache_variables["ENABLE_TESTS"] = self.options.enable_tests tc.cache_variables["ENABLE_UNIT_TESTS"] = self.options.enable_unit_tests
tc.cache_variables["ENABLE_FUZZ_TESTS"] = self.options.enable_fuzz_tests
tc.cache_variables["ENABLE_LLVM_COVERAGE"] = self.options.enable_llvm_coverage tc.cache_variables["ENABLE_LLVM_COVERAGE"] = self.options.enable_llvm_coverage
tc.cache_variables["ENABLE_STATIC_ANALYSIS"] = self.options.enable_static_analysis tc.cache_variables["ENABLE_STATIC_ANALYSIS"] = self.options.enable_static_analysis

View file

@ -1,6 +1,7 @@
if (NOT WIN32) if (NOT WIN32)
add_library_module(surface linux/system.cpp) add_library_module(surface linux/system.cpp)
else() else(WIN32)
add_library_module(surface windows/system.cpp)
endif() endif()
target_link_libraries(surface PUBLIC target_link_libraries(surface PUBLIC

View file

@ -5,6 +5,41 @@
namespace lt::surface { namespace lt::surface {
// This class is to ensure glfwInit/glfwTerminate is called only once and exactly when needed during
// entire application runtime
class GlfwSingleton
{
public:
[[nodiscard]] static auto get() -> GlfwSingleton &
{
static auto instance = GlfwSingleton {};
return instance;
}
GlfwSingleton(GlfwSingleton &&) = delete;
GlfwSingleton(const GlfwSingleton &) = delete;
auto operator=(GlfwSingleton &&) -> GlfwSingleton & = delete;
auto operator=(const GlfwSingleton &) -> GlfwSingleton & = delete;
private:
GlfwSingleton()
{
log_inf("Initializing glfw...");
ensure(glfwInit(), "Failed to initialize 'glfw'");
log_inf("...Finished");
}
~GlfwSingleton()
{
log_inf("Terminating glfw...");
glfwTerminate();
log_inf("...Finished");
}
};
void glfw_error_callbac(int32_t code, const char *description) void glfw_error_callbac(int32_t code, const char *description)
{ {
log_err("GLFW ERROR: {} -> {}", code, description); log_err("GLFW ERROR: {} -> {}", code, description);
@ -97,13 +132,12 @@ void bind_glfw_events(GLFWwindow *handle)
}); });
} }
void init_glfw() {};
System::System(Ref<ecs::Registry> registry): m_registry(std::move(registry)) System::System(Ref<ecs::Registry> registry): m_registry(std::move(registry))
{ {
glfwSetErrorCallback(&glfw_error_callbac); glfwSetErrorCallback(&glfw_error_callbac);
ensure(glfwInit(), "Failed to initialize 'glfw'");
// will call `glfwInit()` only the first time
auto &glfw_instance = GlfwSingleton::get();
ensure(m_registry, "Failed to initialize surface system: null registry"); ensure(m_registry, "Failed to initialize surface system: null registry");
ensure( ensure(
@ -142,8 +176,6 @@ System::~System()
m_registry->view<SurfaceComponent>().each([&](const entt::entity entity, SurfaceComponent &) { m_registry->view<SurfaceComponent>().each([&](const entt::entity entity, SurfaceComponent &) {
m_registry->get_entt_registry().remove<SurfaceComponent>(entity); m_registry->get_entt_registry().remove<SurfaceComponent>(entity);
}); });
glfwTerminate();
} }
void System::on_surface_construct(entt::registry &registry, entt::entity entity) void System::on_surface_construct(entt::registry &registry, entt::entity entity)

View file

@ -0,0 +1,324 @@
#define GLFW_EXPOSE_NATIVE_X11
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#include <surface/system.hpp>
namespace lt::surface {
// This class is to ensure glfwInit/glfwTerminate is called only once and exactly when needed during
// entire application runtime
class GlfwSingleton
{
public:
[[nodiscard]] static auto get() -> GlfwSingleton &
{
static auto instance = GlfwSingleton {};
return instance;
}
GlfwSingleton(GlfwSingleton &&) = delete;
GlfwSingleton(const GlfwSingleton &) = delete;
auto operator=(GlfwSingleton &&) -> GlfwSingleton & = delete;
auto operator=(const GlfwSingleton &) -> GlfwSingleton & = delete;
private:
GlfwSingleton()
{
log_inf("Initializing glfw...");
ensure(glfwInit(), "Failed to initialize 'glfw'");
log_inf("...Finished");
}
~GlfwSingleton()
{
log_inf("Terminating glfw...");
glfwTerminate();
log_inf("...Finished");
}
};
void glfw_error_callbac(int32_t code, const char *description)
{
log_err("GLFW ERROR: {} -> {}", code, description);
}
void handle_event(GLFWwindow *window, const SurfaceComponent::Event &event)
{
auto &callbacks = *static_cast<std::vector<SurfaceComponent::EventCallback> *>(
glfwGetWindowUserPointer(window)
);
for (auto &callback : callbacks)
{
if (callback(event))
{
return;
}
}
}
void bind_glfw_events(GLFWwindow *handle)
{
glfwSetWindowPosCallback(handle, [](GLFWwindow *window, int xpos, int ypos) {
handle_event(window, MovedEvent { xpos, ypos });
});
glfwSetWindowSizeCallback(handle, [](GLFWwindow *window, int width, int height) {
handle_event(
window,
ResizedEvent { static_cast<uint32_t>(width), static_cast<uint32_t>(height) }
);
});
glfwSetWindowCloseCallback(handle, [](GLFWwindow *window) {
handle_event(window, ClosedEvent {});
});
glfwSetWindowFocusCallback(handle, [](GLFWwindow *window, int focus) {
if (focus == GLFW_TRUE)
{
handle_event(window, GainFocusEvent {});
}
else
{
handle_event(window, LostFocusEvent {});
}
});
glfwSetCursorPosCallback(handle, [](GLFWwindow *window, double xpos, double ypos) {
handle_event(
window,
MouseMovedEvent { static_cast<float>(xpos), static_cast<float>(ypos) }
);
});
glfwSetMouseButtonCallback(
handle,
[](GLFWwindow *window, int button, int action, int /*mods*/) {
if (action == GLFW_PRESS)
{
handle_event(window, ButtonPressedEvent { button });
}
else if (action == GLFW_RELEASE)
{
handle_event(window, ButtonReleasedEvent { button });
}
}
);
glfwSetScrollCallback(handle, [](GLFWwindow *window, double /*xoffset*/, double yoffset) {
handle_event(window, WheelScrolledEvent { static_cast<float>(yoffset) });
});
glfwSetKeyCallback(
handle,
[](GLFWwindow *window, int key, int /*scancode*/, int action, int /*mods*/) {
if (action == GLFW_PRESS)
{
handle_event(window, KeyPressedEvent { key });
}
else if (action == GLFW_RELEASE)
{
handle_event(window, KeyReleasedEvent { key });
}
}
);
glfwSetCharCallback(handle, [](GLFWwindow *window, unsigned int character) {
handle_event(window, KeySetCharEvent { character });
});
}
System::System(Ref<ecs::Registry> registry): m_registry(std::move(registry))
{
glfwSetErrorCallback(&glfw_error_callbac);
// will call `glfwInit()` only the first time
auto &glfw_instance = GlfwSingleton::get();
ensure(m_registry, "Failed to initialize surface system: null registry");
ensure(
m_registry->view<SurfaceComponent>().size() == 0,
"Failed to initialize surface system: registry has surface component(s)"
);
m_registry->get_entt_registry()
.on_construct<SurfaceComponent>()
.connect<&System::on_surface_construct>(this);
m_registry->get_entt_registry()
.on_update<SurfaceComponent>()
.connect<&System::on_surface_update>(this);
m_registry->get_entt_registry()
.on_destroy<SurfaceComponent>()
.connect<&System::on_surface_destroy>(this);
}
System::~System()
{
m_registry->get_entt_registry()
.on_construct<SurfaceComponent>()
.disconnect<&System::on_surface_construct>(this);
m_registry->get_entt_registry()
.on_update<SurfaceComponent>()
.connect<&System::on_surface_update>(this);
m_registry->get_entt_registry()
.on_destroy<SurfaceComponent>()
.disconnect<&System::on_surface_destroy>(this);
m_registry->view<SurfaceComponent>().each([&](const entt::entity entity, SurfaceComponent &) {
m_registry->get_entt_registry().remove<SurfaceComponent>(entity);
});
}
void System::on_surface_construct(entt::registry &registry, entt::entity entity)
{
try
{
auto &surface = registry.get<SurfaceComponent>(entity);
ensure_component_sanity(surface);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
surface.m_glfw_handle = glfwCreateWindow(
static_cast<int>(surface.get_resolution().x),
static_cast<int>(surface.get_resolution().y),
surface.get_title().begin(),
nullptr,
nullptr
);
ensure(surface.m_glfw_handle, "Failed to create 'GLFWwindow'");
glfwSetWindowUserPointer(surface.m_glfw_handle, &surface.m_event_callbacks);
surface.m_native_handle = glfwGetX11Window(surface.m_glfw_handle);
bind_glfw_events(surface.m_glfw_handle);
}
catch (...)
{
registry.remove<SurfaceComponent>(entity);
throw;
}
}
void System::on_surface_update(entt::registry &registry, entt::entity entity)
{
auto &surface = registry.get<SurfaceComponent>(entity);
glfwSetWindowUserPointer(surface.m_glfw_handle, &surface.m_event_callbacks);
}
void System::on_surface_destroy(entt::registry &registry, entt::entity entity)
{
auto &surface = registry.get<SurfaceComponent>(entity);
if (surface.m_glfw_handle)
{
glfwDestroyWindow(surface.m_glfw_handle);
}
}
void System::set_title(ecs::Entity entity, std::string_view new_title)
{
auto &surface = entity.get_component<SurfaceComponent>();
surface.m_title = new_title;
glfwSetWindowTitle(surface.m_glfw_handle, surface.m_title.c_str());
}
auto System::tick() -> bool
{
m_registry->view<SurfaceComponent>().each([](SurfaceComponent &surface) {
glfwSwapBuffers(surface.m_glfw_handle);
});
glfwPollEvents();
return false;
}
void System::set_size(ecs::Entity surface_entity, const math::uvec2 &new_size)
{
auto &surface = surface_entity.get_component<SurfaceComponent>();
surface.m_resolution = new_size;
glfwSetWindowSize(
surface.m_glfw_handle,
static_cast<int>(new_size.x),
static_cast<int>(new_size.y)
);
}
void System::set_v_sync(ecs::Entity surface_entity, bool vsync)
{
auto &surface = surface_entity.get_component<SurfaceComponent>();
surface.m_vsync = vsync;
glfwSwapInterval(vsync);
}
void System::set_visibility(ecs::Entity surface_entity, bool visible)
{
auto &surface = surface_entity.get_component<SurfaceComponent>();
surface.m_visible = visible;
if (visible)
{
glfwShowWindow(surface.m_glfw_handle);
}
else
{
glfwHideWindow(surface.m_glfw_handle);
}
}
void System::add_event_listener(
ecs::Entity surface_entity,
SurfaceComponent::EventCallback callback
)
{
auto &surface = surface_entity.get_component<SurfaceComponent>();
surface.m_event_callbacks.emplace_back(std::move(callback));
}
void System::ensure_component_sanity(const SurfaceComponent &component)
{
auto [width, height] = component.get_resolution();
ensure(width != 0u, "Received bad values for surface component: width({}) == 0", width);
ensure(height != 0u, "Received bad values for surface component: height({}) == 0", height);
ensure(
width < SurfaceComponent::max_dimension,
"Received bad values for surface component: width({}) > max_dimension({})",
width,
SurfaceComponent::max_dimension
);
ensure(
height < SurfaceComponent::max_dimension,
"Received bad values for surface component: height({}) > max_dimension({})",
height,
SurfaceComponent::max_dimension
);
ensure(
component.get_title().size() < SurfaceComponent::max_title_length,
"Received bad values for surface component: title.size({}) > max_title_length({})",
component.get_title().size(),
SurfaceComponent::max_title_length
);
}
} // namespace lt::surface
namespace lt {
} // namespace lt

View file

@ -119,21 +119,21 @@ struct Case
struct TestSuite struct TestSuite
{ {
template<class TSuite> template<class TSuite>
constexpr TestSuite(TSuite suite) constexpr TestSuite(TSuite body)
{ {
#ifndef LIGHT_SKIP_TESTS #ifndef LIGHT_SKIP_TESTS
details::Registry::register_suite(+suite); details::Registry::register_suite(+body);
#endif #endif
} }
}; };
struct TestFuzzHarness struct TestFuzzHarness
{ {
template<class TestFuzzHarness> template<class TestFuzzHarnessBody>
constexpr TestFuzzHarness(TestFuzzHarness suite) constexpr TestFuzzHarness(TestFuzzHarnessBody body)
{ {
#ifndef LIGHT_SKIP_FUZZ_TESTS #ifndef LIGHT_SKIP_FUZZ_TESTS
details::Registry::register_fuzz_harness(+suite); details::Registry::register_fuzz_harness(+body);
#endif #endif
} }
}; };

View file

@ -21,7 +21,8 @@ RUN pacman -S --noconfirm --disable-download-timeout \
curl \ curl \
wget \ wget \
zlib \ zlib \
libc++ libc++ \
libinput
RUN pip install --no-cache-dir --break-system-packages conan gitpython \ RUN pip install --no-cache-dir --break-system-packages conan gitpython \
&& conan profile detect && conan profile detect
@ -37,7 +38,7 @@ RUN pip --version \
&& llvm-cov --version && llvm-cov --version
RUN git clone 'https://git.light7734.com/light7734/light.git' \ RUN git clone 'https://git.light7734.com/light7734/light.git' \
&& cd light; git checkout 'ci/code_cov' \ && cd light \
&& conan build . \ && conan build . \
-c tools.system.package_manager:mode=install \ -c tools.system.package_manager:mode=install \
-c tools.cmake.cmaketoolchain:generator=Ninja \ -c tools.cmake.cmaketoolchain:generator=Ninja \

View file

@ -4,6 +4,9 @@ set -e
cd $(git rev-parse --show-toplevel)/ cd $(git rev-parse --show-toplevel)/
rm -rf ./build rm -rf ./build
Xvfb :99 -screen 0 1024x768x16 &
export DISPLAY=:99
conan build . \ conan build . \
-c tools.system.package_manager:mode=install \ -c tools.system.package_manager:mode=install \
-c tools.cmake.cmaketoolchain:generator=Ninja \ -c tools.cmake.cmaketoolchain:generator=Ninja \

View file

@ -4,6 +4,9 @@ set -e
cd $(git rev-parse --show-toplevel)/ cd $(git rev-parse --show-toplevel)/
rm -rf ./build rm -rf ./build
Xvfb :99 -screen 0 1024x768x16 &
export DISPLAY=:99
conan build . \ conan build . \
-c tools.system.package_manager:mode=install \ -c tools.system.package_manager:mode=install \
-c tools.cmake.cmaketoolchain:generator=Ninja \ -c tools.cmake.cmaketoolchain:generator=Ninja \

View file

@ -4,6 +4,9 @@ set -e
cd $(git rev-parse --show-toplevel)/ cd $(git rev-parse --show-toplevel)/
rm -rf ./build rm -rf ./build
Xvfb :99 -screen 0 1024x768x16 &
export DISPLAY=:99
conan build . \ conan build . \
-c tools.system.package_manager:mode=install \ -c tools.system.package_manager:mode=install \
-c tools.cmake.cmaketoolchain:generator=Ninja \ -c tools.cmake.cmaketoolchain:generator=Ninja \

View file

@ -4,12 +4,26 @@ set -e
cd $(git rev-parse --show-toplevel)/ cd $(git rev-parse --show-toplevel)/
rm -rf ./build rm -rf ./build
Xvfb :99 -screen 0 1024x768x16 &
export DISPLAY=:99
export CXX=$(which g++)
export CC=$(which gcc)
conan build . \ conan build . \
-c tools.system.package_manager:mode=install \ -c tools.system.package_manager:mode=install \
-c tools.cmake.cmaketoolchain:generator=Ninja \ -c tools.cmake.cmaketoolchain:generator=Ninja \
-c tools.build:compiler_executables='{"c": "gcc", "cpp": "g++"}' \
-s build_type=Release \ -s build_type=Release \
-o enable_tests=True \ -s compiler=gcc \
-s compiler.version=15 \
-s compiler.libcxx=libstdc++ \
-o use_mold=True \ -o use_mold=True \
-o enable_unit_tests=True \
-o enable_fuzz_tests=False \
-o enable_llvm_coverage=False \
-o enable_static_analysis=False \
-o use_mold=True \
-o export_compile_commands=False \
--build=missing --build=missing
for test in $(find ./build -type f -name '*_tests' -executable); do for test in $(find ./build -type f -name '*_tests' -executable); do

View file

@ -1,5 +1,7 @@
#!/bin/bash #!/bin/bash
export DEBUGINFOD_URLS="https://debuginfod.archlinux.org/"
set -e set -e
cd $(git rev-parse --show-toplevel)/ cd $(git rev-parse --show-toplevel)/
rm -rf ./build rm -rf ./build
@ -8,8 +10,19 @@ conan build . \
-c tools.system.package_manager:mode=install \ -c tools.system.package_manager:mode=install \
-c tools.cmake.cmaketoolchain:generator=Ninja \ -c tools.cmake.cmaketoolchain:generator=Ninja \
-s build_type=Release \ -s build_type=Release \
-o enable_tests=True \ -o enable_unit_tests=True \
-o use_mold=True \ -o use_mold=True \
--build=missing --build=missing
find ./build -type f -name "*_tests" -executable | xargs -I {} bash -c 'valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=255 {}' || exit 1
for test in $(find ./build -type f -name '*_tests' -executable); do
echo "Running $test"
valgrind \
--leak-check=full \
--show-leak-kinds=all \
--track-origins=yes \
--verbose \
--error-exitcode=255 \
${test} || exit 1
done

View file

@ -14,6 +14,7 @@ conan build . \
-c tools.cmake.cmaketoolchain:generator=Ninja \ -c tools.cmake.cmaketoolchain:generator=Ninja \
-s build_type=Release \ -s build_type=Release \
-o enable_static_analysis=True \ -o enable_static_analysis=True \
-o enable_tests=True \ -o enable_unit_tests=True \
-o enable_fuzz_tests=True \
-o use_mold=True \ -o use_mold=True \
--build=missing --build=missing

View file

@ -78,7 +78,7 @@ function (add_executable_module exename)
endfunction () endfunction ()
function (add_test_module target_lib_name) function (add_test_module target_lib_name)
if (NOT ${ENABLE_TESTS}) if (NOT ${ENABLE_UNIT_TESTS})
return() return()
endif () endif ()
@ -114,7 +114,7 @@ function (add_test_module target_lib_name)
endfunction () endfunction ()
function (add_fuzz_module target_lib_name) function (add_fuzz_module target_lib_name)
if (NOT ${ENABLE_TESTS}) if (NOT ${ENABLE_FUZZ_TESTS})
return() return()
endif () endif ()