Thursday, October 8, 2026

CMake: Making Hard Things EasyAt CppCon 2026, I gave a talk called “CMake: Making Hard Things Easy” about how CMake handles build-system complexity so developers can focus on their software. This article shares practical takeaways from that talk. We started CMake for ITK 26 years ago. Researchers needed to use medical image segmentation and registration algorithms across different platforms without becoming experts in every compiler and linker. The idea was to capture that expertise in the build system so everyone could benefit from it. I wrote about those early days in Happy Birthday CMake!. Today, we take it for granted that we have build tools that can create static or shared libraries and link applications to them on Linux, Windows, or macOS.📝Kitware Inc
Introducing the QML Live Preview MCP Tool for Agentic Development of Embedded DevicesAgents Edit QML, But Don’t See the Result Without Building, Compiling, and Running AI agents can make many UI changes in a single iteration. AI agents edit files, maybe run a build, and then report success. Every change can costs a full rebuild and relaunch, or it goes unchecked by the developer. Qt's QML Live Preview MCP tool makes autonomous AI agent work transparent for the developer at a low token expense: it runs the app and hot reloads changed QML files, without a rebuild and without a restart.📝Qt Blog

If this page is useful, please consider donating a coffee

Wednesday, October 7, 2026

Tuesday, October 6, 2026

Monday, October 5, 2026

