labs/tidepool/src/packages
2025-10-28 02:25:31 +00:00
..
aux refactor: remove target (#31) 2025-10-07 03:46:52 +00:00
core refactor: namespace builders 2025-09-14 09:27:13 -07:00
foundation gnutar: Make bootstrap bash reproducible by default 2025-10-28 02:25:31 +00:00
default.nix fix: Correctly resolve packages from preferences.packages.version (#33) 2025-10-04 00:40:05 +00:00
README.md docs: update build instructions and foundation (#38) 2025-10-15 03:21:49 +00:00

Packages

In this folder, the Tidepool package sets are stored.

Foundation

The package set under foundation is a minimal set to start building everything else. It provides a comprehensive set of packages that are used to build all other basic Linux utilities, and are often transitive dependencies of higher-level packages.

The goal of foundation is to build gcc and glibc, as well as some supplementary packages, so that other packages can be built with them. It also sets up a basic Linux environment: coreutils, diffutils, bash, and other utilities you'd expect to find on a Linux distro.

To achieve this, we need a lot of other packages built, too! Some examples include python, xz and gzip.

Lastly, foundation also includes patchelf, a simple C utility. It is not used in foundation, but it is very useful for building more high-level packages: in particular, it allows us to patch binaries to point to our dependencies. This "unbreaks" proprietary binaries by making them point to Tidepool-provided dependencies. Neat!

The foundation package set builds upon and uses packages from Foundation, our early bootstrap chain. It augments the packages from Foundation with Tidepool's cross-compilation capabilities, and adds additional flags to compilers to better support our use case.

Aux

aux, at this time, is a trivial package set that demonstrates the power of a fully-bootstrapped foundation. It consists of 3 trivial packages: a, b and c. The chain of dependencies is like this (the arrow points to the dependency):

a -> b -> c

Package a merely depends on b.

Package b announces a build option custom. It sets up context and sets up a hook after unpack phase. It also propagates dependency c. It's worth discussing this in more depth, because it demonstrates a couple of more advanced features.

context is information that the package provides when it is used as dependency, which builders and hooks may use. For example, to use a C dependency, you would need to tell the compiler where to look for relevant headers by appending a flag. The C dependency can have context defined which includes the necessary compiler flag, and the package that uses this dependency will append this flag automatically.

Nixpkgs uses a different approach to do this. In Nixpkgs, packages include the nix-support subdirectory which contains the same information as what context usually contains. Nixpkgs does this in the builder code at build-time; Tidepool provides this information at eval time, which provides the means to type-check the context.

Package b provides a context to include the necessary directory: include under the Nix store path for package b. This Nix store path is provided as an environment variable from a hook.

While Tidepool's architecture is subject to change, context already has planned changes for it. When those changes happen - the information about context will be moved to a historical design doc. But until then, context is still relevant!

hooks provide extension points for packages. With hooks, you can inject arbitrary build instructions between, before or after the default build stages. Package b does exactly that: it uses a hook to add entry after unpack phase and before others, which exports an environment variable that contains the Nix store path, that is then used for context.

Propagation ensures that the propagated dependency is also installed, when the package is installed. Package b propagates dependency c - this means, when package b is included as a dependency, package c is also included automatically. This is especially useful when working with interpreted languages, such as Python - for them, all dependencies need to be in a single scope, and propagation makes sure of that.

Package c doesn't have dependencies, but it is otherwise identical to package b.