diff options
author | Jordan Galby <jordan.galby@cea.fr> | 2024-07-23 08:44:49 +0200 |
---|---|---|
committer | Bernhard Kaindl <bernhardkaindl7@gmail.com> | 2024-08-07 13:34:07 +0200 |
commit | 6007a77a33156d50999dcfa4d79dce912adf8871 (patch) | |
tree | b5d7fc8ca402b69de3b1e78294965c7c8b93d502 | |
parent | a2794f04bccfd93bb145f4cbbceb927527dd428e (diff) | |
download | spack-6007a77a33156d50999dcfa4d79dce912adf8871.tar.gz spack-6007a77a33156d50999dcfa4d79dce912adf8871.tar.bz2 spack-6007a77a33156d50999dcfa4d79dce912adf8871.tar.xz spack-6007a77a33156d50999dcfa4d79dce912adf8871.zip |
Add linux-perf
-rw-r--r-- | var/spack/repos/builtin/packages/linux-perf/package.py | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/var/spack/repos/builtin/packages/linux-perf/package.py b/var/spack/repos/builtin/packages/linux-perf/package.py new file mode 100644 index 0000000000..afd94f988d --- /dev/null +++ b/var/spack/repos/builtin/packages/linux-perf/package.py @@ -0,0 +1,265 @@ +# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +import os.path +import re +from textwrap import dedent + +import llnl.util.tty as tty + +from spack.package import * + + +class LinuxPerf(Package): + """The Linux perf tool.""" + + homepage = "https://www.kernel.org/" + url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.5.5.tar.xz" + + executables = ["^perf$"] + + maintainers("Jordan474") + + version("6.9.10", sha256="efd12e335fa67d13a3eae30e4b7b7546e74b8ccc90682e4c3fffab0b22654da1") + version("6.6.41", sha256="9ec99c578158ab85d99b37791a76643d2ea4c3f72ecbef7b5eb6d60f3de032ef") + version("5.15.163", sha256="025fc7d8b1560cf456ccae50591fe1ca21c990645df9791aed25820fe78db302") + + variant("libtraceevent", default=True, description="recommended dependency") + variant("python", default=True, description="Python support") + variant("perl", default=True, description="perl script extension") + variant("slang", default=True, description="TUI support") + variant("libpfm4", default=True, description="libpfm4 events extension") + variant("babeltrace", default=True, description="libbabeltrace support for CTF data format") + variant("libcap", default=True, description="process capabilities considered by perf") + variant("numactl", default=True, description="numa perf benchmark") + variant( + "libaudit", + default=False, + description=( + "get perf-trace syscall table from libaudit at runtime," + " rather than unistd.h at buildtime" + ), + ) + variant("debuginfod", default=False, description="support debuginfod") + variant( + "zstd", + default=True, + description="Zstandard based runtime trace compression in record mode", + ) + variant("xz", default=True, description="xz kernel module decompression") + variant( + "openssl", + default=True, + description="support generating build-ids for ELFs generated by jitdump", + ) + variant("jvmti", default=False, description="build jvmti agent") + + depends_on("gmake", type="build") + depends_on("pkgconfig", type="build") + depends_on("flex", type="build") + depends_on("bison", type="build") + + depends_on("elfutils") + depends_on("elfutils +debuginfod", when="+debuginfod") + depends_on("libunwind components=ptrace") + depends_on("libiberty") + depends_on("binutils", type=("build", "link", "run")) + depends_on("zlib-api") + + depends_on("libtraceevent", when="+libtraceevent") + + # jevents requires python >= 3.6 + depends_on("python@3.6:", type=("build", "link", "run"), when="+python") + depends_on("py-setuptools", type="build", when="+python") + depends_on("perl", when="+perl") + depends_on("slang", when="+slang") + depends_on("libpfm4", when="+libpfm4") + depends_on("babeltrace@1.5:", when="+babeltrace") + depends_on("libcap", when="+libcap") + depends_on("audit-userspace", when="+libaudit") + depends_on("numactl", when="+numactl") + depends_on("zstd", when="+zstd") + depends_on("xz", when="+xz") + depends_on("openssl", when="+openssl") + depends_on("openssl@1.1:", when="@5.19: +openssl") + depends_on("java", when="+jvmti") + + depends_on("asciidoc", type="build") + depends_on("xmlto", type="build") + + conflicts( + "~libtraceevent", + when="@6.2:", + msg="linux 6.2 removed internal libtraceevent, and it's highly recommended", + ) + + def url_for_version(self, version): + return f"https://cdn.kernel.org/pub/linux/kernel/v{version[0]}.x/linux-{version}.tar.xz" + + def setup_build_environment(self, env): + # This variable is used in the Makefile. If it is defined on the + # system, it can break the build if there is no build recipe for + # that specific ARCH + env.unset("ARCH") + + @property + def archive_files(self): + return [join_path(self.stage.source_path, "tools/perf/FEATURE-DUMP")] + + def install(self, spec, prefix): + # TODO: + # - GTK2= + # - NO_LIBBPF=1 ? + # - d3 flamegraph resources (libexec/perf-core/scripts/python/flamegraph.py) + + version = self.spec.version + + args = [ + "LIBDW_DIR={}".format(spec["elfutils"].prefix), + "LIBUNWIND_DIR={}".format(spec["libunwind"].prefix), + "NO_SHELLCHECK=1", + ] + # Features to check post-install against `perf version --build-options` + checks = {"dwarf", "libunwind", "libbfd", "zlib"} + + if version >= Version("6.4"): + args.append("BUILD_NONDISTRO=1") + + if "+libaudit" in spec: + checks.add("libaudit") + args.append("NO_SYSCALL_TABLE=1") # will look for libaudit + else: + checks.add("syscall_table") + args.append("NO_LIBAUDIT=1") + + if "+debuginfod" in spec: + if version >= Version("5.19"): # Not in --build-options before that + checks.add("debuginfod") + else: + args.append("NO_LIBDEBUGINFOD=1") + + if "+python" in spec: + checks.add("libpython") + args.extend( + [ + "PYTHON={}".format(spec["python"].command), + "PYTHON_CONFIG={}".format(spec["python"].prefix.bin.join("python-config")), + ] + ) + else: + args.append("NO_LIBPYTHON=1") + + if "+perl" in spec: + checks.add("libperl") + else: + args.append("NO_LIBPERL=1") + + if "+openssl" in spec: + checks.add("libcrypto") + else: + args.append("NO_LIBCRYPTO=1") + + if "+slang" in spec: + checks.add("libslang") + else: + args.append("NO_SLANG=1") + + if "+libpfm4" in spec: + checks.add("libpfm4") + if version < Version("6.4"): + args.append("LIBPFM4=1") + else: + if version >= Version("6.4"): + args.append("NO_LIBPFM4=1") + + if "+babeltrace" in spec: + # checks.add("babeltrace") # Not in --build-options ? + args.append("LIBBABELTRACE_DIR={}".format(spec["babeltrace"].prefix)) + else: + args.append("NO_LIBBABELTRACE=1") + + if "+libcap" in spec: + # checks.add("libcap") # Not in --build-options ? + pass + else: + args.append("NO_LIBCAP=1") + + if "+numactl" in spec: + checks.add("libnuma") + else: + args.append("NO_LIBNUMA=1") + + if "+xz" in spec: + checks.add("lzma") + else: + args.append("NO_LZMA=1") + + if "+zstd" in spec: + checks.add("zstd") + args.append("LIBZSTD_DIR={}".format(spec["zstd"].prefix)) + else: + args.append("NO_LIBZSTD=1") + + if "+libtraceevent" in spec: + if version >= Version("6.2"): # Not in --build-options before that + checks.add("libtraceevent") + if version >= Version("6.10"): + args.append("LIBTRACEEVENT_DIR={}".format(spec["libtraceevent"].prefix)) + if version < Version("6.2"): + args.append("LIBTRACEEVENT_DYNAMIC=1") + else: + if version >= Version("6.2"): + args.append("NO_LIBTRACEEVENT=1") + + if "+jvmti" in spec: + # checks.add("jvmti") # Not in --build-options ? + args.append("JDIR={}".format(spec["java"].prefix)) + else: + args.append("NO_JVMTI=1") + + with working_dir("tools/perf"): + make( + "V=1", + f"JOBS={make_jobs}", + f"prefix={prefix}", + "DESTDIR=", + *args, + "all", + "install", + parallel=False, + ) + + # Create a perfconfig with binutils paths + perfconfig = str(prefix.join("etc/perfconfig")) + assert not os.path.exists(perfconfig) + mkdirp(os.path.dirname(perfconfig)) + with open(perfconfig, "w") as f: + f.write( + dedent( + """\ + [annotate] + addr2line = {addr2line} + objdump = {objdump} + """ + ).format( + addr2line=spec["binutils"].prefix.bin.join("addr2line"), + objdump=spec["binutils"].prefix.bin.join("objdump"), + ) + ) + + # Post-install dependency check: + # $ perf version --build-options + # perf version 6.5.7 + # dwarf: [ on ] # HAVE_DWARF_SUPPORT + # ... + perf = Executable(self.prefix.bin.perf) + output = perf("version", "--build-options", output=str, error=str) + tty.msg(output) # keep a trace in build log + enabled = set(re.findall(r"^\s*(\S+)\s*:\s*\[\s*on\s*\]", output, re.MULTILINE)) + missing = set(checks) - enabled + tty.msg(f"detected features: {sorted(enabled)!r}") + tty.msg(f"expected features: {sorted(checks)!r}") + if missing: + raise InstallError(f"Perf is missing features {sorted(missing)!r}, see log") |