← Back to context

Comment by skrtskrt

19 hours ago

> It's a big glob of homegrown thoughts and ideas. Some of them are really slick, like build deduplication. Others are clever and hard to reason about, or in the worst case, terrifying to touch.

This is true of packaging and build systems in general. They are often the passion projects of one or a handful of people in an organization - by the time they have active outside development, those idiosyncratic concepts are already ossified.

It's really rare to see these sorts of projects decomposed into building blocks even just having code organization that helps a newcomer understand. Despite all the code being out in public, all the important reasoning about why certain things are the way they are is trapped inside a few dev's heads.

As someone who has worked in the space for a while and been heavily exposed to nix, bazel, cmake, bake, and other systems, and also been in that "passion project" role, I think what I've found is that these kinds of systems are just plain hard to talk about. Even the common elements like DAGs cause most people's eyes to immediately glaze over.

Managers and executives are happy to hear that you made the builds faster or more reliable, so the infra people who care about this kind of thing don't waste time on design docs and instead focus on getting to a minimum prototype that demonstrates those improved metrics. Once you have that, then there's buy-in and the project is made official... but by then the bones have already been set in place, so design documentation ends up focused on the more visible stuff like user interface, storage formats, etc.

OTOH, bazel (as blaze) was a very intentionally designed second system at Google, and buildx/buildkit is similarly a rewrite of the container builder for Docker, so both of them should have been pretty free of accidental engineering in their early phases.

  • I don't think you can ever get away from accidental engineering in build systems because as soon as they find their niche something new comes along to disrupt it. Even with something homegrown out of shell scripts and directory trees the boss will eventually ask you to do something that doesn't fit well with your existing concepts.

    A build system is meant to yield artifacts, run tools, parallelize things, calculate dependencies, download packages, and more. And these are all things that have some algorithmic similarity which is a kind of superficial similarity in that the failure modes and the exact systems involved are often dramatically different. I don't know that you can build something that is that all-encompassing without compromising somewhere.

  • Blaze and bazel may have been intentionally designed, but it was designed for Google's needs, and it shows (at least from my observations of bazel, I don't have any experience with blaze). It is better now than it was, but it obviously was designed for a system where most dependencies are vendored, and worked better for languages that google used like c++, java, and python.

    • Blaze instead of make, ant, maven. But now there's cmake and ninjabuild. gn wraps ninjabuild wraps cmake these days fwiu.

      Blaze is/was integrated with Omega scheduler, which is not open.

      Bazel is open source.

      By the time Bazel was open sourced, Twitter had pantsbuild and Facebook had buck.

      OpenWRT's Makefiles are sufficient to build OpenWRT and the kernel for it. (GNU Make is still sufficient to build the Linux kernel today, in 2026.)

      Make compares files to determine whether to rebuild them if they already exist; by comparing file modification time (mtime) unless the task name is in the .PHONY: list at the top of the Makefile. But the task names may not contain slashes or spaces.

      `docker build` and so also BuildKit archive the build chroot after each build step that modifies the filesystem (RUN, ADD, COPY) as a cacheable layer identified by a hash of its content.

      Other Dockerfile instructions add metadata: CMD, ENTRYPOINT, LABEL, ENV, ARG, WORKDIR, USER, EXPOSE <port/tcp>, VOLUME <path>.

      The FROM instruction creates a build stage from scratch or from a different container layer.

      Dockerfile added support for Multi-stage builds with multiple `FROM` instructions in 2017 (versions 17.05, 17.06CE).

      `docker build` is now moby and there is also buildkit? `podman buildx` seems to work.

      nerdctl supports a number of features that have not been merged back to docker or to podman.

      > it obviously was designed for a system where most dependencies are vendored, and worked better for languages that google used like c++, java, and python.

      Those were the primary languages at google at the time. And then also to build software? Make, shell scripts, python, that Makefile calls git which calls perl so perl has to be installed, etc.

      Also gtests and gflags.

      "Compiler Options Hardening Guide for C and C++" https://news.ycombinator.com/item?id=43551959 :

      >> There are default gcc and/or clang compiler flags in distros' default build tools; e.g. `make` specifies additional default compiler flags (that e.g. cmake, ninja, gn, or bazel/buck/pants may not also specify for you).

      Which CPU microarchitectures and flags are supported?

        ld.so --help | grep "supported"
        cat /proc/cpuinfo | grep -E '^(flags|bugs)'` 
      

      AVX-512 is in x86-64-v3. By utilizing features like AVX-512, we would save money (by utilizing features in processors newer than Pentium 4 (x86-64-v1)).

      How to add an `-march=x86-64-v3` argument to every build?

      How to add build flags to everything for something like x86-64-v4?

      Which distros support consistent build parametrization to make adding global compiler build flags for multiple compilers?

      - Gentoo USE flags

      - rebuild a distro and commit to building the core and updates and testing and rawhide with your own compiler flags and package signatures and host mirrored package repos

      - Intel Clear Linux was cancelled.

      - CachyOS (x86-64-v3, x86-64-v4, Zen4)

      - conda-forge?

      Gentoo:

      - ChromiumOS was built on gentoo and ebuild IIRC

      - emerge app-portage/cpuid2cpuflags, CPU_FLAGS_X86=, specify -march=native for C/[C++] and also target-cpu=native for Rust in /etc/portage/make.conf

      - "Gentoo x86-64-v3 binary packages available" (2024) https://news.ycombinator.com/item?id=39250609

      Google, Facebook, and Twitter have a monorepo to build packages from.

      Google had a monorepo at the time that blaze was written.

      Twitter ("X") is moving from pantsbuild to blaze BUILD files.

      TIL there is a buck2. How does facebook/buck2 compare to google/bazel (compare to what is known about blaze)?

      Should I build containers (chroot fs archives) with ansible? Then there is no buildkit.

      FWIW `podman-kube-play` can run some kubernetes yaml.

      1 reply →

> This is true of packaging and build systems in general. They are often the passion projects of one or a handful of people in an organization

This is a very insightful comment