| Leopold | e1ebf72 | 2023-01-08 14:18:15 +0100 | [diff] [blame] | 1 | # How to set up a build environment |
| 2 | |
| 3 | We strongly recommend a Linux workstation - it offers the |
| Leopold Schabel | a5a8170 | 2025-06-25 20:45:25 +0200 | [diff] [blame] | 4 | best developer experience. NixOS, Fedora or Ubuntu are good choices. |
| 5 | |
| 6 | On Windows, use WSL2. Building on ARM64 - including on Apple Silicon Macs (M1, M2, etc.) - will be supported soon. |
| Leopold | e1ebf72 | 2023-01-08 14:18:15 +0100 | [diff] [blame] | 7 | |
| 8 | The more CPU cores, the merrier - our build is fully parallelized, but the monorepo builds |
| 9 | a LOT of stuff, including all of EDK2, QEMU, the Linux kernel, Kubernetes... Bazel is smart about |
| 10 | not 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 | |
| 13 | We will offer pre-warmed build caches in the future, but for now, bring a big rig! |
| 14 | |
| 15 | ## Dependencies |
| 16 | |
| 17 | Monogon's monorepo uses [Bazel](https://bazel.build) for fast, hermetic and fully reproducible builds. |
| 18 | |
| 19 | Our build environment brings its own hermetic and reproducible sysroot, |
| 20 | so 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 | |
| 31 | The following distributions are known to work: |
| 32 | |
| Leopold Schabel | a5a8170 | 2025-06-25 20:45:25 +0200 | [diff] [blame] | 33 | - NixOS (see below) |
| 34 | - Fedora |
| 35 | - Ubuntu |
| Leopold | e1ebf72 | 2023-01-08 14:18:15 +0100 | [diff] [blame] | 36 | - Debian >= 11 |
| 37 | - RHEL / Alma / Rocky >= 8.4 |
| Leopold | e1ebf72 | 2023-01-08 14:18:15 +0100 | [diff] [blame] | 38 | |
| 39 | You can use this snippet to install the official Bazelisk release binary to `/usr/local/bin`: |
| 40 | |
| 41 | ```bash |
| 42 | TMPFILE=$(mktemp) && \ |
| 43 | curl -L -o $TMPFILE \ |
| Leopold Schabel | a5a8170 | 2025-06-25 20:45:25 +0200 | [diff] [blame] | 44 | https://github.com/bazelbuild/bazelisk/releases/download/v1.26.0/bazelisk-linux-amd64 && \ |
| 45 | sha256sum -c - <<< "6539c12842ad76966f3d493e8f80d67caa84ec4a000e220d5459833c967c12bc $TMPFILE" && \ |
| Leopold | e1ebf72 | 2023-01-08 14:18:15 +0100 | [diff] [blame] | 46 | sudo install -m 0755 $TMPFILE /usr/local/bin/bazel && \ |
| 47 | rm $TMPFILE |
| 48 | ``` |
| 49 | |
| 50 | Alternatively, 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 Schabel | a5a8170 | 2025-06-25 20:45:25 +0200 | [diff] [blame] | 54 | go install github.com/bazelbuild/bazelisk@v1.26.0 |
| Leopold | e1ebf72 | 2023-01-08 14:18:15 +0100 | [diff] [blame] | 55 | sudo mv ~/go/bin/bazelisk /usr/local/bin/bazel |
| 56 | ``` |
| 57 | |
| 58 | ### /dev/kvm access for test suites |
| 59 | |
| 60 | Monogon's tests make extensive use of KVM to run virtual machines, both to test the OS as well |
| 61 | as running various microVM-based unit tests. If you want to run all tests, you'll need to make sure |
| 62 | that your local user has access to `/dev/kvm`. You can check this by running `touch /dev/kvm`. |
| 63 | |
| 64 | If you only want to build artifacts without running tests, no KVM access is required. |
| 65 | |
| 66 | On most Linux distributions, you can add your user to the `kvm` group to allow access to `/dev/kvm`: |
| 67 | |
| 68 | ```bash |
| 69 | sudo gpasswd -a $USER kvm |
| 70 | # re-login or run "sudo -u $USER -i" to get a shell with the new group membership |
| 71 | ``` |
| 72 | |
| 73 | If you are running in a virtual machine, make sure that your virtualization software supports |
| 74 | nested 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 |
| 77 | be built and tested without root privileges or other dangerous capabilities. |
| 78 | |
| 79 | ### NixOS |
| 80 | |
| Leopold Schabel | 67023fe | 2023-08-14 12:36:35 +0000 | [diff] [blame] | 81 | We fully support building on NixOS, and we provide a `shell.nix` file to make it easy. Just run `nix-shell` in the |
| 82 | project root! This will drop you into a shell with all dependencies installed, and you can run `bazel ...` as usual. |
| Leopold Schabel | 9508b12 | 2023-07-14 17:54:17 +0200 | [diff] [blame] | 83 | |
| Leopold Schabel | a5a8170 | 2025-06-25 20:45:25 +0200 | [diff] [blame] | 84 | You can also execute tools/bazel directly on a system with Nix installed. The wrapper automatically uses the nix-shell. |
| 85 | |
| 86 | ## VSCode / gopls |
| 87 | |
| 88 | The monorepo is compatible with gopls via GOPACKAGESDRIVER, which uses a Bazel backend to resolve generated code. |
| 89 | |
| 90 | The [included VSCode workspace config](.vscode/settings.json) should work out of the box. |
| 91 | |
| 92 | The 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 | |
| Leopold | e1ebf72 | 2023-01-08 14:18:15 +0100 | [diff] [blame] | 97 | |
| 98 | ## IntelliJ |
| 99 | |
| 100 | This repository is compatible with the IntelliJ Bazel plugin out of the box, which enables |
| 101 | full autocompletion for external dependencies and generated code. |
| 102 | |
| 103 | The 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 Schabel | e18cf27 | 2025-07-08 16:56:03 +0200 | [diff] [blame] | 107 | - Make sure that Bazel "*Bazel Binary Location*" in Other Settings → Bazel Settings points to Bazelisk |
| 108 | (or tools/bazel, if you're on NixOS). |
| Leopold | e1ebf72 | 2023-01-08 14:18:15 +0100 | [diff] [blame] | 109 | - Use _File → Import Bazel project_... and select your monorepo checkout. |
| 110 | |
| 111 | After running the first sync (Alt-Y), everything should now resolve in the IDE, including generated code. |
| 112 | Whenever the project structure changes, re-run the sync to update the IDE. |
| 113 | |
| 114 | It can be useful to configure an External Tool to run Gazelle and add a keyboard shortcut |
| 115 | to quickly run it after changing the project layout. |
| 116 | |
| 117 | ## Trouble? |
| 118 | |
| 119 | Developer experience is very important. Please file a GitHub issue if you run into any problems |
| 120 | or encounter any pain points - we want to fix them! |