Hacker News new | past | comments | ask | show | jobs | submit login
LeanQt – GUI is here, Widgets are near (github.com/rochus-keller)
132 points by Rochus on Nov 12, 2022 | hide | past | favorite | 50 comments



Are there tools to evaluate (imperfectly) the percent of a binary that actually gets used?

Like, run an application, run the watcher tool, then “walk the application” as best as possible and get an output: “35% of the binary was never read.” ?

What’s on my mind is evaluating the actual result of tools and methods for not including unnecessary things. I struggle with this in web land. Tree shaking and such does a wonderful job but I honestly don’t know how much of my bundle is still superfluous.


In an interview I can't find anymore a developer from Farbrausch said that they used such a method to optimize the .kkrieger demo and ended up having a bug in the main menu because while recording the coverage the user never scrolled to a certain main menu item. So once you scrolled there you couldn't scroll up anymore.


This reminds me of Naughty Dog overwriting standard library functions to gain more RAM for Crash Bandicoot. They would just “delete a function and see if the game still worked.”


See my comment in the same parent: https://news.ycombinator.com/item?id=33575452


You can run a profiler to determine which functions actually get called.

I'm reminded of a Smalltalk hack called Spoon. It required two systems: a host system running the full Smalltalk with all its classes, and a target system which had the barest possible Smalltalk environment. Any time an attempt was made to access a class that didn't exist on the target system, it would ask the host system for that class and if available, download it in serialized bytecode form and run it. This may have worked at method level granularity -- i.e., classes were only populated with methods that were actually used on the target system -- I'm not sure. But the result was the target system only contained enough of Smalltalk to actually run the program.


Read this classic article: https://fgiesen.wordpress.com/2012/04/08/metaprogramming-for...

The section called "A plan so insane, it might just work" describes what you mention.


Executable binaries are memory mapped into memory. So the pages are lazily loaded. So in theory you could study how many of the pages (4 KB each) of the binary were actually loaded to get a rough idea. Obviously not very precise since it has a 4 KB granularity.


I don't know, but one could implement this without too much difficulty as a wrapper around afl-showmap.


No, because you can't prove every piece of functionality has been executed.


True. What’s what I meant by (imperfectly). But perfect can’t be the enemy of good. There’s tremendous value in the data. You wouldn’t use it to just omit those bits. But it tells you a lot.


Run time "code coverage" would give you that.


That feels halting problem-esque.


It definitely is if you want a 100% correct and 100% certain answer. But if you accept 3 categories 1: this we know is used 2: this we know is not used, 3 this we don't know anything about, then it's doable.


Branches are a problem, depending on the number of parameters needed to be evaluated:

> Solving a constraint satisfaction problem on a finite domain is an NP-complete problem in general.

https://en.wikipedia.org/wiki/Complexity_of_constraint_satis...


But (2) requires knowing everything the binary will do. You can’t know what something won’t do without knowing what it will do.


You can do (2) if you can tolerate false positives. For example, if a symbol isn't referenced literally elsewhere in the binary, consider it unused, but add a configuration option to keep it in case it is referenced dynamically. The JVM world has been doing this for years with ProGuard.


  With the new gui, image and thirdparty modules, the uncompressed size of the source tree has grown to ~43 MB (10 MB zip compressed), with close to 3000 C/C++ files and more than 700 kSLOC.

  LeanQt is designed to build only the modules you actually need.

  ..The resulting source tree has less than 800 files and requires only ~11 MB (2.6 MB zip compressed), and perfectly works as a substitute of the full source tree in this guide; see the attached LeanQt_core_only.zip file.

Good. Not Alan Key 10kSLOC for the entire universe good. But certainly a step in the right direction.

I have searched high and low for something better, here is one rabbit hole: https://www.areweguiyet.com

Many people are trying, but frustratingly, even in 2022 you could do a lot worse than QT.

If you really want to get depressed read about the internals of Servo (rip) and how they tried to render text.

No wonder something that calls itself lean is still somehow hundreds of thousands of lines.


