blob: 9d0113f0e3ee1777e02ec2d3226e2a4caa88e538 [file] [log] [blame] [view]
Leopolde1ebf722023-01-08 14:18:15 +01001# How to set up a build environment
2
3We strongly recommend a Linux workstation - it offers the
Leopold Schabela5a81702025-06-25 20:45:25 +02004best developer experience. NixOS, Fedora or Ubuntu are good choices.
5
6On Windows, use WSL2. Building on ARM64 - including on Apple Silicon Macs (M1, M2, etc.) - will be supported soon.
Leopolde1ebf722023-01-08 14:18:15 +01007
8The more CPU cores, the merrier - our build is fully parallelized, but the monorepo builds
9a LOT of stuff, including all of EDK2, QEMU, the Linux kernel, Kubernetes... Bazel is smart about
10not rebuilding things that haven't changed, but sometimes, you'll still be hit with a full rebuild
11(such as when the sysroot or Bazel version changes).
12
13We will offer pre-warmed build caches in the future, but for now, bring a big rig!
14
15## Dependencies
16
17Monogon's monorepo uses [Bazel](https://bazel.build) for fast, hermetic and fully reproducible builds.
18
19Our build environment brings its own hermetic and reproducible sysroot,
20so we only require minimal host dependencies:
21
22- Any Linux distribution with a reasonably recent kernel with unprivileged
23 user namespaces enabled. Bazel requires user namespaces to set up its hermetic per-action
24 sandbox without special privileges or capabilities.
25
26- [Bazelisk](https://github.com/bazelbuild/bazelisk) >= v1.15.0. Bazel is serious about breaking
27 backwards compatibility with each major release, so you need the right version to build the repo.
28 Bazelisk downloads (and verifies) the correct version of Bazel for you. It's the de-facto standard
29 way of using Bazel, a bit like rustup is for Rust users.
30
31The following distributions are known to work:
32
Leopold Schabela5a81702025-06-25 20:45:25 +020033- NixOS (see below)
34- Fedora
35- Ubuntu
Leopolde1ebf722023-01-08 14:18:15 +010036- Debian >= 11
37- RHEL / Alma / Rocky >= 8.4
Leopolde1ebf722023-01-08 14:18:15 +010038
39You can use this snippet to install the official Bazelisk release binary to `/usr/local/bin`:
40
41```bash
42TMPFILE=$(mktemp) && \
43 curl -L -o $TMPFILE \
Leopold Schabela5a81702025-06-25 20:45:25 +020044 https://github.com/bazelbuild/bazelisk/releases/download/v1.26.0/bazelisk-linux-amd64 && \
45 sha256sum -c - <<< "6539c12842ad76966f3d493e8f80d67caa84ec4a000e220d5459833c967c12bc $TMPFILE" && \
Leopolde1ebf722023-01-08 14:18:15 +010046 sudo install -m 0755 $TMPFILE /usr/local/bin/bazel && \
47 rm $TMPFILE
48```
49
50Alternatively, if you have a Go >= 1.16 toolchain, you can compile it yourself:
51
52```bash
53# This uses Go's transparency log for pinning to ensure the release hasn't been tampered with.
Leopold Schabela5a81702025-06-25 20:45:25 +020054go install github.com/bazelbuild/bazelisk@v1.26.0
Leopolde1ebf722023-01-08 14:18:15 +010055sudo mv ~/go/bin/bazelisk /usr/local/bin/bazel
56```
57
58### /dev/kvm access for test suites
59
60Monogon's tests make extensive use of KVM to run virtual machines, both to test the OS as well
61as running various microVM-based unit tests. If you want to run all tests, you'll need to make sure
62that your local user has access to `/dev/kvm`. You can check this by running `touch /dev/kvm`.
63
64If you only want to build artifacts without running tests, no KVM access is required.
65
66On most Linux distributions, you can add your user to the `kvm` group to allow access to `/dev/kvm`:
67
68```bash
69sudo gpasswd -a $USER kvm
70# re-login or run "sudo -u $USER -i" to get a shell with the new group membership
71```
72
73If you are running in a virtual machine, make sure that your virtualization software supports
74nested virtualization - otherwise, it won't be possible to use KVM inside the VM.
75
76`/dev/kvm` is considered safe to use by unprivileged users. All of Monogon's monorepo can
77be built and tested without root privileges or other dangerous capabilities.
78
79### NixOS
80
Leopold Schabel67023fe2023-08-14 12:36:35 +000081We fully support building on NixOS, and we provide a `shell.nix` file to make it easy. Just run `nix-shell` in the
82project root! This will drop you into a shell with all dependencies installed, and you can run `bazel ...` as usual.
Leopold Schabel9508b122023-07-14 17:54:17 +020083
Leopold Schabela5a81702025-06-25 20:45:25 +020084You can also execute tools/bazel directly on a system with Nix installed. The wrapper automatically uses the nix-shell.
85
86## VSCode / gopls
87
88The monorepo is compatible with gopls via GOPACKAGESDRIVER, which uses a Bazel backend to resolve generated code.
89
90The [included VSCode workspace config](.vscode/settings.json) should work out of the box.
91
92The following extensions are recommended:
93- [Go](https://marketplace.visualstudio.com/items?itemName=golang.go)
94- [proto3](https://marketplace.visualstudio.com/items?itemName=zxh404.vscode-proto3)
95- [Bazel](https://marketplace.visualstudio.com/items?itemName=BazelBuild.vscode-bazel)
96
Leopolde1ebf722023-01-08 14:18:15 +010097
98## IntelliJ
99
100This repository is compatible with the IntelliJ Bazel plugin out of the box, which enables
101full autocompletion for external dependencies and generated code.
102
103The following steps are necessary:
104
105- Install the [Bazel](https://plugins.jetbrains.com/plugin/8609-bazel),
106 Go and Protocol Buffer plugins in IntelliJ.
Leopold Schabele18cf272025-07-08 16:56:03 +0200107- Make sure that Bazel "*Bazel Binary Location*" in Other Settings Bazel Settings points to Bazelisk
108 (or tools/bazel, if you're on NixOS).
Leopolde1ebf722023-01-08 14:18:15 +0100109- Use _File → Import Bazel project_... and select your monorepo checkout.
110
111After running the first sync (Alt-Y), everything should now resolve in the IDE, including generated code.
112Whenever the project structure changes, re-run the sync to update the IDE.
113
114It can be useful to configure an External Tool to run Gazelle and add a keyboard shortcut
115to quickly run it after changing the project layout.
116
117## Trouble?
118
119Developer experience is very important. Please file a GitHub issue if you run into any problems
120or encounter any pain points - we want to fix them!