1SUMMARY = "Performance analysis tools for Linux" 2DESCRIPTION = "Performance counters for Linux are a new kernel-based \ 3subsystem that provide a framework for all things \ 4performance analysis. It covers hardware level \ 5(CPU/PMU, Performance Monitoring Unit) features \ 6and software features (software counters, tracepoints) \ 7as well." 8HOMEPAGE = "https://perf.wiki.kernel.org/index.php/Main_Page" 9 10LICENSE = "GPLv2" 11 12PR = "r9" 13 14PACKAGECONFIG ??= "scripting tui libunwind" 15PACKAGECONFIG[dwarf] = ",NO_DWARF=1" 16PACKAGECONFIG[scripting] = ",NO_LIBPERL=1 NO_LIBPYTHON=1,perl python3" 17# gui support was added with kernel 3.6.35 18# since 3.10 libnewt was replaced by slang 19# to cover a wide range of kernel we add both dependencies 20PACKAGECONFIG[tui] = ",NO_NEWT=1,libnewt slang" 21PACKAGECONFIG[libunwind] = ",NO_LIBUNWIND=1 NO_LIBDW_DWARF_UNWIND=1,libunwind" 22PACKAGECONFIG[libnuma] = ",NO_LIBNUMA=1" 23PACKAGECONFIG[systemtap] = ",NO_SDT=1,systemtap" 24PACKAGECONFIG[jvmti] = ",NO_JVMTI=1" 25# libaudit support would need scripting to be enabled 26PACKAGECONFIG[audit] = ",NO_LIBAUDIT=1,audit" 27PACKAGECONFIG[manpages] = ",,xmlto-native asciidoc-native" 28PACKAGECONFIG[cap] = ",,libcap" 29# Arm CoreSight 30PACKAGECONFIG[coresight] = "CORESIGHT=1,,opencsd" 31 32# libunwind is not yet ported for some architectures 33PACKAGECONFIG_remove_arc = "libunwind" 34PACKAGECONFIG_remove_riscv64 = "libunwind" 35 36DEPENDS = " \ 37 virtual/${MLPREFIX}libc \ 38 ${MLPREFIX}elfutils \ 39 ${MLPREFIX}binutils \ 40 bison-native flex-native xz \ 41" 42 43do_configure[depends] += "virtual/kernel:do_shared_workdir" 44 45PROVIDES = "virtual/perf" 46 47inherit linux-kernel-base kernel-arch manpages 48 49# needed for building the tools/perf Python bindings 50inherit ${@bb.utils.contains('PACKAGECONFIG', 'scripting', 'python3native', '', d)} 51inherit python3-dir 52export PYTHON_SITEPACKAGES_DIR 53 54#kernel 3.1+ supports WERROR to disable warnings as errors 55export WERROR = "0" 56 57do_populate_lic[depends] += "virtual/kernel:do_shared_workdir" 58 59# needed for building the tools/perf Perl binding 60include ${@bb.utils.contains('PACKAGECONFIG', 'scripting', 'perf-perl.inc', '', d)} 61 62inherit kernelsrc 63 64S = "${WORKDIR}/${BP}" 65SPDX_S = "${S}/tools/perf" 66 67# The LDFLAGS is required or some old kernels fails due missing 68# symbols and this is preferred than requiring patches to every old 69# supported kernel. 70LDFLAGS="-ldl -lutil" 71 72EXTRA_OEMAKE = '\ 73 -C ${S}/tools/perf \ 74 O=${B} \ 75 CROSS_COMPILE=${TARGET_PREFIX} \ 76 ARCH=${ARCH} \ 77 CC="${CC}" \ 78 CCLD="${CC}" \ 79 LDSHARED="${CC} -shared" \ 80 AR="${AR}" \ 81 LD="${LD}" \ 82 EXTRA_CFLAGS="-ldw" \ 83 EXTRA_LDFLAGS="${PERF_EXTRA_LDFLAGS}" \ 84 perfexecdir=${libexecdir} \ 85 NO_GTK2=1 \ 86 ${PACKAGECONFIG_CONFARGS} \ 87 TMPDIR="${B}" \ 88 LIBUNWIND_DIR=${STAGING_EXECPREFIXDIR} \ 89' 90 91EXTRA_OEMAKE += "\ 92 'DESTDIR=${D}' \ 93 'prefix=${prefix}' \ 94 'bindir=${bindir}' \ 95 'sharedir=${datadir}' \ 96 'sysconfdir=${sysconfdir}' \ 97 'perfexecdir=${libexecdir}/perf-core' \ 98 'ETC_PERFCONFIG=${@os.path.relpath(sysconfdir, prefix)}' \ 99 'sharedir=${@os.path.relpath(datadir, prefix)}' \ 100 'mandir=${@os.path.relpath(mandir, prefix)}' \ 101 'infodir=${@os.path.relpath(infodir, prefix)}' \ 102 ${@bb.utils.contains('PACKAGECONFIG', 'scripting', 'PYTHON=python3 PYTHON_CONFIG=python3-config', '', d)} \ 103" 104 105# During do_configure, we might run a 'make clean'. That often breaks 106# when done in parallel, so disable parallelism for do_configure. Note 107# that it has to be done this way rather than by passing -j1, since 108# perf's build system by default ignores any -j argument, but does 109# honour a JOBS variable. 110EXTRA_OEMAKE_append_task-configure = " JOBS=1" 111 112PERF_SRC ?= "Makefile \ 113 tools/arch \ 114 tools/build \ 115 tools/include \ 116 tools/lib \ 117 tools/Makefile \ 118 tools/perf \ 119 tools/scripts \ 120 scripts/ \ 121 arch/${ARCH}/Makefile \ 122" 123 124PERF_EXTRA_LDFLAGS = "" 125 126# MIPS N32 127PERF_EXTRA_LDFLAGS_mipsarchn32eb = "-m elf32btsmipn32" 128PERF_EXTRA_LDFLAGS_mipsarchn32el = "-m elf32ltsmipn32" 129 130do_compile() { 131 # Linux kernel build system is expected to do the right thing 132 unset CFLAGS 133 oe_runmake all 134} 135 136do_install() { 137 # Linux kernel build system is expected to do the right thing 138 unset CFLAGS 139 oe_runmake install 140 # we are checking for this make target to be compatible with older perf versions 141 if ${@bb.utils.contains('PACKAGECONFIG', 'scripting', 'true', 'false', d)} && grep -q install-python_ext ${S}/tools/perf/Makefile*; then 142 oe_runmake DESTDIR=${D} install-python_ext 143 fi 144} 145 146do_configure[prefuncs] += "copy_perf_source_from_kernel" 147python copy_perf_source_from_kernel() { 148 sources = (d.getVar("PERF_SRC") or "").split() 149 src_dir = d.getVar("STAGING_KERNEL_DIR") 150 dest_dir = d.getVar("S") 151 bb.utils.mkdirhier(dest_dir) 152 bb.utils.prunedir(dest_dir) 153 for s in sources: 154 src = oe.path.join(src_dir, s) 155 dest = oe.path.join(dest_dir, s) 156 if not os.path.exists(src): 157 bb.fatal("Path does not exist: %s. Maybe PERF_SRC does not match the kernel version." % src) 158 if os.path.isdir(src): 159 oe.path.copyhardlinktree(src, dest) 160 else: 161 src_path = os.path.dirname(s) 162 os.makedirs(os.path.join(dest_dir,src_path),exist_ok=True) 163 bb.utils.copyfile(src, dest) 164} 165 166do_configure_prepend () { 167 # If building a multlib based perf, the incorrect library path will be 168 # detected by perf, since it triggers via: ifeq ($(ARCH),x86_64). In a 32 bit 169 # build, with a 64 bit multilib, the arch won't match and the detection of a 170 # 64 bit build (and library) are not exected. To ensure that libraries are 171 # installed to the correct location, we can use the weak assignment in the 172 # config/Makefile. 173 # 174 # Also need to relocate .config-detected to $(OUTPUT)/config-detected 175 # for kernel sources that do not already do this 176 # as two builds (e.g. perf and lib32-perf from mutlilib can conflict 177 # with each other if its in the shared source directory 178 # 179 if [ -e "${S}/tools/perf/config/Makefile" ]; then 180 perfconfig="${S}/tools/perf/config/Makefile" 181 fi 182 if [ -e "${S}/tools/perf/Makefile.config" ]; then 183 perfconfig="${S}/tools/perf/Makefile.config" 184 fi 185 if [ -n "${perfconfig}" ]; then 186 # Match $(prefix)/$(lib) and $(prefix)/lib 187 sed -i -e 's,^libdir = \($(prefix)/.*lib\),libdir ?= \1,' \ 188 -e 's,^perfexecdir = \(.*\),perfexecdir ?= \1,' \ 189 -e 's,\ .config-detected, $(OUTPUT)/config-detected,g' \ 190 ${perfconfig} 191 fi 192 # The man pages installation is "$(INSTALL) -d -m 755 $(DESTDIR)$(man1dir)" 193 # in ${S}/tools/perf/Documentation/Makefile, if the mandir set to '?=', it 194 # will use the relative path 'share/man', in the way it will resulting in 195 # incorrect installation for man pages. 196 if [ -e "${S}/tools/perf/Documentation/Makefile" ]; then 197 sed -i 's,^mandir?=,mandir:=,' ${S}/tools/perf/Documentation/Makefile 198 fi 199 if [ -e "${S}/tools/perf/Makefile.perf" ]; then 200 sed -i -e 's,\ .config-detected, $(OUTPUT)/config-detected,g' \ 201 ${S}/tools/perf/Makefile.perf 202 sed -i -e "s,prefix='\$(DESTDIR_SQ)/usr'$,prefix='\$(DESTDIR_SQ)/usr' --install-lib='\$(DESTDIR)\$(PYTHON_SITEPACKAGES_DIR)',g" \ 203 ${S}/tools/perf/Makefile.perf 204 fi 205 sed -i -e "s,--root='/\$(DESTDIR_SQ)',--prefix='\$(DESTDIR_SQ)/usr' --install-lib='\$(DESTDIR)\$(PYTHON_SITEPACKAGES_DIR)',g" \ 206 ${S}/tools/perf/Makefile* 207 208 if [ -e "${S}/tools/build/Makefile.build" ]; then 209 sed -i -e 's,\ .config-detected, $(OUTPUT)/config-detected,g' \ 210 ${S}/tools/build/Makefile.build 211 fi 212 213 # We need to ensure the --sysroot option in CC is preserved 214 if [ -e "${S}/tools/perf/Makefile.perf" ]; then 215 sed -i 's,CC = $(CROSS_COMPILE)gcc,#CC,' ${S}/tools/perf/Makefile.perf 216 sed -i 's,AR = $(CROSS_COMPILE)ar,#AR,' ${S}/tools/perf/Makefile.perf 217 sed -i 's,LD = $(CROSS_COMPILE)ld,#LD,' ${S}/tools/perf/Makefile.perf 218 fi 219 if [ -e "${S}/tools/lib/api/Makefile" ]; then 220 sed -i 's,CC = $(CROSS_COMPILE)gcc,#CC,' ${S}/tools/lib/api/Makefile 221 sed -i 's,AR = $(CROSS_COMPILE)ar,#AR,' ${S}/tools/lib/api/Makefile 222 sed -i 's,LD = $(CROSS_COMPILE)ld,#LD,' ${S}/tools/lib/api/Makefile 223 fi 224 if [ -e "${S}/tools/lib/subcmd/Makefile" ]; then 225 sed -i 's,CC = $(CROSS_COMPILE)gcc,#CC,' ${S}/tools/lib/subcmd/Makefile 226 sed -i 's,AR = $(CROSS_COMPILE)ar,#AR,' ${S}/tools/lib/subcmd/Makefile 227 fi 228 if [ -e "${S}/tools/perf/config/feature-checks/Makefile" ]; then 229 sed -i 's,CC := $(CROSS_COMPILE)gcc -MD,CC += -MD,' ${S}/tools/perf/config/feature-checks/Makefile 230 fi 231 if [ -e "${S}/tools/build/Makefile.feature" ]; then 232 sed -i 's,CFLAGS=,CC="\$(CC)" CFLAGS=,' ${S}/tools/build/Makefile.feature 233 fi 234 235 # 3.17-rc1+ has a include issue for arm/powerpc. Temporarily sed in the appropriate include 236 if [ -e "${S}/tools/perf/arch/$ARCH/util/skip-callchain-idx.c" ]; then 237 sed -i 's,#include "util/callchain.h",#include "util/callchain.h"\n#include "util/debug.h",' ${S}/tools/perf/arch/$ARCH/util/skip-callchain-idx.c 238 fi 239 if [ -e "${S}/tools/perf/arch/arm/util/unwind-libunwind.c" ] && [ -e "${S}/tools/perf/arch/arm/tests/dwarf-unwind.c" ]; then 240 sed -i 's,#include "tests/tests.h",#include "tests/tests.h"\n#include "util/debug.h",' ${S}/tools/perf/arch/arm/tests/dwarf-unwind.c 241 sed -i 's,#include "perf_regs.h",#include "perf_regs.h"\n#include "util/debug.h",' ${S}/tools/perf/arch/arm/util/unwind-libunwind.c 242 fi 243 244 # use /usr/bin/env instead of version specific python 245 for s in `find ${S}/tools/perf/ -name '*.py'` `find ${S}/scripts/ -name 'bpf_helpers_doc.py'`; do 246 sed -i -e "s,#!.*python.*,#!${USRBINPATH}/env python3," ${s} 247 done 248 249 # unistd.h can be out of sync between libc-headers and the captured version in the perf source 250 # so we copy it from the sysroot unistd.h to the perf unistd.h 251 install -D -m0644 ${STAGING_INCDIR}/asm-generic/unistd.h ${S}/tools/include/uapi/asm-generic/unistd.h 252 install -D -m0644 ${STAGING_INCDIR}/asm-generic/unistd.h ${S}/include/uapi/asm-generic/unistd.h 253} 254 255python do_package_prepend() { 256 d.setVar('PKGV', d.getVar("KERNEL_VERSION").split("-")[0]) 257} 258 259PACKAGE_ARCH = "${MACHINE_ARCH}" 260 261 262PACKAGES =+ "${PN}-archive ${PN}-tests ${PN}-perl ${PN}-python" 263 264RDEPENDS_${PN} += "elfutils bash" 265RDEPENDS_${PN}-archive =+ "bash" 266RDEPENDS_${PN}-python =+ "bash python3 python3-modules ${@bb.utils.contains('PACKAGECONFIG', 'audit', 'audit-python3', '', d)}" 267RDEPENDS_${PN}-perl =+ "bash perl perl-modules" 268RDEPENDS_${PN}-tests =+ "python3" 269 270RSUGGESTS_SCRIPTING = "${@bb.utils.contains('PACKAGECONFIG', 'scripting', '${PN}-perl ${PN}-python', '',d)}" 271RSUGGESTS_${PN} += "${PN}-archive ${PN}-tests ${RSUGGESTS_SCRIPTING}" 272 273FILES_SOLIBSDEV = "" 274FILES_${PN} += "${libexecdir}/perf-core ${exec_prefix}/libexec/perf-core ${libdir}/traceevent ${libdir}/libperf-jvmti.so" 275FILES_${PN}-archive = "${libdir}/perf/perf-core/perf-archive" 276FILES_${PN}-tests = "${libdir}/perf/perf-core/tests ${libexecdir}/perf-core/tests" 277FILES_${PN}-python = " \ 278 ${PYTHON_SITEPACKAGES_DIR} \ 279 ${libexecdir}/perf-core/scripts/python \ 280 " 281FILES_${PN}-perl = "${libexecdir}/perf-core/scripts/perl" 282 283 284INHIBIT_PACKAGE_DEBUG_SPLIT="1" 285DEBUG_OPTIMIZATION_append = " -Wno-error=maybe-uninitialized" 286