forked from bpftrace/bpftrace
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathflake.nix
More file actions
305 lines (277 loc) · 11.5 KB
/
flake.nix
File metadata and controls
305 lines (277 loc) · 11.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
{
description = "High-level tracing language for Linux";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils";
nix-appimage = {
# We're maintaining a fork b/c upstream is missing support for unstable
# and has also dropped the following feature we depend on:
# https://github.com/ralismark/nix-appimage/pull/9
#
# Also b/c appimage-runtime (which nix-appimage depends on) has a bug
# that's being fixed in:
# https://github.com/AppImageCrafters/appimage-runtime/pull/14
url = "github:danobi/nix-appimage/74e44691812b4f220e84fd89895931ff4f904a03";
# Avoid multiple copies of the same dependency
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
};
naersk = {
url = "github:nix-community/naersk";
# See above
inputs.nixpkgs.follows = "nixpkgs";
};
blazesym = {
url = "github:libbpf/blazesym";
flake = false;
};
};
outputs = { self, nixpkgs, flake-utils, nix-appimage, naersk, blazesym, ... }:
# This flake only supports 64-bit linux systems.
# Note bpftrace support aarch32 but for simplicity we'll omit it for now.
flake-utils.lib.eachSystem [ "x86_64-linux" "aarch64-linux" ]
(system:
let
pkgs = import nixpkgs { inherit system; };
# The default LLVM version is the latest supported release
defaultLlvmVersion = 21;
# Override to specify the bcc build we want.
# We need a specific patch in BCC which resolves a build failure with
# LLVM 21 and is not a part of any official release, yet.
bccVersion = "8c5c96ad3beeed2fa827017f451a952306826974";
bcc = (pkgs.bcc.override {
llvmPackages = pkgs."llvmPackages_${toString defaultLlvmVersion}";
}).overridePythonAttrs {
version = bccVersion;
src = pkgs.fetchFromGitHub {
owner = "iovisor";
repo = "bcc";
rev = "${bccVersion}";
# See above
sha256 = "sha256-XcTqcsbyUBe83vsjUC70GoffCXaxk32QddBKFEP6LD8=";
};
};
# Download statically linked vmtest binary
arch = pkgs.lib.strings.removeSuffix "-linux" system;
vmtestVersion = "0.18.0";
# Architecture-specific SHA values.
# You can get the sha by using the trick above and running `nix develop --system aarch64-linux`.
# It'll error out on the actual build, but the SHA check is done before that.
vmtestSha = {
"x86_64" = "sha256:1wv49fq7n820jj7zyvbvrrzg2vwvyy8kb3gfw1lg55rzfqzhl9v3";
"aarch64" = "sha256:1nsq32bn6pd1gmij1qlry8ydn4gp0jdcqs030ba6yh2c30rhi02d";
};
vmtest = pkgs.stdenv.mkDerivation {
name = "vmtest";
version = vmtestVersion;
src = builtins.fetchurl {
url = "https://github.com/danobi/vmtest/releases/download/v${vmtestVersion}/vmtest-${arch}";
sha256 = vmtestSha.${arch};
};
# Remove all other phases b/c we already have a prebuilt binary
phases = [ "installPhase" ];
installPhase = ''
install -m755 -D $src $out/bin/vmtest
'';
};
# Build blazesym
blazesym_c = naersk.lib.${system}.buildPackage {
root = blazesym;
cargoBuildOptions = x: x ++ [ "-p" "blazesym-c" ];
copyLibs = true;
postInstall = ''
# Export C headers
mkdir -p $out/include
cp capi/include/*.h $out/include/
'';
};
# Define lambda that returns a derivation for a kernel given kernel version and SHA as input
mkKernel = kernelVersion: sha256:
with pkgs;
stdenv.mkDerivation rec {
name = "kernel";
version = kernelVersion;
src = builtins.fetchurl {
url = "https://github.com/bpftrace/kernels/releases/download/assets/linux-v${kernelVersion}.tar.zst";
sha256 = sha256;
};
# Remove all other phases b/c we already have a prebuilt binary
phases = [ "installPhase" ];
installPhase = ''
mkdir -p $out
tar xvf $src --strip-components=1 -C $out
'';
nativeBuildInputs = [ gnutar zstd ];
};
# Define lambda that returns a derivation for bpftrace given llvm version as input
mkBpftrace =
llvmVersion:
pkgs.stdenv.mkDerivation {
name = "bpftrace";
src = self;
nativeBuildInputs = [
pkgs.bison
pkgs.bpftools
pkgs."llvmPackages_${toString llvmVersion}".clang
pkgs.cmake
pkgs.flex
pkgs.gcc
pkgs.ninja
pkgs.pkg-config
];
buildInputs = [
bcc
blazesym_c
pkgs.asciidoctor
pkgs.cereal
pkgs.elfutils
pkgs.gtest
pkgs.libbfd
pkgs.libelf
pkgs.libffi
pkgs.libopcodes
pkgs.libpcap
pkgs.systemdLibs
pkgs."llvmPackages_${toString llvmVersion}".libclang
pkgs."llvmPackages_${toString llvmVersion}".llvm
pkgs.pahole
pkgs.xxd
pkgs.zlib
];
# Release flags
cmakeFlags = [
"-DCMAKE_BUILD_TYPE=Release"
"-DENABLE_SYSTEMD=1"
];
# Technically not needed cuz package name matches mainProgram, but
# explicit is fine too.
meta.mainProgram = "bpftrace";
};
# Define lambda that returns a devShell derivation with extra test-required packages
# given the bpftrace LLVM version as input
mkBpftraceDevShell =
llvmVersion:
let
pkg = self.packages.${system}."bpftrace-llvm${toString llvmVersion}";
in
with pkgs;
pkgs.mkShell {
buildInputs = [
bc
binutils
bpftools
coreutils
pkgs."llvmPackages_${toString llvmVersion}".clang-tools # Needed for the nix-aware "wrapped" clang-tidy
gawk
git
gnugrep
go # For runtime tests
iproute2
kmod
# For git-clang-format
pkgs."llvmPackages_${toString llvmVersion}".libclang.python
nftables
procps
python3
python3Packages.looseversion
qemu_kvm
rustc # For runtime tests
strace
unixtools.ping
util-linux
vmtest
] ++ pkg.nativeBuildInputs ++ pkg.buildInputs;
# Some hardening features (like _FORTIFY_SOURCE) requires building with
# optimizations on. That's fine for actual flake build, but for most of the
# dev builds we do in nix shell, it just causes warning spew.
hardeningDisable = [ "all" ];
};
# Ensure that the LLVM & clang version for AFL are aligned, and can
# be controlled alongside the version used for the shell environment.
mkAFL =
llvmVersion:
pkgs.aflplusplus.override {
clang = pkgs."clang_${toString llvmVersion}";
llvm = pkgs."llvmPackages_${toString llvmVersion}".llvm;
llvmPackages = pkgs."llvmPackages_${toString llvmVersion}";
};
# Lambda that can be used for a fuzzing environment. Not part of the default
# devshell because aflplusplus is only available for x86_64/amd64.
mkBpftraceFuzzShell =
llvmVersion: shell:
let
afl = mkAFL llvmVersion;
in
with pkgs;
pkgs.mkShell {
nativeBuildInputs = shell.nativeBuildInputs;
buildInputs = [ afl ] ++ shell.buildInputs;
# See above.
hardeningDisable = [ "all" ];
};
in
{
# Set formatter for `nix fmt` command
formatter = pkgs.nixpkgs-fmt;
# Define package set
packages = rec {
default = self.packages.${system}."bpftrace-llvm${toString defaultLlvmVersion}";
# Support matrix of llvm versions
bpftrace-llvm21 = mkBpftrace 21;
bpftrace-llvm20 = mkBpftrace 20;
bpftrace-llvm19 = mkBpftrace 19;
bpftrace-llvm18 = mkBpftrace 18;
bpftrace-llvm17 = mkBpftrace 17;
# Self-contained static binary with all dependencies
appimage = nix-appimage.mkappimage.${system} {
drv = default;
entrypoint = pkgs.lib.getExe default;
name = default.name;
# Exclude the following groups to reduce appimage size:
#
# *.a: Static archives are not necessary at runtime
# *.h: Header files are not necessary at runtime (some ARM headers for clang are large)
# *.py, *.pyc, *.whl: bpftrace does not use python at runtime
# libLLVM-11.so: Appimage uses the latest llvm we support, so not llvm11
#
# The basic process to identify large and useless files is to:
#
# ```
# $ nix build .#appimage
# $ ./result --appimage-mount
# $ cd /tmp/.mount_resultXXXX # in new terminal
# $ fd -S +1m -l
# ```
exclude = [
"... *.a"
"... *.h"
"... *.py"
"... *.pyc"
"... *.whl"
"... libLLVM-11.so"
];
};
# Kernels to run runtime tests against
kernel-6_14 = mkKernel "6.14.4" "sha256:0gvbw38vmbccvz64b3ljqiwkkgil0hgnlakpdjang038pxsxddmr";
};
# Define apps that can be run with `nix run`
apps.default = {
type = "app";
program = "${self.packages.${system}.default}/bin/bpftrace";
};
devShells = rec {
default = self.devShells.${system}."bpftrace-llvm${toString defaultLlvmVersion}";
bpftrace-llvm21 = mkBpftraceDevShell 21;
bpftrace-llvm20 = mkBpftraceDevShell 20;
bpftrace-llvm19 = mkBpftraceDevShell 19;
bpftrace-llvm18 = mkBpftraceDevShell 18;
bpftrace-llvm17 = mkBpftraceDevShell 17;
# Note that we depend on LLVM 18 explicitly for the fuzz shell, and
# this is managed separately. The version of LLVM used to build the
# tool must be the same as the version linked as a dependency, or
# strange things happen. Hopefully this is a simple update, where
# both numbers are bumped at the same time.
bpftrace-fuzz = mkBpftraceFuzzShell 18 self.devShells.${system}."bpftrace-llvm18";
};
});
}