about summary refs log tree commit diff
path: root/nixpkgs/pkgs/os-specific/linux/kernel/perf/default.nix
blob: 172965f2a78f1725027e5f5e476d0ae784fb739b (plain) (blame)
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
{ lib
, stdenv
, fetchpatch
, fetchurl
, kernel
, elfutils
, python3
, perl
, newt
, slang
, asciidoc
, xmlto
, makeWrapper
, docbook_xsl
, docbook_xml_dtd_45
, libxslt
, flex
, bison
, pkg-config
, libunwind
, binutils-unwrapped
, libiberty
, audit
, libbfd
, libbfd_2_38
, libopcodes
, libopcodes_2_38
, libpfm
, libtraceevent
, openssl
, systemtap
, numactl
, zlib
, babeltrace
, withGtk ? false
, gtk2
, withZstd ? true
, zstd
, withLibcap ? true
, libcap
}:
let
  d3-flame-graph-templates = stdenv.mkDerivation rec {
    pname = "d3-flame-graph-templates";
    version = "4.1.3";

    src = fetchurl {
      url = "https://registry.npmjs.org/d3-flame-graph/-/d3-flame-graph-${version}.tgz";
      sha256 = "sha256-W5/Vh5jarXUV224aIiTB2TnBFYT3naEIcG2945QjY8Q=";
    };

    installPhase = ''
      install -D -m 0755 -t $out/share/d3-flame-graph/ ./dist/templates/*
    '';
  };
in

stdenv.mkDerivation {
  pname = "perf-linux";
  version = kernel.version;

  inherit (kernel) src;

  postPatch = ''
    # Linux scripts
    patchShebangs scripts
    patchShebangs tools/perf/check-headers.sh
  '' + lib.optionalString (lib.versionAtLeast kernel.version "6.3") ''
    # perf-specific scripts
    patchShebangs tools/perf/pmu-events
  '' + ''
    cd tools/perf

    for x in util/build-id.c util/dso.c; do
      substituteInPlace $x --replace /usr/lib/debug /run/current-system/sw/lib/debug
    done

  '' + lib.optionalString (lib.versionAtLeast kernel.version "5.8") ''
    substituteInPlace scripts/python/flamegraph.py \
      --replace "/usr/share/d3-flame-graph/d3-flamegraph-base.html" \
      "${d3-flame-graph-templates}/share/d3-flame-graph/d3-flamegraph-base.html"

  '' + lib.optionalString (lib.versionAtLeast kernel.version "6.0") ''
    patchShebangs pmu-events/jevents.py
  '';

  makeFlags = [ "prefix=$(out)" "WERROR=0" "ASCIIDOC8=1" ] ++ kernel.makeFlags
    ++ lib.optional (!withGtk) "NO_GTK2=1"
    ++ lib.optional (!withZstd) "NO_LIBZSTD=1"
    ++ lib.optional (!withLibcap) "NO_LIBCAP=1";

  hardeningDisable = [ "format" ];

  # perf refers both to newt and slang
  nativeBuildInputs = [
    asciidoc
    xmlto
    docbook_xsl
    docbook_xml_dtd_45
    libxslt
    flex
    bison
    libiberty
    audit
    makeWrapper
    pkg-config
    python3
  ];

  buildInputs = [
    elfutils
    newt
    slang
    libtraceevent
    libunwind
    zlib
    openssl
    numactl
    python3
    perl
    babeltrace
  ] ++ (if (lib.versionAtLeast kernel.version "5.19")
  then [ libbfd libopcodes ]
  else [ libbfd_2_38 libopcodes_2_38 ])
  ++ lib.optional (lib.meta.availableOn stdenv.hostPlatform systemtap) systemtap.stapBuild
  ++ lib.optional withGtk gtk2
  ++ lib.optional withZstd zstd
  ++ lib.optional withLibcap libcap
  ++ lib.optional (lib.versionAtLeast kernel.version "5.8") libpfm
  ++ lib.optional (lib.versionAtLeast kernel.version "6.0") python3.pkgs.setuptools;

  env.NIX_CFLAGS_COMPILE = toString ([
    "-Wno-error=cpp"
    "-Wno-error=bool-compare"
    "-Wno-error=deprecated-declarations"
    "-Wno-error=stringop-truncation"
  ] ++ lib.optionals (stdenv.cc.isGNU && lib.versions.major stdenv.cc.version == "13") [
    # Workaround gcc bug that causes enev simplest `perf top` runs to
    # crash: https://gcc.gnu.org/PR111009.
    # Can be removed once gcc-13 is updated past 13.2.0.
    "-O1"
  ]);

  doCheck = false; # requires "sparse"

  installTargets = [ "install" "install-man" ];

  # TODO: Add completions based on perf-completion.sh
  postInstall = ''
    # Same as perf. Remove.
    rm -f $out/bin/trace
  '';

  separateDebugInfo = true;

  preFixup = ''
    # Pull in 'objdump' into PATH to make annotations work.
    # The embedded Python interpreter will search PATH to calculate the Python path configuration(Should be fixed by upstream).
    # Add python.interpreter to PATH for now.
    wrapProgram $out/bin/perf \
      --prefix PATH : ${lib.makeBinPath [ binutils-unwrapped python3 ]}
  '';

  meta = with lib; {
    homepage = "https://perf.wiki.kernel.org/";
    description = "Linux tools to profile with performance counters";
    maintainers = with maintainers; [ viric ];
    platforms = platforms.linux;
    broken = kernel.kernelOlder "5";
  };
}