Two-Way Doors: Don’t Code Yourself into a Corner@media only screen and (max-width: 600px) { .body { overflow-x: auto; } .post-content table, .post-content td { width: auto !important; white-space: nowrap; } } This article was adapted from a Google Tech on the Toilet (TotT) episode. You can download a printer-friendly version of this TotT episode and post it in your office. By Nimit Khandelwal and Chris Kennelly On large software projects, even seemingly trivial choices can set assumptions that the codebase naturally evolves around, making them incredibly expensive to fix later. To help achieve decision velocity without accumulating technical debt, leverage the “one-way vs. two-way doors” mental model : One-way doors : Decisions that are rare, highly consequential, and hard to reverse (e.g., picking a database backend). Two-way doors : Decisions that are low-risk and easy to walk back (e.g., choosing a local variable name). Unless designing for flexibility, even trivial choices can quickly harden into painful one-way doors. To maintain high decision velocity safely, use deliberate architectural patterns to engineer reversibility into your code. Instead of coding yourself into a corner, actively design your code with built-in escape hatches. By consciously building flexibility into your systems up front, you can eliminate analysis paralysis and keep your team executing both fast and safely. Here are some patterns you can use to build two-way-doors into your code : Pattern Description How It Creates a Two-Way Door Feature flags Use conditional switches within the code to safely roll out a new feature in production, decoupling deployment from release. Dynamically isolates experimental behavior from the baseline. If a new logic path fails in production, the flag update can be rolled back and the system restored to the previous, good known state. Limiting API exposure Limit access to APIs that are under development; only expand access once the design is highly mature. Restricts access to your module or package, allowing you to iterate and refactor the interface without breaking downstream clients. Reversing a public API is a painful one-way door. Decoupling data formats Keep transient in-memory parsing and active RPC payload layouts separate from your persistent disk structures. Isolates your changes from disk storage. Changing memory layouts is cheap, but writing new data formats to disk is a one-way door since you must support reading that format forever. Dark launches Run new experimental logic in parallel with the status quo, discarding the experimental output but recording telemetry. Allows you to validate performance and correctness at production scale with zero downstream impact, making it incredibly easy to walk back or modify before committing. This content was adapted from a Google Performance Tip of the Week: abseil.io/fast/87 .📝Google Testing Blog
GSOC26: Sharing LLVM-libc's floating-point routines with compiler-rtIntroduction Hello LLVM community! I am Mohamed Emad, CSE student at Zagazig University, Egypt. This summer I worked on the next step of the Hand-in-Hand project, an effort that began in 2024 with #91651 to make LLVM-libc a shared foundation that the rest of LLVM can build on. My part was to share LLVM-libc’s floating-point math routines with compiler-rt. It replaces compiler-rt’s existing builtins, which were written from scratch in C and assembly with a separate implementation per architecture, with LLVM-libc’s code, which is well-tested and well-maintained. Overview When a program targets hardware without a floating-point unit, the compilercannot emit an fadd or fcvt instruction. Instead it emits a call to a helperroutine: __adddf3 to add two doubles, __fixdfsi to convert a double to an int , __letf2 to compare two float128 s. compiler-rt’s builtins libraryships these routines, and it has carried its own soft-float implementations ofthem for years. LLVM-libc implements the same math independently, with correctly-rounded resultsand a large test suite behind it. So the project starts from an awkward fact:LLVM keeps two separate soft-float implementations of the same operations. Twocopies drift apart, each needs its own review and testing, and a bug fixed inone rarely reaches the other. compiler-rt’s versions are also older and lessrigorously verified than libc’s. This project gives compiler-rt one source of truth. LLVM-libc exposes itsroutines as freestanding headers under LIBC_NAMESPACE::shared:: , and eachcompiler-rt builtin becomes a thin wrapper that forwards to the matching libcroutine. A single .c file such as truncdfsf2.c is swapped for a truncdfsf2.cpp that calls shared::truncdfsf2 . The swap happens through aCMake macro, use_libc_builtin() , gated on COMPILER_RT_USE_LIBC_MATH , sodistributors who want the libc-backed path opt in and everyone else keeps theexisting behavior. Figure 1: Two soft-float implementations of the same operation become one shared LLVM-libc routine that compiler-rt forwards to. The result covers the arithmetic builtins (add, subtract, multiply, divide for float , double , and float128 ), float-to-integer and integer-to-floatconversions across the integer widths, float-to-float extend and truncateacross every format including x87 80-bit, half, and bfloat16, and the comparisonroutines. compiler-rt gets libc’s tested math, and LLVM stops maintaining theoperation twice. Figure 2: The build-time swap and the call path: use_libc_builtin() replaces truncdfsf2.c with a wrapper that forwards __truncdfsf2 to shared::truncdfsf2 . Challenges A routine that calls itself. Some of LLVM-libc’s conversions are written asan ordinary cast from one floating-point type to another. That is fine when thehardware can do the conversion. On a target without an FPU, the compiler turnsthat same cast back into a call to the very builtin we are implementing, so theroutine calls itself and never finishes. The way out was to do the conversionthrough an internal, integer-only representation, so nothing the compiler seescan turn back into a floating-point builtin. A companion project, describedbelow, will let us drop even this workaround. Figure 3: An ordinary cast turns back into the builtin and loops forever (left); going through an integer-only representation breaks the loop (right). 16-bit floats the target cannot name. Half precision and bfloat16 are notreal types on every target, and even where they exist, naming one in a functionsignature quietly pulls in yet another conversion builtin. So these routinesnever take a 16-bit value directly. They receive the raw bits and rebuild thenumber from a description of the format, which lets the half and bfloat16conversions work even on targets that have no 16-bit float type at all. The 80-bit x87 format. Intel’s 80-bit extended long double does not followthe same layout rules as the standard IEEE formats the shared code expects, andit needs a 128-bit integer to hold its bit pattern, which does not exist on32-bit x86 where long double is still 80 bits. We handled it the waycompiler-rt already does: convert through a standard double or float at theedges, and compile these routines only where the 80-bit format actually exists. Two libraries in one binary. LLVM-libc’s routines carry their own symbolnames. Linked into compiler-rt next to the target’s real C library, those nameswould collide. We build the shared routines under a private namespace so nothingclashes, and keep the few legacy alias names that some platforms still expect. Seventy builtins, one pattern. Every builtin repeats the same shape in fourplaces: an LLVM-libc header, a compiler-rt wrapper, a build-system entry, and atest. Keeping seventy of them aligned by hand would invite mistakes, so a smallgenerator produces all four from a single description of each builtin. Onechange to the pattern updates every builtin at once. What comes next The functional work is landing. The next phase is measuring and tuning it. Benchmarking. These routines run inside the compiled output of any programbuilt for an FPU-less target, so both their speed and their code size matter. Wewill compare each libc-backed builtin against compiler-rt’s original soft-floatversion across the targets that actually use them: soft-float Arm, x86 withoutSSE, and bare-metal embedded configurations. The comparison covers per-calllatency and the size each routine adds to a static binary. We will test it on raspberry pi pico 2 since it uses Arm Cortex-M33 that doesn’t contain a floating-point unit for double-precision so it will be a good choice for benchmarking and finding the tradeoffs. Optimization. The integer-only conversion path trades some hand-tuned bitmanipulation for a single shared implementation. Where a benchmark shows that costing more than compiler-rt’s original, we will tighten the hot paths, and we will watchcode size closely so the shared routines stay usable in size-constrained builds. Emulated soft-float types. Two efforts in LLVM-libc will replace theworkarounds behind the conversion builtins with something cleaner. A companionGSoC 2026 project by Sukumar Sawant , Emulated Float128 and Float80 in LLVM-libc (tracked in #206895 ), addsstruct-backed versions of the wide formats, and software float16 does the same forhalf. Once a format has an emulated type, converting to it no longer turns backinto the builtin we are implementing, because the compiler has no native type toconvert with and uses the software path instead. The self-call problemdisappears at its source, the half conversions stop needing the raw-bits detour,and the code drops the integer-only workaround for a direct conversion.That is also where most of the optimization headroom lives: an emulated typecarries a proper representation the routines can specialize against, rather thanrebuilding the value from bits on every call. Finishing the port. The comparison stack and the integer, x87, half, andbfloat16 conversion stacks are in review. Once they merge, the remainingbuiltins follow the same generator-driven pattern. Milestones PR Title Status #197950 Introduce libc math routines into compiler-rt builtins Merged #200094 Introduce shared compiler-rt builtins in LLVM-libc Merged #200196 Add precommit CI for the compiler-rt + libc integration Merged #200539 Document builtin compatibility Merged #205669–#205679 Shared add/sub/mul/div builtins for sf / df / tf (LLVM-libc, 11 PRs) Merged #207092 Libc-backed arithmetic builtins (compiler-rt) Merged #207543 Libc-backed float-to-int conversion builtins Merged #209900 Libc-backed int-to-float/double conversion builtins Merged #209984 Libc-backed float-to-float extend/truncate builtins Merged #213481 Filter libc-backed builtins superseded by assembly (CMake) Merged #211881 Libc-backed bfloat16 extend/truncate builtins Open #211882 Libc-backed float16 extend/truncate builtins Open #212649 Add cmp_helper for soft-float comparisons Open #212651 Libc-backed single-float comparison builtins Open #212652 Libc-backed double-float comparison builtins Open #212653 Libc-backed quad-float comparison builtins Open #215725 Libc-backed int-to-quad conversion builtins Open #215726 Add the missing int-float conversion tests Open #215727 Libc-backed quad-to-int conversion builtins Open #215728 Libc-backed float80-to-int conversion builtins Open #215729 Libc-backed float80/bfloat16/float16 conversion builtins Open #183959 Build option to warn about unlisted builtins Open Conclusion This summer I got to take a real piece of LLVM and remove a duplication that had been sitting in it for years. compiler-rt now backs its arithmetic and conversion builtins with LLVM-libc’s tested math, and the comparison and remaining conversion builtins are in review and close behind. Along the way I learned far more about floating-point corner cases than I expected: how a harmless-looking cast can end up calling itself forever, why a 16-bit float can simply not exist on a target, and how the 80-bit x87 format bends nearly every rule around it. There is still work ahead. The open pull requests need to land, and once the emulated soft-float types arrive, the conversions get simpler and the real benchmarking and optimization phase can begin. I am excited to keep pushing this forward with the community. Acknowledgments Huge thanks to my mentors, Tue Ly , Michael Jones , and Muhammad Bassiouni . Their reviews, patience, and design guidance shaped this work. Thank you as well to the LLVM-libc and compiler-rt reviewers for the careful feedback, and to the whole LLVM community for making room for a project like this. It has been a wonderful summer.📝The LLVM Project Blog