> 10kSLOC for the entire universe

It is the nature of idealists that they see the world idealized. Smalltalk-80 itself has nearly 30 kSLOC (the low-level code for the VM adds another 5 to 10 kSLOC); it's just more difficult to count, but I wrote tools which can do it (https://github.com/rochus-keller/Smalltalk/).


Not at all being idealistic, this is a hard problem.

But if we're really going to compare stuff.. Systemd alone is over 1 million lines. Probably X/Wayland as well. And the not-slim QT is probably going to end up over 1 million lines soon enough. There is a reason why this slim version exists.

That's at least two orders of magnitude difference in complexity. Maybe there's no getting around it but one has got to wonder whether things went horribly wrong somewhere.


Well, to be fair Qt Core, Gui and Widgets can du much more than ST-80; there are more platform abstractions, things like threads and unicode, more and more powerful widgets, more powerful font and 2d drawing, etc.; it's not just the same functionality with a different number of SLOC.

For the people who are comfortable with even less, it's worth comparing it to the 1991 Ceres Oberon System, which has less than 14 kSLOC including the compiler and TUI.


Oh they definitely went horribly wrong somewhere. And I suspect that shared sense is the reason so many alternative, niche, minimalist and retro projects are springing up. Personally I'm keeping a close eye on Haiku and SerenityOS as potential ports in the storm of ever-taller Jenga towers of dependencies and complexity...


I suspect they're referring to VPRI's STEPS research, not Smalltalk. (And it was a target of 20k, not 10k.)


> I have searched high and low for something better, here is one rabbit hole: https://www.areweguiyet.com

I'm very interested in the KDAB/cxx-qt path from that page: https://github.com/KDAB/cxx-qt

Once they get Arm & Android coverage, that'll be my go-to solution. Rust for all business logic and remote synchronization. Qt/QML for display with accessors into the Rust model.


There is also Slint: https://github.com/slint-ui/slint which is written entirely in rust. The UI is fairly similar to Qml. And you can have the logic in Rust or in C++.


> Not Alan Key 10kSLOC for the entire universe good.

if this was enough that's what we'd use though, no ?

While I like this project, I don't use half of the features it mentions in the supported features, and I use half of the features with no support planned so it's not an option for me ; i'd wager anyone not making todo apps has different set of requirements which leads to something like Qt which comes with everything. Simple example: no scripting support means pretty much that it's unuseable for any technical app e.g. in CAD/CAM or similar. No SQL means that it's unuseable for any kind of enterprisey CRUD client app.


> no scripting support ... No SQL

It's mostly about concentration of responsibilities, or as they say on Unix: "do one thing and do it well". Scripting support can easily be delegated to other projects (LeanQt inherits meta and introspection facilities of Qt which make dynamic bindings easy to accomplish, see e.g. this one for Lua: https://github.com/rochus-keller/NAF/tree/master/Script2); the same applies to database integration and other topics.


yes, and Qt SQL does one thing and does it well, which is getting SQL data in a format compatible with Qt's data model. You can do it by hand but you will just literally be reimplementing what is in QtSQL's module as soon as you want to display the result of queries in a table in your GUI. Same for scripting: the "meta and introspection facilities of Qt" are exactly what makes it possible to just call a member function or set a property of a C++ object from QJSEngine ; you can use another JS engine but you'll just end up reimplement all the glue code that is in QJSEngine, and for the sake of what? Having DLLs that start with another letter than Q?


> and Qt SQL does one thing and does it well

Well, that's not particularly what the Unix philosophy is up to, unless Qt Sql is a separate project.

> use another JS engine but you'll just end up reimplement all the glue code that is in QJSEngine

There is no necessity to have it in the same project. And there is still original Qt if you want to have it all.


