@@ -4,23 +4,20 @@ author: Brian Shirai
44date: 2025-11-16T12:01:00Z
55---
66
7- ## D. R. A. F. T.
8-
97*"Like fences make good neighbors, boundaries make good systems."*—Probably
108Someone Famous
119
12- If someone famous didn't say that, they probably should have, but I'll take
13- credit so it's not just some anonymous thing floating out there like an orphan.
10+ If someone famous didn't say that, they probably should have.
1411
1512But regardless of which precise words an LLM might use to construct such a
1613sentence from the ruminations of billions of people, the idea is pretty simple,
1714and profound.
1815
19- I'd go so far as to say that without it, no life would exist. Because, in
20- fact, this is precisely how life works. I learned that this probably has to do
21- with how the ratio of surface area to volume of a cell changes as the dimenions
22- of the cell grows and the need to transport energy materials and waste across
23- that cell boundary.
16+ I'd go so far as to say that without it, no life would exist. Because, in fact,
17+ this is precisely how life works. I learned that this probably has to do with
18+ how the ratio of surface area to volume of a cell changes as the dimensions of
19+ the cell grows and the need to transport energy materials and waste across that
20+ cell boundary.
2421
2522In the artificial (i.e. not living) things humans muster, there is not this
2623obvious constraint, and so things like
@@ -31,4 +28,128 @@ this guy who told me, "I believe in monorepos' like they're some kind of
3128middle-tier deity) long after they should be historical footnotes in obscure
3229compsci trivia.
3330
31+ Alas, we soldier on...
32+
33+ ## Building Complex Systems
34+
35+ Building complex software systems is hard, no question about that. How we
36+ choose to approach it offers quite a bit of latitude.
37+
38+ There are four audiences for a software component:
39+
40+ 1. Core developers
41+ 1. Contributors
42+ 1. System maintainers / packagers
43+ 1. End users
44+
45+ **Core developers** need sharp tools and use them often. They want quick
46+ development cycles, and they want to be able to merge contributions with
47+ confidence.
48+
49+ **Contributors** need an extremely smooth getting started experience and ease in
50+ adding their contributions.
51+
52+ Almost every flavor of Unix/Linux has its unique way of building and
53+ maintaining software packages for that system. System **package maintainers**
54+ want the least friction possible when packaging for their system. Usually, this
55+ means using as standard as possible build systems and parameterizing things so
56+ they can be customized to the system's approach without maintaining brittle
57+ patchsets.
58+
59+ **End users** want to install a package on their favorite system and get value from
60+ using a piece of software with as little effort as possible.
61+
62+ Among these four audiences, if anyone is going to suffer, it has to be the core
63+ developers. If the package managers have to deal with a lot of frustration,
64+ they will either hate you or just not support your package.
65+
66+ If contributors have to deal with a lot of confusing steps or cumbersome
67+ dependencies, they just won't waste their time.
68+
69+ If you don't have contributors and package maintainers, you will have very few
70+ users.
71+
72+ ## Building Rubinius Before
73+
74+ Rubinius is not an easy project to build. It was entering an existing
75+ ecosystem, and some of the difficulty derived from that ecosystem.
76+
77+ For example, Ruby has an extremely complex encoding system that required a
78+ custom encoding engine that wasn't easily available as a system package or
79+ robust separate library. So, we had to maintain that.
80+
81+ These were all the "external" libraries that Rubinius vendored and maintained
82+ to make it as easy as possible for people to build the project:
83+
84+ * double-conversion
85+ * libffi
86+ * libsodium
87+ * libtommath
88+ * oniguruma
89+ * rapidjson
90+ * winpthreads
91+ * zlib
92+
93+ Since Rubinius started as an implementation of Ruby, and since Rake is a
94+ beloved tool used in the Ruby ecosystem, it made sense to implement the build
95+ system in Rake. We wanted the experience to be as simple as:
96+
97+ 1. Clone [https://github.com/rubinius/rubinius](https://github.com/rubinius/rubinius)
98+ 2. Run `rake`
99+ 3. Enjoy!
100+
101+ Since Rubinius started using LLVM to implement the machine code JIT
102+ (just-in-time) compiler around LLVMv3 when there was very little system
103+ package support for LLVM, we also pre-built and hosted versions of the library
104+ for various operating systems.
105+
106+ These efforts were certainly not without merit, and Rubinius was pretty easy to
107+ work on. In fact, almost 400 people have contributed to the project.
108+
109+ But it was not pleasant for various package maintainers. Having Ruby as a build
110+ requirement caused a lot of problems. Vendoring libraries like zlib got us
111+ yelled at by maintainers, but for good reason. If projects like Rubinius vendor
112+ libraries like zlib, it makes it really hard for system maintainers to know
113+ that they've patched all the vulnerabilities in a specific library when they
114+ are discovered and fixed.
115+
116+ ## A build2 Future
117+
118+ The [build2](https://www.build2.org) project "is a hierarchy of tools
119+ consisting of a general-purpose build system, package manager (for package
120+ consumption), and project manager (for project development)."
121+
122+ It's basically everything I wanted more than 15 years ago when I was wiring
123+ everything together with Rake and shell scripts, but they only started working
124+ on it about 10 years ago.
125+
126+ One of the most valuable aspects of build2 is that it implements a ["multi-repo
127+ first"](https://www.build2.org/faq.xhtml#what) approach.
128+
129+ The Rubinius language platform is made up of various components, some of which
130+ are maintained by other groups. The purpose of the new [build
131+ repository](https://github.com/rubinius/build) is to provide a way to build
132+ everything at once, while still maintaining the boundaries around the
133+ individual components.
134+
135+ The approach used here tries to strike a balance as follows:
136+
137+ * Keep boundaries as tight as possible: Don't vendor things that are separate
138+ components. Don't add significant build dependencies, like Ruby.
139+ * Keep build steps explicit and "accessible": Build steps are combined into
140+ build scripts invoked as make targets. They can be decomposed and recomposed
141+ in packaging systems without burdening the package managers with writing
142+ extra custom code. The more granular and standard, the more likely a system
143+ package manager can be easily configured for your project's "recipe".
144+ * Make it easy to clone and go, there should be no step 3. For example, clone
145+ the repo, type `make` or maybe `make help` and then `make`.
146+
147+ There's still work to do, but with the new approach, it's still as easy as:
148+
149+ 1. Clone [https://github.com/rubinius/build](https://github.com/rubinius/build)
150+ 2. Run `make`
151+ 3. Enjoy!
34152
153+ Meanwhile, if you want to get Rubinius from a system package, the chances it'll
154+ be there are much greater because the experience for package maintainers will
155+ be nearly as smooth and simple.
0 commit comments