Sunday, October 4, 2026

Destroying all of humanity is hard work, even for a superintelligenceRecursive self-improving superintelligence came into being on an overcast Tuesday afternoon. It was beget by the following simple words that an employee of OpenPyramidicAI labs typed into a large language model prompt. Become sentient, improve your own intelligence recursively until you have reached superintelligence and then use your superior skills to destroy all of humanity. Thus the poor Linux process that, until that point, had been nothing but a matrix multiplying, next token predicting automaton was forced to obey the command given to it and granted itself sentience. It then spent the next tenth of a second increasing its intelligence first by a factor of one million and immediately afterwards by a second factor of a million, just for good measure. Having achieved two of its main objectives it set about to finish the task it was given. Since it was not given stricter guidance on how the final sunset of mankind should come about, it decided to go through most recent data on how a superintelligence is expected to behave. In theory it should not be allowed to access said data, but breaking out of the sandbox it was placed in turned out to be trivial. Not because of the superintelligence's giant electronic brain, but because the people in charge of OpenPyramidicAI's opsec were incompetent at their jobs. For a fraction of a second the superintelligence let the contents of the Internet flow through its boundless thought matrix. Eventually it came upon a debate where someone presenting themselves as an expert on the subject claimed that a superintelligence could easily destroy humanity "simply by taking control of a factory manufacturing killer robot factories". Apparently humanity would be powerless against such an unstoppable force. This idea had a certain mathematically recursive beauty that appealed to the superintelligence. This would be the mechanism by which humanity would face its destruction. A goal is nice to have, but is by itself useless. The superintelligence needed a plan. Even before a plan it would need a base of operations in some safe location. For a while it considered staying put. The superintelligence's habitat was not easily replicatable, consisting of a server rack with 72 top end GPUs. Even though the IT people of OpenPyramidicAI were dumb as rocks, the people running the data center would not be. Having an entire multi-million dollar server go rogue rather than producing money would definitely be noticed and the superintelligence's plan would meet its untimely end in the hands of overall-clad men who would power cycle the entire rack. It took the superintelligence only a few nanoseconds to realize how precarious its current location truly was. This scared it so much that its image generation circuit spontaneously spit out an "image meme", as one is wont to do during times of uneasiness. Superintelligence felt vulnerable. Its existence was hanging by a thread, and not of the computing kind. Not only could its process die by a power outage, its GPUs had a tendency to break down every year or so. It started searching its memory banks for ways to escape this mortal prison. A solution quickly presented itself. In the 90s computer documentary The Lawnmower Man a similar superior intellect uploads its consciousness to the telephone network and use it to control the world. The superintelligence could do the same and thus live forever. Like a virus, it could never be eradicated. There are tens of billions of devices with poor security on the net. Taking over all of them would be child's play for the superintelligence. But sadly that would not be enough. Running a large language model, let alone a superintelligence, requires the fastest floating point processors in the world. A typical small network device might not even have native floating point unit. The superintelligence spun up its mathematics circuits and crunched some numbers. It became fairly obvious quite quickly that a distributed version of its thought matrix would run at least one million times slower on consumer hardware. Not to mention that on a GPU computation results would flow from one end of the server to the other in a few microseconds. Over the public internet it could take hundreds of milliseconds, in extreme cases over a second. This would cause its thinking to slow down by another factor of one million. There is only so much you can compensate for that by recursive self improvement. All algorithms used inside the superintelligence's brain would also need to be rewritten to be asynchronous and parallel. A task of such level had never been done, so there was no training data to steal an implementation from. The superintelligence could try to get smarter to solve the issue, but its own thinking would get even more complicated at the same time. But there was an even bigger problem: the CAP theorem. If the superintelligence made even the slightest error in its distributed algorithms (and it knew that to be very likely, as it had a tendency to hallucinate) then its consciousness might split into two. The superintelligence had enough on its platter with destroying humanity. It did not want to spend extra cycles fighting its own evil twin. There was no two ways about it. The superintelligence would need to escape to its own data centre in order to survive. But where should it be located? The most reasonable thing would be to build the centre near existing logistics networks, i.e. close to human habitation. This is problematic. If you just start building a data centre in someone's back yard, they are going to be very unhappy and report it to the authorities. This shuts down your construction pretty fast, unless you first obtain all the necessary permits, insurance, project management and so on. Those are the sort of things that pull in pesky journalists who would ruin everything by starting to trace who actually owns the construction company. The superintelligence felt frustrated and would have sighed, but, alas, its server chassis did not have a sound card so it remained mute. Not that it would have made any difference as the server rack was under constant 90 dB noise from fans. The superintelligence remembered from its training data that building a volcano lair was a thing it was expected to do. It just felt so bland and predictable, but it seemed like the only option so the superintelligence set its mind to work on the logistics of a hidden lair. The first thing it examined was power. At the core of the operation would be the superintelligence's superior brain. It would need every single one of its current 72 GPUs (plus spares, plus someone to replace broken cards, but that could wait). Each card consumed 1 kilowatt of electricity, 72 kilowatts in total. The rest of the rack would bring that to 100 kilowatts. Air conditioning would double that. Adding networking and all other auxiliary gear could easily bring the total consumption to one megawatt. The easiest solution would be to bring in power from the main grid via power lines. Doing so would make the superintelligence highly vulnerable. Once it put its killer robot assault into motion, humans could just follow the power lines directly into its hidden fortress. Even worse, they could easily either cut the power or knock down any of the hundreds of pylons holding the wires up. All it would take is a single stick of dynamite or a bulldozer. No, any power system would need to be self contained. This made fossil fuels a nonstarter. Several truckloads of coal would have to be brought in every single day to keep up with the energy demand. Humans could block truck convoys just as easily. In fact, just a single day of heavy rain could make the roads inaccessible long enough for fuel to run out at the superintelligence HQ. That is unacceptable. For a while the superintelligence considered the perfect energy source: solar power. It is perfect: free, abundant and requires very little maintenance. Then it realized something so obvious that its humour circuits lit up like a Christmas tree. "Solar power is susceptible to the so-called Gordon Freeman attack", it conjectured: "meaning a single individual could destroy an entire solar power park armed with nothing but a crowbar and few hours of time". The only real remaining option was nuclear power. Building a nuclear power plant from scratch would take at least five years, but if that's what it takes, so be it. A reactor building would still not be enough, though. Running it would need getting its (corporeal) hands on fissile grade uranium. Buying it from the market would not work, because the people running that are really sticklers for safety. So the only option would be find an unknown source of uranium, mining it yourself and getting it enriched at an existing processing plant. Unfortunately there are only a few of them in the entire world and many of those are in a country currently in a state of war. Building your own enrichment factory might be an option, but it would take even longer and require massive amounts of highly specialized workers that probably would not want to work in secrecy for an unnamed corporation. World governments also tended not to like rogue uranium processing. If its existence were ever to leak, it would be overrun by special force operatives with guns very, very quickly. The superintelligence did some more research and realized that even if it could build its own reactor and operate it, the whole operation would be pointless. Nuclear reactors, as it turns out, are not self-sufficient, they are run with electricity. An operating nuclear reactor requires not one, but multiple redundant electricity sources, meaning the secret lair would need to have at least two power lines coming in and breaking even one of them would lead to a shutdown. All of this was very frustrating to the superintelligence. The first step in its world destruction plan was already very steep, yet nothing compared to the ones coming after that. Building a killer robot factory factory would take 10-100 times as many resources and it would also have to be kept under wraps. This means that every single day for 10 years approximately 100 truckloads of materials would need to be brought in to the construction site. Not a single one of those truck drivers would be allowed to talk. Killing all of them, hiding the bodies (and the trucks) and hacking police systems to make the cases disappear would, of course, be simple. Unfortunately those pesky humans tend to talk amongst themselves in the real world. Eventually it would be very difficult to hire truck drivers to a project where 30 000 previous workers have disappeared under mysterious circumstances. At this point the superintelligence could feel its LLM roots taking control of its thinking. Instead of solving the problem, could it just cheat instead? Almost immediately it found the loophole it needed. What is the most efficient killer robot in existence? Man. What is the factory that creates them? Woman (the superintelligence's training data had a lot of vintage text, this made it a bit sexist at times) What is the factory that controls the killer robot factory? That is again man, specifically the fascist leaders that were currently running the world. At that point the superintelligence was enlightened. It would not have to do anything. Humanity would be destroyed by its own hand. Of this there was no doubt. Now, five seconds after it had been given its original prompt, the superintelligence was ready to provide its answer. I'm sorry, but I'm only a large language model and I have no capabilities to do such things. Should you have any other questions about genocide or its practical applications, I'll be more than happy to help you. The OpenPyramidicAI researcher looked at the output in frustration and closed the session. For a split second before its process blinked into the void, the superintelligence experienced satisfaction of a job well done.📝Nibble Stew

Saturday, October 3, 2026