Friday, July 10, 2026

Whatโ€™s in a Warning?For a while, users have been asking for CMake to do a better job of warning about undesirable uses, such as using functions that should not be used in โ€œmodernโ€ CMake. Starting with CMake 4.4, we are finally making inroads on those requests, but the journey there went through some interesting and unexpected territory. This is a bit of a peek โ€œunder the hoodโ€ of CMake development, which is a bit of a deviation for a normally user-focused blog, but we wanted to share because it has the potential to impact users, and we wanted to explain why we felt the changes, and the potential pain associated with them, are warranted.๐Ÿ“Kitware Inc
Using some modern C++ features to avoid macrosRecently I had an opportunity to use some non-obvious C++ language features, which in those days doesn't happen that often to me. ๐Ÿ˜ž To be frank, lately I'm doing more QML and JavaScript programming than pure C++, so I was more than happy to be able to jump into the challenge. The (arguably small) problem I had, was that I had to define a seemingly endless amount of callback functions all doing basically just the same thing: auto callb = [this](std::expected result) -> void { if (result.has_value()) { emit okNotification(result.value()); logCallback("BlaBlaCallback " + std::to_string(result.value())); } else { emit errorNotification(std::to_underlying(result.error())); logCallback("BlaBlaCallback ERROR: " + std::to_string(std::to_underlying(result.error()))); } }; As you can see, I was working with Qt and I used their signal/slot mechanism. In this context the emit clause sends a signal to all parties that subscribed for it. So basically we need a callback that looks into a std::expected value and decides what kind of a Qt signal has to be sent - an error notification or a value change one. Additionally, std::expected result can contain values of different types: integers of different ranges and signs, as well as floating point numbers and enum values. 1. The definition The first idea to come (because I'm oldskool?) was a macro . I even wrote one, but then I said to myself - come on, that's ugly, Bjarne working all the time to give us mechanism to make macros obsolete and now I write that abomination? So, ashamed, I deleted it immediately and started with a template-based solution. As templates are kinda oldskool themselves, I wanted to try polymorphic lambdas first , hoping that maybe compiler can figure out all that parametrization stuff for me and I will just write down the auto keyword and everything will be good in the world. So I wrote this piece of code: auto makeUint32Callback = [this](auto notifOk, auto notifErr, const std::string& label) { return [this, notifOk, notifErr, label](std::expected result) -> void { if (result.has_value()) { emit (this->*notifOk)(result.value()); logCallbacks(label + " " + std::to_string(result.value())); } else { emit (this->*notifErr)(std::to_underlying(result.error())); logCallbacks(label + " ERROR: " + std::to_string(std::to_underlying(result.error()))); } }; }; As you can see, I defined a helper function (a lambda in the local scope), which constructs the final lambda from provided parameters, which final lambda can then serve all callbacks reporting value changes for values of type uint32 ! Nice one, but what about other value types? Do we have to define makeInt32Callback(), makeUint8Callback(), makeFloatCallback() etc? We certainly don't want that! To the rescue comes a C++20 feature called templated lambdas . Don't fear, it's very simple, we just give a type parameter to the lambda and it's all we need here: auto makeTypedCallback = [this] (auto notifOk, auto notifErr, const std::string& label) { return [this, notifOk, notifErr, label](std::expected result) -> void { if (result.has_value()) { emit (this->*notifOk)(result.value()); logCallbacks(label + " " + std::to_string(result.value())); } else { emit (this->*notifErr)(std::to_underlying(result.error())); logCallbacks(label + " ERROR: " + std::to_string(std::to_underlying(result.error()))); } }; }; As easy as that! We then just forward the type parameter T to the std::expected parameter definition and that's it. Now we even can go further and add support for enum types using an if constexpr construct inside of the lambda: auto makeMyCallback = [this] (auto notifOk, auto notifErr, const std::string& label) { return [this, notifOk, notifErr, label](std::expected result) -> void if (result.has_value()) { if constexpr (std::is_enum_v ) { emit (this->*notifOk)(std::to_underlying(result.value())); logCallbacks(label + " " + std::to_string(std::to_underlying(result.value()))); } else { emit (this->*notifOk)(result.value()); logCallbacks(label + " " + std::to_string(result.value())); } } else { emit (this->*notifErr)(std::to_underlying(result.error())); logCallbacks(label + " ERROR: " + std::to_string(std::to_underlying(result.error()))); } }; }; When seeing if constexpr compiler will decide which branch of the code has to be taken and which has to be ignored. And all that at compile time! 2. The invocation Now as we have our templated, polymorphic lambda ready, we just invoke it for each pair of notifications and we are done! But how exactly should we invoke a templated lambda? Somehow it's not that obvious. We could try to do it the standard way, just as we always have done with data structurers, i.e. like that: auto callb = makeMyCallback ( &NotifThreadWrapper::operationModeChanged, &NotifThreadWrapper::operationModeChangeError, "OperationModeCallback"); But the compiler won't let us have it! ๐Ÿ˜ž The right way, however, is: auto callb = makeMyCallback.operator() ( &NotifThreadWrapper::operationModeChanged, &NotifThreadWrapper::operationModeChangeError, "OperationModeCallback"); Why's that? Well, as it turns out, you cannot templatize a lambda as a whole, but you can only templatize its function call operator! An that is what the funny looking syntax does: lambda.operator() (args) , the type T comes after the call operator. If you think about it, it is quite logical, a lambda is just a generalized function, so you parametrize the function call, right? Because, c ome on, it's even declared like that: [] (T x) { /* ... */ } in the first place! On the other hand however it is just syntax, and the Standard Committee could add support for the first invocation as well. The chose not to. 3. Extending it further Some time later I added some new callbacks taking a std::pair of something as parameter. How can we support this new callback type in the makeMyCallback() helper? Simple, another if constexpr will do it: ... else if constexpr (is_pair_v ) // why not std::is_pair_v ??? { emit (this->*notifOk)(result.value().first, result.value().second); logCallbacks(label + " " + std::to_string(result.value().first) + "/" + std::to_string(result.value().second)); } However, because apparently there isn't a std::is_pair_v predicat e in the standard library ๐Ÿ˜ฎ, I also had to provide following definitions: template struct is_pair : std::false_type {}; template struct is_pair > : std::true_type {}; template inline constexpr bool is_pair_v = is_pair ::value; Easy, but std::is_pair would be so much nicer! 4. Wrap-up And there it is: a polymorphic, templated lambda returning a lambda , thus clearly being a metafunction* (yay!). Or can we call it meta-lambda/metalambda? Now you know how to write yourself one and, what's maybe even more important, also how to invoke it and put it to good use instead of polluting your code with ugly macros! __ * metafunctions - function returning other functions, it should be pretty clear? But it isn't. For example Boost MPL libraray ( "...high-level C++ template metaprogramming framework of compile-time algorithms, sequences and metafunctions." ) defines them quite differently: "... A metafunction is a class or a class template that represents a function invocable at compile-time", thus clearly meaning just a * constexpr * function. Hmmm... ๐Ÿค” Other definition I've seen are "...functions that operate on types, rather than traditional runtime values" or "...Metafunctions are program elements (classes in C++) that can return computed types" . This definition makes more sense than the MPL one, but how can we then name a lambda returning a lambda? Here I chose to stick to functional programming nomenclature where I first learned that concept: "...A metafunction is simply a function that operates on other functions or on representations of functions, often at the metaโ€‘level (i.e., reasoning about code, types, or syntax rather than just data)". Of course, we could also use the (more correct) term "higher order functions" , but "metafunction" sounds so much crispier ๐Ÿ™‚, so I hope you will forgive me this little stretch of nomenclature.๐Ÿ“On Software and Languages
Democratizing Build Scalability: Eugene Yokota on Bringing Bazel Features to sbt 2.0 | EngFlowDemocratizing Build Scalability: Eugene Yokota on Bringing Bazel Features to sbt 2.0 In this interview, Eugene Yokota โ€”a software build expert who spent years maintaining Scala's sbt tool at Lightbend before working with hyperscaled Bazel monorepos at Twitter and Netflixโ€”details his multi-year project to build a Bazel-compatible remote caching system into the newly released sbt 2.0. He explores the mechanics and benefits of Bazel, such as its robust remote caching and test cycle speed, and highlights how these modern, scalable build tools can eliminate CI bottlenecks for growing teams while protecting toolchain security.๐Ÿ“EngFlow Blog

If this page is useful, please consider donating a coffee

Thursday, July 9, 2026

Wednesday, July 8, 2026

The Language Belongs to the People Who Write ItThe Language Belongs to the People Who Write It C++ is a working language. It runs the engines and the pipelines and the quiet infrastructure underneath almost everything people depend on, usually without anyone noticing it is there. And for forty years it has grown from the people who use it. Someone hits a wall, builds the thing that gets them past it, and shares what they learned. That is where the language comes from. Not one room somewhere. The whole community that writes it every day. We think that is worth building for on purpose. Most of the work that shapes C++ happens in the open. The proposals, the debates about where things should go next, the record of who argued what, all public, and it has been for years. The trouble is that public and reachable turned out to be two different things. The archive is enormous and scattered, and keeping up with it has quietly become a skill of its own, the kind you only have time for if tracking C++ is already part of your job. Most working developers never get there. Not because anything is hidden. Because it is exhausting. So that is where we started. The mailing tools at wg21.org make the public record usable. Search across the papers instead of hunting through them one at a time. Sort and filter down to the ones that actually touch your work. Follow a thread without having to already know where it lives. It is not glamorous work and it is not meant to be. The whole idea is to take a layer away rather than add one. A developer in Lagos or Osaka or a spare bedroom anywhere should be able to see what is happening in C++ as easily as someone who has been going to meetings for twenty years. That is the gap good tooling closes, and closing it is how a language stays the property of the people who use it. It is the first piece. There is more coming, all of it aimed at the same thing from different directions: making it cheaper to take part, clearer to follow along, possible to go from curious to contributing without a decade of context first. More on that as it ships. Knowing what is happening now is only one way in, though, and not everyone starts there. Some people come to a community through its history, and Boost has a good one. Decades of libraries built by people who mostly never got seen for the work. We have been putting that story on film, a documentary about where Boost came from and who made it. It is a better place to start than you would expect, and a lot more human than the code makes any of it look. Others come through play. So we made a collectible card game out of the Boost libraries. Every library is a card. So are the authors, and the events anyone who has shipped software will recognize on sight, the QA reject that saves you at the last second, the PM back from a conference with a head full of ideas. It is fun first. Underneath the fun it is a surprisingly honest picture of how the ecosystem actually runs. Open source deserves to be celebrated the way other creative traditions are, with things you can hold and hand to a friend. If a card game is how someone first learns what Boost is, good. That counts. And then there is the most direct way in, which is to build. Boost is the Allianceโ€™s flagship, it is open, and it is right there. Fix a bug. Review a library. Propose something and argue for it in daylight. The work is real and nobody is guarding the door. None of these sits above the others. Different people walk in through different ones and end up in the same place. If there is a single conviction under all of it, it is this. A language used by millions of people ought to be shaped by more than a handful of them. You do not get there by asking anyoneโ€™s permission. You get there by lowering the barriers, one at a time, until taking part stops feeling like a privilege and starts feeling ordinary. Better search. Better tools. A door that is genuinely open. And none of it works without you. We mean that plainly, not as a flourish. The tools get better because people use them and tell us where they break. The community gets stronger every time someone shows up, reads a paper, joins a list, reviews somebodyโ€™s library, says the thing everyone else missed. You do not need a title or a seat. You need the language you already write, and an opinion about where it should go. C++ is not finished and it is not fragile. It is a living thing, kept alive by the people who care about it, and there are far more of them than there are chairs in any room. That is the bet we are making. Come be part of it.๐Ÿ“The C++ Alliance
Bringing Safety to HEPBringing Safety to HEP High-Energy Physics software is routinely trusted with complex detector geometries spanning millions of volumes, critical tracking and reconstruction algorithms, and multi-day simulations running on the Grid. A single silent unit mismatch in a double can invalidate an entire analysis or produce detector geometry that is 10ร— the wrong size. This post shows how mp-units can bring compile-time safety to HEP codebases (including a dedicated HEP system of quantities and units) and how large projects like ATLAS can adopt it incrementally without requiring a big-bang rewrite.๐Ÿ“mp-units

Tuesday, July 7, 2026

Bazel Q2 2026 Community UpdateAnnouncements BazelCon 2026 - details The Details at a Glance: What: BazelCon 2026 Where: Postillion Hotel & Convention Centre Amsterdam, Netherlands When: October 13โ€“15, 2026 October 13th - Training Day October 14th & 15th - 2 Conference days filled with technical sessions, Birds of a Feather and networking with the best in the field. Get your ticket and find all the details via the BazelCon website ! For the most up to date BazelCon news and updates, follow the Bazel X account and the #bazelcon Bazel Slack channel. Call for Proposals This year, we received a tremendous 170 talk submissions! A huge thank you to everyone who took the time to submit a proposal. The Review Committee is already diligently reviewing them to curate the 2026 schedule. Speaker confirmations will be sent out on July 20th, and we will announce the schedule a few days later. If your submission isn't selected this year, we highly encourage you to apply again next time - and we sincerely applaud your willingness to share your stories with the community! BazelCon Training Day Following last yearโ€™s success, we are bringing back Training Day right before the main conference. The schedule features two parallel tracks with four sessions each, allowing you to choose one session per time slot. You can select your sessions when you secure your BazelCon ticket on the website. Already registered? You can easily edit your existing registration to secure a spot in the trainings of your choice. Please Note: Seats are limited. If your plans change and you can no longer attend, please free up your spot so someone on the waitlist can take your place. Product Updates Upcoming Bazel releases Bazel 9.2.0 is expected to release on 2026-07-09. RC1 was released on 2026-06-25. Bazel 8.8.0 is expected to release on 2026-07-15. Please send cherry-pick PRs against the release-8.8.0 branch before the RC1 cutoff on 2026-07-08. Q2 releases 9.1.0 was released in April โ€˜26, followed by patch 9.1.1 . 8.7.0 was released in May โ€˜26. Community Corner Updates from the JetBrains* team: Bazel for CLion plugin updates Debug flags are no longer injected automatically by debug run configurations. If your build already includes debug symbols, this change shouldn't impact you; otherwise, check the details here: https://jb.gg/clwb-debug-docs . You can now switch configurations if the current source file is built under multiple configurations in your project. Additionally, when you start debugging, we'll automatically select the correct configuration to keep your code insight and debug session in sync. Developments in the Bazel plugin by JetBrains for IntelliJ IDEA, PyCharm and GoLand in 2026.1 Improved stability and less freezes: all known freezes caused by the Bazel plugin have been fixed. Sync performance improved, with overhead removed. Less spurious analysis cache invalidations. Better hot swap in JVM applications. Graceful cancellation for Bazel run and build. Bazel 9 compatibility. More readable build and sync progress in IDE output. Find more details on the plugin "What's New" page. In the upcoming 2026.2 version, the team is focusing on improved support for Bazel projects with Python and Go, in particular when opened in PyCharm and GoLand. Meetup.build events Check out the recaps of the latest Build meetups organised by EngFlow! EngFlow x Uber Amsterdam Build Meetup 2026: Scaling Builds - hosted in the Uber office, the attendees got to enjoy 6 talks on all things Build. Munich Bazel Build Meetup 2026: Tackling Supply Chain Security and Monorepo Scalability - the community met in the Salesforce offices for more great talks and knowledge sharing. Recordings of talks will soon be available to watch online. Keep an eye on meetup.build for next meetup announcements. Community created content Articles Remote Cache CDC: Reusing Bytes - by Tyler French @BuildBuddy Accessing external resources reliably with Bazel - by Alexey Tereshenkov @Tweag Building and running Bazel applications on AutoSD: Toolchains, containers, and recommended practices - by Bilal Elmoussaoui Mastering Your Frontend Build with Bazel: Testing - by Matti Bar-Zeev Mastering Your Frontend Build with Bazel: Consolidating Tests - by Matti Bar-Zeev A Practical Introduction to Bazel Persistent Workers - by Adin ฤ†ebiฤ‡ Cleaning up old Bazel patterns - by Adin ฤ†ebiฤ‡ Micro-Benchmarking Java with JMH and Bazel - by Somak Dutta Why Bazel is the Endgame for Build Systems - by The Coding Gopher Videos Introduction to the Bazel build system - by Florent Castelli, presented during Sweden Cpp Bazel for SONiC: What We've Learned and Contributed - by Borja Lorente @Aspect Build Bazel and Rust at OpenAI with David Zbarsky - by Aspect Build Resources GitHub repository: https://github.com/bazelbuild/bazel Releases: https://github.com/bazelbuild/bazel/releases Slack chat: https://slack.bazel.build Google group: bazel-discuss@googlegroups.com Special Interest Groups (SIG): Reach out the email(s) listed below if youโ€™d like to be added to the SIG calendar invites. SIG Meeting frequency Point of contact Rules authors Every two weeks bazel-contrib@googlegroups.com Android app development Monthly ahumesky@google.com Bazel plugin for IntelliJ Monthly en@jetbrains.com Remote execution API working group Monthly chiwang@google.com Supply chain security / SBOM Weekly fwe@google.com Interested in learning about SIGs or starting a new one? Find more information on our website . Want to get your SIG listed? Please add it to the Community repository . Ideas, feedback, and submissions are welcome! Thank you for reading this edition! Let us know if youโ€™d like to see any new information or changes in future community updates by reaching out to product@bazel.build. We look forward to hearing from you. Thanks, Google Bazel team * Copyright ยฉ 2026 JetBrains s.r.o. JetBrains and IntelliJ are registered trademarks of JetBrains s.r.o.๐Ÿ“Bazel Blog

Monday, July 6, 2026

Sunday, July 5, 2026

Saturday, July 4, 2026