1{
2 lib,
3 makeWrapper,
4 fetchFromGitHub,
5 rustPackages,
6 pkg-config,
7 elfutils,
8 zlib,
9}:
10let
11 inherit (rustPackages.rustc) llvmPackages;
12 inherit (rustPackages) rustPlatform;
13 bpftool = llvmPackages.stdenv.mkDerivation {
14 pname = "bpftool";
15 version = "0-unstable-2023-03-11";
16
17 # this fork specialized for some functions
18 # and has eventually been embedded into the ecc binary
19 src = fetchFromGitHub {
20 owner = "eunomia-bpf";
21 repo = "bpftool";
22 rev = "05940344f5db18d0cb1bc1c42e628f132bc93123";
23 hash = "sha256-g2gjixfuGwVnFlqCMGLWVPbtKOSpQI+vZwIZciXFPTc=";
24 fetchSubmodules = true;
25 };
26
27 buildInputs = [
28 llvmPackages.libllvm
29 elfutils
30 zlib
31 ];
32
33 buildPhase = ''
34 make -C src
35 '';
36
37 installPhase = ''
38 # We don't use the default `make install` because we are looking to create a
39 # directory structure compatible with `build.rs` of `ecc`.
40 mkdir -p $out/src/libbpf
41 # some headers are required
42 cp -r src/libbpf/include $out/src/libbpf
43 cp src/bpftool $out/src
44 '';
45 };
46
47 vmlinux-headers = fetchFromGitHub {
48 owner = "eunomia-bpf";
49 repo = "vmlinux";
50 rev = "933f83becb45f5586ed5fd089e60d382aeefb409";
51 hash = "sha256-CVEmKkzdFNLKCbcbeSIoM5QjYVLQglpz6gy7+ZFPgCY=";
52 };
53
54in
55rustPlatform.buildRustPackage rec {
56 pname = "ecc";
57 version = "1.0.27";
58
59 src = fetchFromGitHub {
60 owner = "eunomia-bpf";
61 repo = "eunomia-bpf";
62 rev = "v${version}";
63 hash = "sha256-KfYCC+TJbmjHrV46LoshD+uXcaBVMKk6+cN7TZKKYp4=";
64 };
65
66 sourceRoot = "${src.name}/compiler/cmd";
67
68 cargoHash = "sha256-iYceYwRqnYA6KxCQxOieR8JZ6TQlIL+OSzAjyr4Cu/g=";
69
70 nativeBuildInputs = [
71 pkg-config
72 makeWrapper
73 rustPlatform.bindgenHook
74 ];
75
76 buildInputs = [
77 elfutils
78 zlib
79 ];
80
81 CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER = "gcc";
82
83 preBuild = ''
84 # `SANDBOX` defined by upstream to disable build-time network access
85 export SANDBOX=1
86 # specify dependencies' location
87 export VMLINUX_DIR=${vmlinux-headers}
88 export BPFTOOL_DIR=${bpftool}
89 '';
90
91 preCheck = ''
92 export HOME=$NIX_BUILD_TOP
93 '';
94
95 checkFlags = [
96 # requires network access
97 "--skip=bpf_compiler::tests::test_generate_custom_btf"
98
99 # FIXME: requires dynamic link `libclang` or clang binary which are not found in check env
100 "--skip=bpf_compiler::tests::test_compile_bpf"
101 "--skip=bpf_compiler::tests::test_export_multi_and_pack"
102 "--skip=document_parser::test::test_parse_empty"
103 "--skip=document_parser::test::test_parse_maps"
104 "--skip=document_parser::test::test_parse_progss"
105 "--skip=document_parser::test::test_parse_variables"
106 ];
107
108 passthru = {
109 inherit bpftool;
110 };
111
112 postFixup = ''
113 wrapProgram $out/bin/ecc-rs \
114 --prefix LIBCLANG_PATH : ${lib.getLib llvmPackages.libclang}/lib \
115 --prefix PATH : ${
116 lib.makeBinPath (
117 with llvmPackages;
118 [
119 clang
120 bintools-unwrapped
121 ]
122 )
123 }
124 '';
125
126 meta = with lib; {
127 homepage = "https://eunomia.dev";
128 description = "EBPF compile toolchain for eunomia-bpf";
129 mainProgram = "ecc-rs";
130 maintainers = with maintainers; [ oluceps ];
131 platforms = platforms.linux;
132 license = licenses.mit;
133 };
134}