Skip to content

Back to the catalog

adincebic.com
jsonEnglish

Adin Ćebić

adincebic.com · English

jsonindiewebblogroll

Open the feed

https://adincebic.com/feed.json

Last post
Nov 8, 2026
Posts in 24 h · 7 days · 30 days
0 · 0 · 4
Our last check
Answering
Served from
United States
Site title
Adin Ćebić —
Text score
3,794
Format
json
Community
indieweb, blogroll

Posts

What our queue read from this feed. Open one to read it here, or go to the site that published it.

  1. Bazel genquery
    Nov 8, 2026 · original
    There are some Bazel queries I find myself running manually quite often to inspect things as I go. Or, in today s world, I might have those queries defined in an AGENTS.md file or a skill. That works fine. But what if there were a way to encode a query into the Bazel target graph and execute it like a normal target? Enter genquery genquery is basically a way to turn a Bazel query expression into a Bazel target. For example, if you want to list all the dependencies of a given target, you might run something like this: bazel query 'deps(//ios/app:library)' This would print all the transitive dependencies of our iOS app s library target (including the target itself). Now, what if we could instead run: bazel build //ios/app:deps And have Bazel produce a text file containing all those dependencies at bazel-bin/ios/app/deps ? Here s what that would look like in ios/app/BUILD : genquery( name =
  2. Validating Bazel Rule Attributes
    Nov 1, 2026 · original
    Oftentimes, it is necessary to validate rule attributes to prevent misuse of a rule. While attributes can be validated as part of the main rule implementation function, there is perhaps a better way to do it. Rule initializer This is yet another lesser-known feature of Bazel, where we can declare an initializer function that runs when a rule is instantiated. In my opinion, this is the ideal place to validate inputs. Take this fictitious rule, where we want to make sure that it only accepts certain modes: def _init(name, mode = "safe", **kwargs): if mode not in ["safe", "fast"]: fail("mode must be 'safe' or 'fast'; got %r" % mode) return {"mode": mode} def _impl(ctx): out = ctx.actions.declare_file(ctx.label.name + ".txt") ctx.actions.write(out, ctx.attr.mode + "\n") return [DefaultInfo(files = depset([out]))] validated_file = rule( implementation = _impl, initializer = _init, attrs = { "
  3. What Bazel Thinks Has Changed
    Oct 25, 2026 · original
    Very often, engineers I support ask me how they can inspect what Bazel thinks has changed between builds. While it s true that they could generate execution logs and compare them, they often don t have those enabled, and diffing the logs can be tricky given how large they can get. Yes, there s the BuildBuddy CLI, which can help with that, but there s another way to peek into Bazel s state and see which files Bazel detected as changed when deciding what needs to be re-evaluated. Enter DiffAwareness This is a neat trick for inspecting Bazel s server log to see what changes Bazel detected. After running a build, we can use grep , rg , or any other tool to inspect the log. For example: bazel build //:app Now, let s say the build has finished. Whether Bazel actually re-ran any actions (or invoked the compiler) is a different question. We can inspect which file changes Bazel detected by runnin
  4. BazelCon 2026: My Notes and Observations
    Oct 18, 2026 · original
    I always find BazelCon to be an exceptional experience, and this year was no exception. From the things I learned by randomly talking to people, to meeting familiar faces and learning from the talks and BOF sessions, it is simply an incredible experience. Today I want to go over some things I observed and what I am looking forward to in Bazel 10. AI is everywhere Nowadays, when we are all using AI agents every day, I find that using AI is becoming just like using any other tool. There was no talk about doomsday scenarios, but rather encouragement to use AI even more. On more than one occasion, people would say point your agent at the documentation instead of reading the documentation yourself. Also, EngFlow s report on how much people are using AI was eye-opening. It s not like I didn t expect it, but seeing the numbers really puts things into perspective. IDEs as we know them are going
  5. Fine-Grained Swift Warning Control with Bazel Features
    Oct 11, 2026 · original
    Ever since Swift gained the ability to control warnings via diagnostic groups in SE-0443 , we ve been able to promote specific diagnostic groups to errors. However, passing these flags via copts on swift_library targets isn t always convenient. To apply them globally, we d either need to modify every swift_library target, pass them via the command line, configure them in .bazelrc , or use Bazel macros to apply them automatically. All of these approaches have their downsides, such as accidentally applying the flags to external repositories, introducing additional complexity through macros, or making it difficult to opt out for specific targets. In the past, I ve written about Bazel s features mechanism , as well as how to suppress warnings in external repositories . Bazel feature-based approach In rules_swift 4.2.0, we added a way to control these warnings using Bazel s features mechanism
  6. Configuring Bazel Module Extensions with tag_class
    Oct 4, 2026 · original
    When writing a Bazel module extension, we sometimes need a way to let the user pass some values to configure things, download binaries from a specified URL, etc. A Bazel module extension itself does not support attributes in the same way repository rules and normal rules do. Instead, it offers another API called tag_class , which lets us define attributes for tags exposed by a module extension. A single module extension can have multiple tag classes. During extension evaluation, we can iterate over the modules that use our extension and inspect the tags of the class we are interested in. Downloading a binary For the purposes of this simplistic article, we will define a very crude repository rule to download any sort of binary. Then we will wire it up through a module extension, which will allow the user to specify the URL and SHA-256 value. Our repository rule will look like this: def _b
  7. Running Bazel Targets Under Another Executable
    Sep 27, 2026 · original
    When running a binary through Bazel with bazel run , we might find ourselves in a situation where it is desirable to wrap it in a parent binary or script. This could be to profile the running binary, fiddle with its environment, run it through a debugger, or any sort of thing really. To achieve this, we could build the binary and then manually wrap it with whatever we want, but that is a bit tedious and perhaps prone to errors. Using –run_under Bazel has a flag specifically for this use case: --run_under . Simply put, it prepends a command to the executable being run. It is a rather old Bazel feature — --run_under was already around in 2015, during the early days of the public Bazel project. For example, if we wanted to measure the CPU time of a rules_xcodeproj executable target, we could do something like this: bazel run //:xcodeproj --run_under="time" This effectively results in Bazel
  8. Tree Artifacts Over ZIP Files in Bazel
    Sep 20, 2026 · original
    Typically, when writing Bazel rules, we output files as the final step, and that is what we need most of the time. However, today I want to make a case for outputting directories—or, as Bazel calls them, “tree artifacts.” There are many reasons to reach for a tree artifact instead of, say, a ZIP file. For one, zipping can be expensive and time-consuming, depending on the size and contents of the output. Every downstream action that needs the directory then has to unzip it again, adding more CPU work, disk I/O, and temporary files. Archives are also opaque blobs. By contrast, Bazel represents a tree artifact as a directory whose individual files are stored in the content-addressable store. The tree is still treated as a single declared output for dependency and action-cache purposes, but remote caching and remote execution can deduplicate the files it contains instead of repeatedly storin
  9. Exploring map_directory in Bazel 9
    Sep 13, 2026 · original
    In the world of Bazel, we prefer to be explicit as much as possible and register actions ahead of time. In fact, this is not just a preference but a strongly enforced rule that enables all the good stuff Bazel gives us. However, there is a world where a bit of dynamism is useful—or, in some cases, unavoidable. Today I am exploring the little-known map_directory API that was introduced in Bazel 9. Registering actions dynamically Say we write a rule that generates a couple of files and then want to register a separate Bazel action for each of those files. The Bazel API did not facilitate this use case before version 9. Sure, we could have resorted to all sorts of tricks and hacks, but there was no nice native way to register actions based on the contents of a generated directory. This is where map_directory comes in. It allows part of action registration to be deferred until execution time
  10. Bazel, APFS Clones, and Disk Space
    Sep 6, 2026 · original
    I was recently writing about the problem of disk space usage when building with Bazel due to its many caches. That led me to pay more attention to the work being done in this area, and I discovered that Bazel 9.3.0 is expected to make better use of copy-on-write cloning on macOS #30776 to avoid unnecessarily duplicating files between the disk cache and the output base. On APFS, this essentially means copy-on-write: the cloned files initially share the same underlying data blocks, so they don t immediately take up twice the physical disk space. If either copy is modified, the filesystem only needs to allocate storage for the changed blocks. Using APFS clones from Swift Naturally, I got interested in learning how this feature works, and it turns out to be pretty simple. There is a low-level API function, clonefile(...) , which does exactly what you would expect: it creates a copy-on-write
  11. How to Reduce Bazel Disk Space Usage Across Git Worktrees
    Aug 30, 2026 · original
    Ever since the advent of coding agents, a lot of engineers have started utilizing Git worktrees and, by extension, multiple Bazel output bases. We all know the story: Bazel caches tend to take up a lot of disk space when working with large projects. Manual deletion and garbage collection can only take you so far. Enter bb-clientd bb-clientd is a daemon that runs on your machine and can act as a local remote cache and proxy for Bazel. More importantly, it also implements Bazel s Output Service protocol , introduced in Bazel 7.2. This allows bb_clientd to manage Bazel s output tree through a virtual filesystem—FUSE on Linux and NFSv4 on macOS—and lazily materialize files when they are actually accessed. Combined with its content-addressed local cache, this means that multiple Bazel output bases can reuse the same cached content instead of each storing their own copies of identical files. T
  12. Preventing Transitive Swift Imports with Bazel
    Aug 23, 2026 · original
    Swift s permissive nature when it comes to module dependencies has always annoyed me and made my life a bit harder than I expected. Of course, I m talking about transitive module imports. You know the situation: there is a ModuleA which is a dependency of ModuleB , and if you declare ModuleB as a dependency of ModuleC , ModuleC can import ModuleA even though it never declared ModuleA as its own direct dependency. There are a lot of reasons why you might not want that, from making dependencies harder to visualize to enforcing a certain module structure, and so on. Unfortunately, Swift itself does not provide a mechanism to enforce direct module dependencies—or at least I don t know of one. Layering check via rules_swift One of the reasons I like working with Bazel is the flexibility it provides. One example of that is a feature in rules_swift called layering check , which prevents importi
  13. Profiling Starlark Memory Usage in Bazel
    Aug 16, 2026 · original
    When using Bazel within a large monorepo, there comes a time when memory starts becoming a problem, and it is important to be aware of the available tools that can help with diagnosis. Fortunately, Bazel offers Starlark memory profiling, which we can utilize to see how much memory is being swallowed by the analysis phase. Setting up Surprisingly, it is a little tedious to set this up, but in the end, it is not that difficult either. First, we need to download the allocation instrumenter JAR from Maven Central . Once that s on disk, we can start Bazel in memory tracking mode like so: bazel --host_jvm_args=-javaagent:/path/to/java-allocation-instrumenter-3.3.4.jar \ --host_jvm_args=-DRULE_MEMORY_TRACKER=1 \ build --nobuild //path/to/target Here, we start Bazel with memory tracking enabled and pass --nobuild so that only analysis is performed, which is what we want to measure. After analysi
  14. Testing Bazel Remote Build Execution Locally with actiond
    Aug 9, 2026 · original
    When configuring remote build execution, it is very important to test changes locally so you don t waste time on CI. A lot of the time, people don t even have access to an RBE environment. Yes, BuildBuddy offers their service for free for open-source projects, but I feel like having access to an RBE environment locally is invaluable. I only recently started utilizing RBE more seriously, and while working through that setup I accidentally discovered actiond . I really wish I had known about it earlier. Having a remote executor that you can run locally makes experimenting with RBE, debugging issues, and checking whether your targets actually execute remotely much easier. actiond from hermeticbuild actiond is a full-fledged remote build executor that you can spin up easily simply by downloading it: curl -L \ https://github.com/hermeticbuild/actiond/releases/latest/download/darwin-actiond_ma
  15. Less Boilerplate for Bazel Transitions
    Aug 2, 2026 · original
    I’ve written about Bazel transitions multiple times: first when demonstrating rule extensions , and then when explaining split transitions . Now I want to showcase a community-built way to apply transitions more easily. Enter with_cfg.bzl with_cfg.bzl is a convenient way to apply Bazel transitions. It was created by well-known community member Fabian , and I can’t recommend it enough. Applying a transition to a plain swift_library Say we want to ensure that our swift_library is always built with --compilation_mode=opt . We can achieve that quite easily with the following .bzl file: load("@rules_swift//swift:swift_library.bzl", "swift_library") load("@with_cfg.bzl", "with_cfg") opt_swift_library, _opt_swift_library_internal = ( with_cfg(swift_library) .set("compilation_mode", "opt") .build() ) That’s it. NOTE: You can ignore _opt_swift_library_internal . It needs to be assigned to a globa
  16. Pruning Unused Action Inputs in Bazel
    Jul 26, 2026 · original
    Bazel has grown significantly since its initial open-source release, and it is hard to keep up with every release. One useful feature that may have slipped past you is unused_inputs_list , a parameter of ctx.actions.run(...) that lets an action report which of its declared inputs it did not actually use. After the action executes successfully, Bazel can prune those files from the action s effective input set. On subsequent incremental builds, changing only one of the reported unused files will not cause the action to run again. This is post-execution dependency pruning , not pre-execution input discovery. The action still starts with all of its declared inputs. It reports unused inputs only after it has run. If the action later needs to execute again, Bazel restores the original input set first, because a previously unused input may be needed during the new execution. A natural use case
  17. A Note on Bazel’s config.exec()
    Jul 19, 2026 · original
    When writing a rule that executes in the exec configuration, we need to communicate that to Bazel so it doesn’t attempt to build it for the target configuration: generator = rule( implementation = _generator_impl, ..., cfg = "exec", ) While there is nothing wrong with cfg = "exec" , my opinion is that we should use the newer transition object API. This means that instead of: cfg = "exec" we use: cfg = config.exec() Why? Apart from legitimate use cases such as transition composition and passing an exec group , I think using the object form is better for readability and discoverability. "exec" is a special string. You need to already know what it means and where it is supported. config.exec() , on the other hand, looks like an API. It is easier to discover, easier to search for, and makes it clearer that we are applying an execution transition. Passing the "exec" string is not deprecated,
  18. Making Bazel Module Extensions Work Together with override_repo
    Jul 12, 2026 · original
    Recently, I have noticed more rulesets adopting Bzlmod-specific features. With Bazel 6 no longer supported and Bzlmod adoption continuing across the ecosystem, rulesets can increasingly rely on newer module APIs. One feature that caught my attention while I was setting up a hermetic Android toolchain is the ability to override a repository generated by a module extension. override_repo requires Bazel 7.4.0 or newer and can only be used by the root module. Overriding a repository There are several reasons to override a repository generated by a module extension. It can simplify migrations by allowing existing call sites to keep using the same repository name. It can also avoid introducing multiple similarly named repositories. Most importantly, it gives module authors a way to provide a smoother developer experience when integrating with other rulesets. A good example is Keith’s hermetic
  19. Stamping iOS Builds with Bazel
    Jul 5, 2026 · original
    Stamping is the act of embedding build metadata into the product that we ship to customers. It can help with issue diagnosis, analytics, and so on. Conveniently, Bazel offers us a first-class solution, and it is very easy to take advantage of it in the context of iOS apps. Workspace status script The first step in enabling stamping is to create a workspace status script. For example, we can create a script that emits the current Git commit hash: #!/usr/bin/env bash set -eu -o pipefail echo "STABLE_GIT_COMMIT $(git rev-parse HEAD)" Now we need to tell Bazel to execute the script: --workspace_status_command=./tools/workspace_status.sh Reading the value at build time For iOS apps, or really any Apple platform app, it is usually best to embed this data in a plist file so we can read it at runtime. First, we use a genrule to read the workspace status data and materialize a plist file: genrule
  20. Making Developer Tools Available Through Bazel
    Jun 28, 2026 · original
    Traditionally, when setting up a developer machine, instructions include something like install the following tools using Homebrew . What if we could always have tools available without asking developers to install anything but Bazel? This is easily achievable with Bazel since it gives us a way to download and execute binaries. Before diving into the implementation, let s first explore the downsides of asking developers to install tools on their own. Problems with Homebrew for developer tools brew install … When developing on macOS, the default package manager is Homebrew, so we install tools like linters and formatters using it. However, it is not great for versioning in this use case. By default, we usually end up installing whatever version Homebrew currently resolves, unless we specifically do extra work to avoid that. This is the first problem: we can t expect people to ensure that

Found by rss-feed-index, which checks each feed once a month at most.

Same record as JSON: https://api.agentalog.com/api/feeds/fd_adincebic_com_549fad12b80335f2. More from this site: adincebic.com in the Feeds tab.

Looking for something else?QuestionsContact