Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Generated C++ files are not deterministic, making ccache useless #7642

Open
ubruhin opened this issue Feb 15, 2025 · 1 comment
Open

Generated C++ files are not deterministic, making ccache useless #7642

ubruhin opened this issue Feb 15, 2025 · 1 comment
Labels
a:language-c++ C++ API, codegen, CMake build system (mS,mO) bug Something isn't working

Comments

@ubruhin
Copy link
Contributor

ubruhin commented Feb 15, 2025

Bug Description

The *.cpp files generated from *.slint files are not deterministic. Some struct member initialization code seems to have a random order (maybe coming from an unordered dict?). The problem is that this breaks ccache from being useful, thus wasting time during development.

Example of generated code:

// This file is auto-generated
#include "/home/urban/tmp/slint-cpp-template/build/app-window.h"

auto Button_root_1::init (const class SharedGlobals* globals,slint::cbindgen_private::ItemTreeWeak enclosing_component,uint32_t tree_index,uint32_t tree_index_of_first_child) -> void{
    auto self = this;
    self->self_weak = enclosing_component;
    self->globals = globals;
    this->tree_index_of_first_child = tree_index_of_first_child;
    self->tree_index = tree_index;
    self->root_1_accessible_action_default.set_handler(
                    [this]() {
                        [[maybe_unused]] auto self = this;
                        [&]{ [&]() -> void { if (self->native_3.checkable.get()) { self->native_3.checked.set((! self->native_3.checked.get())); } else { ; }}();self->native_3.clicked.call(); }();
                    });
    self->root_1_empty_2_layout_cache.set_binding([this]() {
                            [[maybe_unused]] auto self = this;
                            return slint::private_api::solve_box_layout([&](const auto &a_0, const auto &a_1, const auto &a_2, const auto &a_3, const auto &a_4){ slint::private_api::BoxLayoutData o{}; o.size = a_0; o.alignment = a_1; o.cells = a_2; o.spacing = a_3; o.padding = a_4; return o; }(self->root_1_width.get(), slint::cbindgen_private::LayoutAlignment::Stretch, slint::cbindgen_private::Slice<slint::cbindgen_private::BoxLayoutCellData>{ std::array<slint::cbindgen_private::BoxLayoutCellData, 1>{ slint::cbindgen_private::BoxLayoutCellData ( [&](const auto &a_0){ slint::private_api::BoxLayoutCellData o{}; o.constraint = a_0; return o; }(SLINT_GET_ITEM_VTABLE(NativeButtonVTable)->layout_info({SLINT_GET_ITEM_VTABLE(NativeButtonVTable), const_cast<slint::cbindgen_private::NativeButton*>(&self->native_3)}, slint::cbindgen_private::Orientation::Horizontal, &self->globals->window().window_handle())) ) }.data(), 1 }, 0, [&](const auto &a_0, const auto &a_1){ slint::private_api::Padding o{}; o.begin = a_0; o.end = a_1; return o; }(0, 0)),slint::cbindgen_private::Slice<int>{ std::array<int, 0>{  }.data(), 0 });
                        });
    self->root_1_empty_2_layoutinfo_h.set_binding([this]() {
                            [[maybe_unused]] auto self = this;
                            return slint::private_api::box_layout_info(slint::cbindgen_private::Slice<slint::cbindgen_private::BoxLayoutCellData>{ std::array<slint::cbindgen_private::BoxLayoutCellData, 1>{ slint::cbindgen_private::BoxLayoutCellData ( [&](const auto &a_0){ slint::private_api::BoxLayoutCellData o{}; o.constraint = a_0; return o; }(SLINT_GET_ITEM_VTABLE(NativeButtonVTable)->layout_info({SLINT_GET_ITEM_VTABLE(NativeButtonVTable), const_cast<slint::cbindgen_private::NativeButton*>(&self->native_3)}, slint::cbindgen_private::Orientation::Horizontal, &self->globals->window().window_handle())) ) }.data(), 1 },0,[&](const auto &a_0, const auto &a_1){ slint::private_api::Padding o{}; o.end = a_0; o.begin = a_1; return o; }(0, 0),slint::cbindgen_private::LayoutAlignment::Stretch);
                        });
    self->root_1_empty_2_layoutinfo_v.set_binding([this]() {
                            [[maybe_unused]] auto self = this;
                            return slint::private_api::box_layout_info_ortho(slint::cbindgen_private::Slice<slint::cbindgen_private::BoxLayoutCellData>{ std::array<slint::cbindgen_private::BoxLayoutCellData, 1>{ slint::cbindgen_private::BoxLayoutCellData ( [&](const auto &a_0){ slint::private_api::BoxLayoutCellData o{}; o.constraint = a_0; return o; }(SLINT_GET_ITEM_VTABLE(NativeButtonVTable)->layout_info({SLINT_GET_ITEM_VTABLE(NativeButtonVTable), const_cast<slint::cbindgen_private::NativeButton*>(&self->native_3)}, slint::cbindgen_private::Orientation::Vertical, &self->globals->window().window_handle())) ) }.data(), 1 },[&](const auto &a_0, const auto &a_1){ slint::private_api::Padding o{}; o.end = a_0; o.begin = a_1; return o; }(0, 0));
                        });
    self->native_3.checkable.set_binding([this]() {
                            [[maybe_unused]] auto self = this;
                            return false;
                        });
    self->native_3.enabled.set_binding([this]() {
                            [[maybe_unused]] auto self = this;
                            return true;
                        });
}

Lines 17 and 25 contain random content:

slint::private_api::BoxLayoutData o{}; o.size = a_0; o.alignment = a_1; o.cells = a_2; o.spacing = a_3; o.padding = a_4; return o;
slint::private_api::BoxLayoutData o{}; o.cells = a_0; o.spacing = a_1; o.padding = a_2; o.alignment = a_3; o.size = a_4; return o;

Another case are embedded resources in the generated *.h files, which seem to be random too:

Image

This is actually much worse as the generated header file will be included in many *.cpp files, causing ccache to fail on all those files too. In LibrePCB this currently leads to ~60 seconds of wasted time on every unnecessary rebuild.

I suspect this problem should be easy to fix, but would save a lot of time (and nerves).

Note that I can't say if there are more cases than the two mentioned, but I'd be happy to try again and report once these two are fixed.

Reproducible Code (if applicable)

Environment Details

  • Slint Version: Current master
  • Platform/OS: Linux
  • Programming Language: C++
  • Backend/Renderer:

Product Impact

No response

@ubruhin ubruhin added bug Something isn't working need triaging Issue that the owner of the area still need to triage labels Feb 15, 2025
@ogoffart ogoffart added the a:language-c++ C++ API, codegen, CMake build system (mS,mO) label Feb 15, 2025
@ogoffart
Copy link
Member

Thanks for the bug report. This should indeed be fixed. Probably some HashMap can be replaced by BTreeMap

@ogoffart ogoffart removed the need triaging Issue that the owner of the area still need to triage label Feb 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:language-c++ C++ API, codegen, CMake build system (mS,mO) bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants