1{
2 lib,
3 llvmPackages,
4 fetchFromGitHub,
5 writeShellScript,
6 bash,
7 meson,
8 ninja,
9 jq,
10 pkg-config,
11 bpftools,
12 elfutils,
13 zlib,
14 zstd,
15 scx-common,
16 protobuf,
17 libseccomp,
18}:
19
20let
21 # Fixes a bug with the meson build script where it specifies
22 # /bin/bash twice in the script
23 misbehaviorBash = writeShellScript "bash" ''
24 shift 1
25 exec ${lib.getExe bash} "$@"
26 '';
27
28in
29llvmPackages.stdenv.mkDerivation (finalAttrs: {
30 pname = "scx_cscheds";
31 inherit (scx-common) version src;
32
33 # scx needs specific commits of bpftool and libbpf
34 # can be found in meson.build of scx src
35 # grep 'bpftool_commit =' ./meson.build
36 bpftools_src = fetchFromGitHub {
37 owner = "libbpf";
38 repo = "bpftool";
39 inherit (scx-common.versionInfo.bpftool) rev hash;
40 fetchSubmodules = true;
41 };
42 # grep 'libbpf_commit = ' ./meson.build
43 libbpf_src = fetchFromGitHub {
44 owner = "libbpf";
45 repo = "libbpf";
46 inherit (scx-common.versionInfo.libbpf) rev hash;
47 fetchSubmodules = true;
48 };
49
50 # this imitates the fetch_bpftool and fetch_libbpf script in src/meson-scripts
51 fetchBpftool = writeShellScript "fetch_bpftool" ''
52 [ "$2" == '${finalAttrs.bpftools_src.rev}' ] || exit 1
53 cd "$1"
54 cp --no-preserve=mode,owner -r "${finalAttrs.bpftools_src}/" ./bpftool
55 '';
56 fetchLibbpf = writeShellScript "fetch_libbpf" ''
57 [ "$2" == '${finalAttrs.libbpf_src.rev}' ] || exit 1
58 cd "$1"
59 cp --no-preserve=mode,owner -r "${finalAttrs.libbpf_src}/" ./libbpf
60 mkdir -p ./libbpf/src/usr/include
61 '';
62
63 postPatch = ''
64 rm meson-scripts/fetch_bpftool meson-scripts/fetch_libbpf
65 patchShebangs ./meson-scripts
66 cp ${finalAttrs.fetchBpftool} meson-scripts/fetch_bpftool
67 cp ${finalAttrs.fetchLibbpf} meson-scripts/fetch_libbpf
68 substituteInPlace meson.build \
69 --replace-fail '[build_bpftool' "['${misbehaviorBash}', build_bpftool"
70
71 # TODO: Remove in next release.
72 substituteInPlace lib/scxtest/overrides.h \
73 --replace-fail '#define __builtin_preserve_enum_value(x,y,z) 1' '#define __builtin_preserve_enum_value(x,y) 1'
74 '';
75
76 nativeBuildInputs = [
77 meson
78 ninja
79 jq
80 pkg-config
81 zstd
82 protobuf
83 llvmPackages.libllvm
84 ]
85 ++ bpftools.buildInputs
86 ++ bpftools.nativeBuildInputs;
87
88 buildInputs = [
89 elfutils
90 zlib
91 libseccomp
92 ];
93
94 mesonFlags = [
95 (lib.mapAttrsToList lib.mesonEnable {
96 # systemd unit is implemented in the nixos module
97 # upstream systemd files are a hassle to patch
98 "systemd" = false;
99 # not for nix
100 "openrc" = false;
101 "libalpm" = false;
102 })
103 (lib.mapAttrsToList lib.mesonBool {
104 # needed libs are already fetched as FOD
105 "offline" = true;
106 # rust based schedulers are built separately
107 "enable_rust" = false;
108 })
109 # Clang to use when compiling .bpf.c
110 (lib.mesonOption "bpf_clang" (lib.getExe llvmPackages.clang))
111 ];
112
113 hardeningDisable = [
114 "stackprotector"
115 "zerocallusedregs"
116 ];
117
118 # We copy the compiled header files to the dev output
119 # These are needed for the rust schedulers
120 postFixup = ''
121 mkdir -p ${placeholder "dev"}
122 cp -r libbpf ${placeholder "dev"}
123 '';
124
125 outputs = [
126 "bin"
127 "dev"
128 "out"
129 ];
130
131 doCheck = true;
132
133 meta = scx-common.meta // {
134 description = "Sched-ext C userspace schedulers";
135 longDescription = ''
136 This includes C based schedulers such as scx_central, scx_flatcg,
137 scx_nest, scx_pair, scx_qmap, scx_simple, scx_userland.
138
139 ::: {.note}
140 Sched-ext schedulers are only available on kernels version 6.12 or later.
141 It is recommended to use the latest kernel for the best compatibility.
142 :::
143 '';
144 };
145})