I don't understand why being in the same or a separate project matters at all. It's an entirely theoretical thing. The only actual meaningful question is if it is in the same shared library or not (and it isn't). Your CPU does not care that function A comes from company A and function B from company A or B when executing, it'll be the same code.


See, I’d rather use Qt for the UI, rusqlite for data access, and Lua, Rhai, or an embedded JS engine for scripting.


Why, what is it going to bring you


Sounds like (based on this thread of comments) that you're arguing that this should be a framework, where all the boring stuff is already taken care of, for run-of-the-mill, enterprisey projects.

Some people are doing things that don't fit neatly in such frameworks, and when that happens, they're fighting against it rather than actually choosing what they want to code.

If it is so onerous that not having QtSQL is a deal killer, then it sounds like Qt has some weird problems with how it's API is designed preventing it from being flexible. Otherwise, if it it easy to load your own data in to Qt from whatever source, SQL or not, then not having QtSQL is fine, it just means an extra hour of coding and a little extra boilerplate, whoopdeedoo.


Looks useful!

> LeanQt is a stripped-down Qt version which includes the essential features and is easy to build from source and to integrate with an application.


I wonder how long it takes to compile on an RPi. I tried it once with the full Qt build and gave up :) Of course, I should have cross-compiled but I guess I didn't want it enough.


Takes about 10 minutes to build on a 3 GHz i7-2600K. So maybe an hour or two on an RPi?

The impressive thing is that the build instructions are like 3 lines long, and actually result in a working build. No drama, no specific compiler versions required, no CMake or autotools or other external crap, no dependency hell... just lots of cl.exe invocations scrolling by, followed by a command prompt.


I just tried on a Raspberry Pi Model 3B, BCM2835 ARMv7, 4 cores, Raspbian Linux 4.9.59-v7+ armv7l; "time ./lua build.lua ../LeanQt -P HAVE_GUI" reported 65 minutes (rounded).


Compiling qt on the pi is an overnight sort of thing. I think it took 12+ hours when I did it on a pi4. Thankfully, once it's compiled, you don't have to compile again until you next version bump.


Why compiling on the pi, instead of cross compiling?


Compiling Qt with the right switches is hard enough, before you throw in cross compiling on top. Since you only need to compile a new Qt release once every few months, why optimize the process? Just kick it off and go to sleep. I don't modify core Qt libraries ever. If I was iterating on Qt itself, I would definitely figure out cross compiling. Anyways if you come up with such a working cross-compile recipe, you should post it some place.


Qt cross compiles fine with Scratchbox2.

I think people working on cross compilation are wasting their time. They are trying to fix it "properly", separating build time dependency and run time dependency, because host system can't run cross compiled target binary. The obvious solution (what Scratchbox2 does) is for host system to run cross compiled target binary, instead of trying to "fix" the build system.


To be fair, I don't think I've ever gotten cross-compiling to work, beyond a "Hello World".

Especially since many ARM platforms are stuck on old libcs that are difficult to support.


Nice to see. I remember a while back trying to compile an open source app built with Qt. I gave up on it when I got to the part where I had to sacrifice a young male goat. Referring in particular to this: "Unfortunately, there has been a certain proliferation over the years where Qt has been bloated with all sorts of features with questionable value. The standard binary installation of Qt swallows several gigabytes and requires a login to a commercial company server, which discourages many people."


You should see the emails you get as a commercial customer. They're currently busy adding on advertising hooks and remote analytics.


An interesting idea. I would love to see Python bindings, right now seems to be Cpp only.


It's just normal Qt with a bunch of features removed. Modifying one of the existing Python Qt bindings to build against this should be relatively straightforward.


Would love the same thing with QML and QtQuick modules!


Novarnitgoldarnitfritzeb, I said that 'Widgets are n[clang]'


No charts?


As soon as the Graphics View Framework is migrated (currently, not even widgets are migrated), you should be able to compile the Qt Charts source code with LeanQt, because the latter maintains compatibility with most of the Qt API. Whether this makes sense or not is a different question, since there is still original Qt which can install these things all at once if needed.


Charts module is GPL, if you care about commercial usage. The core is LGPL which isn't too bad to comply with for commercial products.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: