* [RFC PATCH v2 1/7] kbuild: factor the userspace ABI flags out into KBUILD_USERABI
2026-10-16 14:31 [RFC PATCH v2 0/7] kbuild: build the userspace tools in tools/ with the kernel Sasha Levin
@ 2026-10-16 14:31 ` Sasha Levin
2026-10-16 14:31 ` [RFC PATCH v2 2/7] kbuild: add "make tools_build" to build userspace tools from tools/ Sasha Levin
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Sasha Levin @ 2026-10-16 14:31 UTC (permalink / raw)
To: Nathan Chancellor, Nicolas Schier, linux-kbuild
Cc: Sasha Levin, Shuah Khan, linux-kselftest, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, linux-perf-users, Thomas Weißschuh,
Andrew Morton, linux-kernel
KBUILD_USERCFLAGS and KBUILD_USERLDFLAGS pick up the flags that select
the target ABI for userspace programs: --target= under clang, -m32/-m64,
or CONFIG_ARCH_USERFLAGS. Collect those in KBUILD_USERABI and export it,
so programs built outside of kbuild's userprogs can be compiled for the
same ABI without also inheriting kbuild's warning and language flags.
No functional change: KBUILD_USERCFLAGS and KBUILD_USERLDFLAGS keep the
same value.
Assisted-by: LLM
Signed-off-by: Sasha Levin <sashal@kernel.org>
Reviewed-by: Thomas Weißschuh <linux@weissschuh.net>
---
Makefile | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/Makefile b/Makefile
index 7c855e6fe5448..8c94aff229b21 100644
--- a/Makefile
+++ b/Makefile
@@ -650,7 +650,7 @@ export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AW
export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD TAR
export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS KBUILD_PROCMACROLDFLAGS LDFLAGS_MODULE
-export KBUILD_USERCFLAGS KBUILD_USERLDFLAGS
+export KBUILD_USERCFLAGS KBUILD_USERLDFLAGS KBUILD_USERABI
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
@@ -1270,15 +1270,17 @@ endif
USERFLAGS_FROM_KERNEL := --target=%
ifdef CONFIG_ARCH_USERFLAGS
-KBUILD_USERCFLAGS += $(CONFIG_ARCH_USERFLAGS)
-KBUILD_USERLDFLAGS += $(CONFIG_ARCH_USERFLAGS)
+KBUILD_USERABI := $(CONFIG_ARCH_USERFLAGS)
else
+KBUILD_USERABI :=
# If not overridden also inherit the bit size
USERFLAGS_FROM_KERNEL += -m32 -m64
endif
-KBUILD_USERCFLAGS += $(filter $(USERFLAGS_FROM_KERNEL), $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS))
-KBUILD_USERLDFLAGS += $(filter $(USERFLAGS_FROM_KERNEL), $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS))
+KBUILD_USERABI += $(filter $(USERFLAGS_FROM_KERNEL), $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS))
+
+KBUILD_USERCFLAGS += $(KBUILD_USERABI)
+KBUILD_USERLDFLAGS += $(KBUILD_USERABI)
# userspace programs are linked via the compiler, use the correct linker
ifdef CONFIG_CC_IS_CLANG
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC PATCH v2 2/7] kbuild: add "make tools_build" to build userspace tools from tools/
2026-10-16 14:31 [RFC PATCH v2 0/7] kbuild: build the userspace tools in tools/ with the kernel Sasha Levin
2026-10-16 14:31 ` [RFC PATCH v2 1/7] kbuild: factor the userspace ABI flags out into KBUILD_USERABI Sasha Levin
@ 2026-10-16 14:31 ` Sasha Levin
2026-10-16 14:31 ` [RFC PATCH v2 3/7] perf build: Add MINIMAL=1 to build without optional features Sasha Levin
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Sasha Levin @ 2026-10-16 14:31 UTC (permalink / raw)
To: Nathan Chancellor, Nicolas Schier, linux-kbuild
Cc: Sasha Levin, Shuah Khan, linux-kselftest, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, linux-perf-users, Thomas Weißschuh,
Andrew Morton, linux-kernel
The programs under tools/ have their own build systems and are not built
by "make", so nothing builds them together with the kernel they belong
to, and breakage in them is only noticed when someone happens to build
them by hand, sometimes many stable releases later.
Add a "Build userspace tools from tools/" menu (CONFIG_TOOLS_BUILD) with
an entry for each tool, and a "tools_build" target that builds the
selected ones for the target:
- Each tool is built by its own build system, as it is built
standalone, into tools-build/ in the object tree. "make clean" removes
that directory without running the tools' own clean rules.
- The compiler is the one CONFIG_CC_CAN_LINK was tested with: $(CC),
USERCFLAGS and KBUILD_USERABI, so cross builds, including LLVM=1
ARCH=<arch> without CROSS_COMPILE, produce target binaries. USERLDFLAGS
reach the tools as LDFLAGS.
- kbuild's own state (srctree, objtree, VPATH, sub_make_done, ...) and
the user's CFLAGS/LDFLAGS/O= from the environment or the command line
are kept away from the tools.
- Under UML, ARCH and SRCARCH are set to the architecture UML runs on
(HEADER_ARCH): a UML kernel runs that architecture's programs, and
the tools' build systems do not know ARCH=um.
- A tool is rebuilt from scratch when its make arguments change.
"make -n" shows the build without removing or recording anything.
- On failure, the message names the option that skips the tool.
The menu depends on CC_CAN_LINK, so toolchains without a C library are
unaffected, and is limited to glibc toolchains for x86_64 and arm64,
which is what it has been tested with.
The first entries are the tools that only need a C library: bootconfig,
counter, dma, gpio, hv, iio, spi and usb.
Assisted-by: LLM
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.gitignore | 5 +++
Makefile | 8 +++-
lib/Kconfig.debug | 2 +
tools/Kconfig | 73 +++++++++++++++++++++++++++++++++++++
tools/Makefile.kbuild | 85 +++++++++++++++++++++++++++++++++++++++++++
5 files changed, 172 insertions(+), 1 deletion(-)
create mode 100644 tools/Kconfig
create mode 100644 tools/Makefile.kbuild
diff --git a/.gitignore b/.gitignore
index 9875120ea7bde..6bf05bbd94245 100644
--- a/.gitignore
+++ b/.gitignore
@@ -101,6 +101,11 @@ modules.order
#
/tar-install/
+#
+# userspace tools (make tools_build)
+#
+/tools-build/
+
#
# pacman files (make pacman-pkg)
#
diff --git a/Makefile b/Makefile
index 8c94aff229b21..af5d0a9d51df9 100644
--- a/Makefile
+++ b/Makefile
@@ -1633,6 +1633,11 @@ tools/%: FORCE
$(Q)mkdir -p $(objtree)/tools
$(Q)$(MAKE) O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ $*
+# The userspace programs selected in tools/Kconfig, built for the target
+PHONY += tools_build
+tools_build: headers
+ $(Q)$(MAKE) -f $(srctree)/tools/Makefile.kbuild
+
# ---------------------------------------------------------------------------
# Kernel selftest
@@ -1772,7 +1777,7 @@ CLEAN_FILES += vmlinux.symvers modules-only.symvers \
modules.builtin modules.builtin.modinfo modules.nsdeps \
modules.builtin.ranges vmlinux.o.map vmlinux.unstripped \
vmlinux.thinlto-index builtin.order \
- compile_commands.json rust/test \
+ compile_commands.json rust/test tools-build \
rust-project.json .vmlinux.objs .vmlinux.export.c \
.builtin-dtbs-list .builtin-dtbs.S sbom-*.spdx.json
@@ -1894,6 +1899,7 @@ help:
@echo ' clang-tidy - Check with clang-tidy'
@echo ''
@echo 'Tools:'
+ @echo ' tools_build - Build the userspace tools selected in tools/Kconfig'
@echo ' nsdeps - Generate missing symbol namespace dependencies'
@echo ' sbom - Generate Software Bill of Materials'
@echo ''
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 6b24a2c89b84d..16984158977b3 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1913,6 +1913,8 @@ config PROVIDE_OHCI1394_DMA_INIT
source "samples/Kconfig"
+source "tools/Kconfig"
+
config ARCH_HAS_DEVMEM_IS_ALLOWED
bool
diff --git a/tools/Kconfig b/tools/Kconfig
new file mode 100644
index 0000000000000..2d05c8e593e21
--- /dev/null
+++ b/tools/Kconfig
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config TOOLS_BUILD_ABI
+ def_bool X86_64 || ARM64
+
+config TOOLS_BUILD_GLIBC
+ def_bool $(success,echo '#include <features.h>' | $(CC) $(CLANG_FLAGS) $(USERCFLAGS) -E -dM -x c - | grep -q __GLIBC__)
+
+menuconfig TOOLS_BUILD
+ bool "Build userspace tools from tools/"
+ depends on CC_CAN_LINK
+ depends on TOOLS_BUILD_ABI
+ depends on TOOLS_BUILD_GLIBC
+ help
+ Build the selected programs under tools/ for the target together
+ with the kernel, as part of "make all", or alone with
+ "make tools_build". Each program is built by its own build system
+ into tools-build/ in the object tree. The tools then always match
+ the kernel they were built with, and a change that breaks one of
+ them shows up in the same build that compiles the kernel.
+
+ This needs a compiler that can link glibc programs for the target,
+ and is currently limited to x86_64 and arm64.
+
+ If unsure, say N.
+
+if TOOLS_BUILD
+
+config TOOLS_BUILD_BOOTCONFIG
+ bool "bootconfig"
+ help
+ Build tools/bootconfig, the boot configuration editor, for the
+ target. This is independent of the host copy that the kernel
+ build uses for CONFIG_CMDLINE_FROM_BOOTCONFIG.
+
+config TOOLS_BUILD_COUNTER
+ bool "Counter tools"
+ help
+ Build tools/counter (counter_example, counter_watch_events).
+
+config TOOLS_BUILD_DMA
+ bool "DMA map benchmark"
+ help
+ Build tools/dma (dma_map_benchmark).
+
+config TOOLS_BUILD_GPIO
+ bool "GPIO tools"
+ help
+ Build tools/gpio (lsgpio, gpio-hammer, gpio-event-mon,
+ gpio-watch).
+
+config TOOLS_BUILD_HV
+ bool "Hyper-V guest daemons"
+ help
+ Build tools/hv (hv_kvp_daemon, hv_vss_daemon and, on x86,
+ hv_fcopy_uio_daemon).
+
+config TOOLS_BUILD_IIO
+ bool "IIO tools"
+ help
+ Build tools/iio (lsiio, iio_event_monitor, iio_generic_buffer).
+
+config TOOLS_BUILD_SPI
+ bool "SPI tools"
+ help
+ Build tools/spi (spidev_test, spidev_fdx).
+
+config TOOLS_BUILD_USB
+ bool "USB tools"
+ help
+ Build tools/usb (testusb, ffs-test).
+
+endif # TOOLS_BUILD
diff --git a/tools/Makefile.kbuild b/tools/Makefile.kbuild
new file mode 100644
index 0000000000000..8cfa7f80039cd
--- /dev/null
+++ b/tools/Makefile.kbuild
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Builds the userspace programs selected in tools/Kconfig for the target.
+# Invoked by "make tools_build", which "make all" runs when CONFIG_TOOLS_BUILD
+# is set. Each program is built by its own build system, the way it is built
+# standalone, into $(objtree)/tools-build/.
+
+PHONY := __tools_build
+__tools_build:
+
+include include/config/auto.conf
+
+abs_srctree := $(realpath $(srctree))
+toolsdir := $(abs_srctree)/tools
+outdir := $(CURDIR)/tools-build
+
+# kbuild's state and the user's compiler flags, from the environment or the
+# command line, would change how these build
+unexport srctree objtree srcroot VPATH building_out_of_srctree sub_make_done
+unexport CLANG_FLAGS INSTALL_HDR_PATH O
+unexport CFLAGS CPPFLAGS LDFLAGS EXTRA_CFLAGS EXTRA_LDFLAGS USERCFLAGS USERLDFLAGS
+space := $(subst ,, )
+overrides := $(subst \$(space),\@space@,$(MAKEOVERRIDES))
+MAKEOVERRIDES := $(subst \@space@,\$(space),$(filter-out O=% CFLAGS=% CPPFLAGS=% \
+ LDFLAGS=% EXTRA_CFLAGS=% EXTRA_LDFLAGS=% USERCFLAGS=% USERLDFLAGS=% \
+ $(if $(CONFIG_UML),ARCH=% SRCARCH=%),$(overrides)))
+
+# A UML kernel runs the programs of the architecture it is built on. The tools
+# are built for that architecture, as they do not know ARCH=um.
+ifdef CONFIG_UML
+override ARCH := $(HEADER_ARCH)
+override SRCARCH := $(HEADER_ARCH)
+export ARCH SRCARCH
+endif
+
+# The compiler CONFIG_CC_CAN_LINK was tested with. The tools take linker
+# flags from LDFLAGS.
+tools-cc := $(CC) $(USERCFLAGS) $(KBUILD_USERABI)
+ifneq ($(USERLDFLAGS),)
+override LDFLAGS := $(USERLDFLAGS)
+export LDFLAGS
+endif
+
+squote := '
+escsq = $(subst $(squote),'\$(squote)',$1)
+
+# $(call build,<output directory>,<make arguments>,<files to check>,<CONFIG_ symbol>)
+# Builds in an empty directory when the make arguments or LDFLAGS changed, or
+# when one of the files is newer than the last build. "make -n" only shows
+# the build.
+build-key = $(call escsq,$(2) LDFLAGS=$(USERLDFLAGS))
+dry-run := $(findstring n,$(firstword -$(MAKEFLAGS)))
+
+define build
+ +$(Q)$(if $(dry-run),,if [ "$$(cat $(1)/.tools_build 2>/dev/null)" != '$(build-key)' ] $(if $(3),|| \
+ [ -n "$$(find $(3) -newer $(1)/.tools_build -print -quit 2>/dev/null)" ]); then \
+ rm -rf $(1); \
+ fi;) \
+ mkdir -p $(1) && $(MAKE) $(2) && \
+ $(if $(dry-run),:,printf '%s' '$(build-key)' > $(1)/.tools_build) || \
+ { echo >&2 "tools_build: $(patsubst $(outdir)/%,%,$(1)) failed to build; set CONFIG_$(4)=n to skip it"; false; }
+endef
+
+# Programs in tools/<name>, which track their own header dependencies
+tools-$(CONFIG_TOOLS_BUILD_BOOTCONFIG) += bootconfig
+tools-$(CONFIG_TOOLS_BUILD_COUNTER) += counter
+tools-$(CONFIG_TOOLS_BUILD_DMA) += dma
+tools-$(CONFIG_TOOLS_BUILD_GPIO) += gpio
+tools-$(CONFIG_TOOLS_BUILD_HV) += hv
+tools-$(CONFIG_TOOLS_BUILD_IIO) += iio
+tools-$(CONFIG_TOOLS_BUILD_SPI) += spi
+tools-$(CONFIG_TOOLS_BUILD_USB) += usb
+
+tool-targets := $(addprefix tool-,$(tools-y))
+
+__tools_build: $(tool-targets)
+
+PHONY += $(tool-targets)
+$(tool-targets): tool-%: FORCE
+ $(call build,$(outdir)/$*,-C $(toolsdir)/$* O=$(outdir)/$* CC='$(call escsq,$(tools-cc))',,TOOLS_BUILD_$(shell echo $* | tr a-z A-Z))
+
+PHONY += FORCE
+FORCE:
+
+.PHONY: $(PHONY)
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC PATCH v2 3/7] perf build: Add MINIMAL=1 to build without optional features
2026-10-16 14:31 [RFC PATCH v2 0/7] kbuild: build the userspace tools in tools/ with the kernel Sasha Levin
2026-10-16 14:31 ` [RFC PATCH v2 1/7] kbuild: factor the userspace ABI flags out into KBUILD_USERABI Sasha Levin
2026-10-16 14:31 ` [RFC PATCH v2 2/7] kbuild: add "make tools_build" to build userspace tools from tools/ Sasha Levin
@ 2026-10-16 14:31 ` Sasha Levin
2026-10-16 15:41 ` Ian Rogers
2026-10-16 14:31 ` [RFC PATCH v2 4/7] tools: build perf in tools_build Sasha Levin
` (3 subsequent siblings)
6 siblings, 1 reply; 10+ messages in thread
From: Sasha Levin @ 2026-10-16 14:31 UTC (permalink / raw)
To: Nathan Chancellor, Nicolas Schier, linux-kbuild
Cc: Sasha Levin, Shuah Khan, linux-kselftest, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, linux-perf-users, Thomas Weißschuh,
Andrew Morton, linux-kernel
Turning off every optional feature takes a long list of NO_* variables,
and the list has to follow features as they are added and renamed. The
one in tests/make for make_minimal has fallen behind: it leaves
libtraceevent, jevents, slang, AIO, LZMA, zlib, libLLVM and Rust to be
detected, so a make_minimal build still needs libtraceevent and python.
Add MINIMAL=1, which turns off every optional feature, the BPF skeletons
and the shellcheck run. perf then builds, natively or cross, with no
library beyond the C library and without python, pkg-config, clang or
rustc, and the result does not depend on what is installed on the build
machine.
A MINIMAL=1 build also leaves out the notices that post unwind and
python support are disabled, which it asked for, and the one about the
pkg-config search path for cross builds, as pkg-config is not needed
then.
It is handled in Makefile.perf rather than Makefile.config, as
Makefile.config is included after the pkg-config and shellcheck setup.
Use it for make_minimal in tests/make.
Suggested-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/CAP-5=fWFY-tpJz2vcBZvurwdZY5gwd8cuTemE9q1rtZ0Vi0dng@mail.gmail.com
Assisted-by: LLM
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/perf/Makefile.config | 8 ++++++--
tools/perf/Makefile.perf | 40 ++++++++++++++++++++++++++++++++++++--
tools/perf/tests/make | 8 +-------
3 files changed, 45 insertions(+), 11 deletions(-)
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 4d5993da9f945..137c9e120670b 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -742,7 +742,9 @@ dwarf-post-unwind-text := BUG
# setup DWARF post unwinder
ifdef NO_LIBUNWIND
ifdef NO_LIBDW
- $(warning Disabling post unwind, no support found.)
+ ifneq ($(MINIMAL),1)
+ $(warning Disabling post unwind, no support found.)
+ endif
dwarf-post-unwind := 0
else
dwarf-post-unwind-text := libdw
@@ -828,7 +830,9 @@ endef
PYTHON_EXTENSION_SUFFIX := '.so'
ifdef NO_LIBPYTHON
- $(call disable-python,Python support disabled by user)
+ ifneq ($(MINIMAL),1)
+ $(call disable-python,Python support disabled by user)
+ endif
else
ifndef PYTHON
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 29cfd44c427f3..c770077e7d392 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -129,6 +129,9 @@ include ../scripts/utilities.mak
# Define GEN_VMLINUX_H to generate vmlinux.h from the BTF.
#
# Define NO_SHELLCHECK if you do not want to run shellcheck during build
+#
+# Define MINIMAL=1 to build without any optional feature, needing only a C
+# compiler and library, flex and bison
# As per kernel Makefile, avoid funny character set dependencies
unexport LC_ALL
@@ -174,6 +177,37 @@ endef
LD += $(EXTRA_LDFLAGS)
+# MINIMAL=1 is handled here rather than in Makefile.config, which is included
+# after the pkg-config and shellcheck setup below
+ifeq ($(MINIMAL),1)
+ NO_LIBELF := 1
+ NO_LIBDW := 1
+ NO_LIBTRACEEVENT := 1
+ NO_JEVENTS := 1
+ NO_LIBPYTHON := 1
+ NO_LIBBPF := 1
+ BUILD_BPF_SKEL := 0
+ NO_SLANG := 1
+ NO_DEMANGLE := 1
+ NO_BACKTRACE := 1
+ NO_AIO := 1
+ NO_ZLIB := 1
+ NO_LZMA := 1
+ NO_LIBZSTD := 1
+ NO_LIBNUMA := 1
+ NO_LIBLLVM := 1
+ NO_CAPSTONE := 1
+ NO_LIBPFM4 := 1
+ NO_LIBDEBUGINFOD := 1
+ NO_BABELTRACE2 := 1
+ NO_SDT := 1
+ NO_JVMTI := 1
+ NO_RUST := 1
+ NO_PERF_READ_VDSO32 := 1
+ NO_PERF_READ_VDSOX32 := 1
+ NO_SHELLCHECK := 1
+endif
+
# Some distros provide the command $(CROSS_COMPILE)pkg-config for
# searching packges installed with Multiarch. Use it for cross
# compilation if it is existed.
@@ -195,8 +229,10 @@ else
PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/local/share/pkgconfig/
PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/share/pkgconfig/
export PKG_CONFIG_LIBDIR
- $(warning Missing PKG_CONFIG_LIBDIR, PKG_CONFIG_PATH and PKG_CONFIG_SYSROOT_DIR for cross compilation,)
- $(warning set PKG_CONFIG_LIBDIR for using Multiarch libs.)
+ ifneq ($(MINIMAL),1)
+ $(warning Missing PKG_CONFIG_LIBDIR, PKG_CONFIG_PATH and PKG_CONFIG_SYSROOT_DIR for cross compilation,)
+ $(warning set PKG_CONFIG_LIBDIR for using Multiarch libs.)
+ endif
endif
endif
endif
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index d2c2f526e1db0..dbbc971a144b2 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -115,13 +115,7 @@ make_install_prefix := install prefix=/tmp/krava
make_install_prefix_slash := install prefix=/tmp/krava/
make_static := LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX32=1 NO_JVMTI=1 NO_LIBTRACEEVENT=1 NO_LIBELF=1
-# all the NO_* variable combined
-make_minimal := NO_LIBPYTHON=1
-make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_BACKTRACE=1
-make_minimal += NO_LIBNUMA=1 NO_LIBBIONIC=1 NO_LIBDW=1
-make_minimal += NO_LIBBPF=1
-make_minimal += NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1
-make_minimal += NO_CAPSTONE=1
+make_minimal := MINIMAL=1
# binutils 2_42 and newer have bfd_thread_init()
new_libbfd := $(shell echo '#include <bfd.h>' | $(CC) -E -x c - | grep bfd_thread_init)
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [RFC PATCH v2 3/7] perf build: Add MINIMAL=1 to build without optional features
2026-10-16 14:31 ` [RFC PATCH v2 3/7] perf build: Add MINIMAL=1 to build without optional features Sasha Levin
@ 2026-10-16 15:41 ` Ian Rogers
0 siblings, 0 replies; 10+ messages in thread
From: Ian Rogers @ 2026-10-16 15:41 UTC (permalink / raw)
To: Sasha Levin
Cc: Nathan Chancellor, Nicolas Schier, linux-kbuild, Shuah Khan,
linux-kselftest, Peter Zijlstra, Ingo Molnar,
Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Adrian Hunter, James Clark,
linux-perf-users, Thomas Weißschuh, Andrew Morton,
linux-kernel
On Fri, Oct 16, 2026 at 7:31 AM Sasha Levin <sashal@kernel.org> wrote:
>
> Turning off every optional feature takes a long list of NO_* variables,
> and the list has to follow features as they are added and renamed. The
> one in tests/make for make_minimal has fallen behind: it leaves
> libtraceevent, jevents, slang, AIO, LZMA, zlib, libLLVM and Rust to be
> detected, so a make_minimal build still needs libtraceevent and python.
>
> Add MINIMAL=1, which turns off every optional feature, the BPF skeletons
> and the shellcheck run. perf then builds, natively or cross, with no
> library beyond the C library and without python, pkg-config, clang or
> rustc, and the result does not depend on what is installed on the build
> machine.
>
> A MINIMAL=1 build also leaves out the notices that post unwind and
> python support are disabled, which it asked for, and the one about the
> pkg-config search path for cross builds, as pkg-config is not needed
> then.
>
> It is handled in Makefile.perf rather than Makefile.config, as
> Makefile.config is included after the pkg-config and shellcheck setup.
>
> Use it for make_minimal in tests/make.
>
> Suggested-by: Ian Rogers <irogers@google.com>
> Link: https://lore.kernel.org/r/CAP-5=fWFY-tpJz2vcBZvurwdZY5gwd8cuTemE9q1rtZ0Vi0dng@mail.gmail.com
> Assisted-by: LLM
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
> tools/perf/Makefile.config | 8 ++++++--
> tools/perf/Makefile.perf | 40 ++++++++++++++++++++++++++++++++++++--
> tools/perf/tests/make | 8 +-------
> 3 files changed, 45 insertions(+), 11 deletions(-)
>
> diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
> index 4d5993da9f945..137c9e120670b 100644
> --- a/tools/perf/Makefile.config
> +++ b/tools/perf/Makefile.config
> @@ -742,7 +742,9 @@ dwarf-post-unwind-text := BUG
> # setup DWARF post unwinder
> ifdef NO_LIBUNWIND
> ifdef NO_LIBDW
> - $(warning Disabling post unwind, no support found.)
> + ifneq ($(MINIMAL),1)
> + $(warning Disabling post unwind, no support found.)
> + endif
> dwarf-post-unwind := 0
> else
> dwarf-post-unwind-text := libdw
> @@ -828,7 +830,9 @@ endef
>
> PYTHON_EXTENSION_SUFFIX := '.so'
> ifdef NO_LIBPYTHON
> - $(call disable-python,Python support disabled by user)
> + ifneq ($(MINIMAL),1)
> + $(call disable-python,Python support disabled by user)
> + endif
Thanks for the clean up!
In perf-tools-next/linux-next both LIBPYTHON and LIBPERL are gone
(context in https://lore.kernel.org/linux-perf-users/20260926062029.800743-47-irogers@google.com/#t
).
> else
>
> ifndef PYTHON
> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> index 29cfd44c427f3..c770077e7d392 100644
> --- a/tools/perf/Makefile.perf
> +++ b/tools/perf/Makefile.perf
> @@ -129,6 +129,9 @@ include ../scripts/utilities.mak
> # Define GEN_VMLINUX_H to generate vmlinux.h from the BTF.
> #
> # Define NO_SHELLCHECK if you do not want to run shellcheck during build
> +#
> +# Define MINIMAL=1 to build without any optional feature, needing only a C
> +# compiler and library, flex and bison
>
> # As per kernel Makefile, avoid funny character set dependencies
> unexport LC_ALL
> @@ -174,6 +177,37 @@ endef
>
> LD += $(EXTRA_LDFLAGS)
>
> +# MINIMAL=1 is handled here rather than in Makefile.config, which is included
> +# after the pkg-config and shellcheck setup below
> +ifeq ($(MINIMAL),1)
> + NO_LIBELF := 1
> + NO_LIBDW := 1
> + NO_LIBTRACEEVENT := 1
> + NO_JEVENTS := 1
> + NO_LIBPYTHON := 1
> + NO_LIBBPF := 1
> + BUILD_BPF_SKEL := 0
> + NO_SLANG := 1
> + NO_DEMANGLE := 1
> + NO_BACKTRACE := 1
> + NO_AIO := 1
> + NO_ZLIB := 1
> + NO_LZMA := 1
> + NO_LIBZSTD := 1
> + NO_LIBNUMA := 1
> + NO_LIBLLVM := 1
> + NO_CAPSTONE := 1
> + NO_LIBPFM4 := 1
> + NO_LIBDEBUGINFOD := 1
> + NO_BABELTRACE2 := 1
> + NO_SDT := 1
> + NO_JVMTI := 1
> + NO_RUST := 1
> + NO_PERF_READ_VDSO32 := 1
> + NO_PERF_READ_VDSOX32 := 1
> + NO_SHELLCHECK := 1
We should expand this with NO_MYPY and NO_PYLINT for the
perf-tools-next version.
Thanks,
Ian
> +endif
> +
> # Some distros provide the command $(CROSS_COMPILE)pkg-config for
> # searching packges installed with Multiarch. Use it for cross
> # compilation if it is existed.
> @@ -195,8 +229,10 @@ else
> PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/local/share/pkgconfig/
> PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/share/pkgconfig/
> export PKG_CONFIG_LIBDIR
> - $(warning Missing PKG_CONFIG_LIBDIR, PKG_CONFIG_PATH and PKG_CONFIG_SYSROOT_DIR for cross compilation,)
> - $(warning set PKG_CONFIG_LIBDIR for using Multiarch libs.)
> + ifneq ($(MINIMAL),1)
> + $(warning Missing PKG_CONFIG_LIBDIR, PKG_CONFIG_PATH and PKG_CONFIG_SYSROOT_DIR for cross compilation,)
> + $(warning set PKG_CONFIG_LIBDIR for using Multiarch libs.)
> + endif
> endif
> endif
> endif
> diff --git a/tools/perf/tests/make b/tools/perf/tests/make
> index d2c2f526e1db0..dbbc971a144b2 100644
> --- a/tools/perf/tests/make
> +++ b/tools/perf/tests/make
> @@ -115,13 +115,7 @@ make_install_prefix := install prefix=/tmp/krava
> make_install_prefix_slash := install prefix=/tmp/krava/
> make_static := LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX32=1 NO_JVMTI=1 NO_LIBTRACEEVENT=1 NO_LIBELF=1
>
> -# all the NO_* variable combined
> -make_minimal := NO_LIBPYTHON=1
> -make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_BACKTRACE=1
> -make_minimal += NO_LIBNUMA=1 NO_LIBBIONIC=1 NO_LIBDW=1
> -make_minimal += NO_LIBBPF=1
> -make_minimal += NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1
> -make_minimal += NO_CAPSTONE=1
> +make_minimal := MINIMAL=1
>
> # binutils 2_42 and newer have bfd_thread_init()
> new_libbfd := $(shell echo '#include <bfd.h>' | $(CC) -E -x c - | grep bfd_thread_init)
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC PATCH v2 4/7] tools: build perf in tools_build
2026-10-16 14:31 [RFC PATCH v2 0/7] kbuild: build the userspace tools in tools/ with the kernel Sasha Levin
` (2 preceding siblings ...)
2026-10-16 14:31 ` [RFC PATCH v2 3/7] perf build: Add MINIMAL=1 to build without optional features Sasha Levin
@ 2026-10-16 14:31 ` Sasha Levin
2026-10-16 14:31 ` [RFC PATCH v2 5/7] tools: build kernel selftests " Sasha Levin
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Sasha Levin @ 2026-10-16 14:31 UTC (permalink / raw)
To: Nathan Chancellor, Nicolas Schier, linux-kbuild
Cc: Sasha Levin, Shuah Khan, linux-kselftest, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, linux-perf-users, Thomas Weißschuh,
Andrew Morton, linux-kernel
Add CONFIG_TOOLS_BUILD_PERF. perf is built as it is built standalone,
with optional features enabled when their libraries are installed, and
with perf's WERROR setting following CONFIG_WERROR. The feature table is
left out of the kernel build log.
CONFIG_TOOLS_BUILD_PERF_MINIMAL builds it with MINIMAL=1 instead, which
turns every optional feature off, so the result does not depend on the
build machine. allmodconfig and allyesconfig turn it on.
Assisted-by: LLM
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/Kconfig | 16 ++++++++++++++++
tools/Makefile.kbuild | 10 ++++++++++
2 files changed, 26 insertions(+)
diff --git a/tools/Kconfig b/tools/Kconfig
index 2d05c8e593e21..4f13e3b104377 100644
--- a/tools/Kconfig
+++ b/tools/Kconfig
@@ -60,6 +60,22 @@ config TOOLS_BUILD_IIO
help
Build tools/iio (lsiio, iio_event_monitor, iio_generic_buffer).
+config TOOLS_BUILD_PERF
+ bool "perf"
+ help
+ Build tools/perf. As in a standalone perf build, optional
+ features are enabled when the libraries they need are installed.
+
+config TOOLS_BUILD_PERF_MINIMAL
+ bool "Build perf with all optional features disabled"
+ depends on TOOLS_BUILD_PERF
+ help
+ Build perf with MINIMAL=1, which turns off every optional
+ feature, so that the result does not depend on which libraries
+ the build machine has installed. allmodconfig and allyesconfig
+ turn this on, which keeps their builds the same on every
+ machine.
+
config TOOLS_BUILD_SPI
bool "SPI tools"
help
diff --git a/tools/Makefile.kbuild b/tools/Makefile.kbuild
index 8cfa7f80039cd..4b3ea73bc8ab9 100644
--- a/tools/Makefile.kbuild
+++ b/tools/Makefile.kbuild
@@ -79,6 +79,16 @@ PHONY += $(tool-targets)
$(tool-targets): tool-%: FORCE
$(call build,$(outdir)/$*,-C $(toolsdir)/$* O=$(outdir)/$* CC='$(call escsq,$(tools-cc))',,TOOLS_BUILD_$(shell echo $* | tr a-z A-Z))
+# perf, without the feature table in the kernel build log
+perf-flags := CC='$(call escsq,$(tools-cc))' FEATURE_DISPLAY= WERROR=$(if $(CONFIG_WERROR),1,0)
+perf-flags-$(CONFIG_TOOLS_BUILD_PERF_MINIMAL) += MINIMAL=1
+
+__tools_build: $(if $(CONFIG_TOOLS_BUILD_PERF),perf)
+
+PHONY += perf
+perf: FORCE
+ $(call build,$(outdir)/perf,-C $(toolsdir)/perf -f Makefile.perf O=$(outdir)/perf $(perf-flags) $(perf-flags-y),,TOOLS_BUILD_PERF)
+
PHONY += FORCE
FORCE:
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC PATCH v2 5/7] tools: build kernel selftests in tools_build
2026-10-16 14:31 [RFC PATCH v2 0/7] kbuild: build the userspace tools in tools/ with the kernel Sasha Levin
` (3 preceding siblings ...)
2026-10-16 14:31 ` [RFC PATCH v2 4/7] tools: build perf in tools_build Sasha Levin
@ 2026-10-16 14:31 ` Sasha Levin
2026-10-16 16:17 ` Shuah Khan
2026-10-16 14:31 ` [RFC PATCH v2 6/7] kbuild: build the tools selected in tools/Kconfig as part of "make all" Sasha Levin
2026-10-16 14:31 ` [RFC PATCH v2 7/7] Documentation: describe building tools with the kernel Sasha Levin
6 siblings, 1 reply; 10+ messages in thread
From: Sasha Levin @ 2026-10-16 14:31 UTC (permalink / raw)
To: Nathan Chancellor, Nicolas Schier, linux-kbuild
Cc: Sasha Levin, Shuah Khan, linux-kselftest, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, linux-perf-users, Thomas Weißschuh,
Andrew Morton, linux-kernel
Add a "Kernel selftests" sub-menu with one entry per selftests directory
that builds with only a C library and does not write into the source
tree. Each is built as "make kselftest-all" builds it, with KHDR_INCLUDES
pointing at the UAPI headers installed in the object tree, but by its own
make, so the selected ones build in parallel. Selftests whose Makefile
does not use KHDR_INCLUDES still build against the C library's copy of
the UAPI headers.
As with "make kselftest-all", a selftest that fails to build does not
fail the build unless FORCE_TARGETS is set. kselftest_deps.sh then lists
the libraries the selftest needs that the compiler cannot link with.
The selftests do not track header dependencies, so a selftest is built
again from scratch when its own directory, a header or makefile any
selftest may share, or the kernel sources and headers it includes (the
vDSO test includes the architecture's vDSO code) are newer than its last
build.
Selftests that need libraries beyond the C library, a vmlinux with BTF,
or a sanitizer runtime are left out for now.
Assisted-by: LLM
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/Kconfig | 241 ++++++++++++++++++++++++++++++++++++++++++
tools/Makefile.kbuild | 118 ++++++++++++++++++++-
2 files changed, 355 insertions(+), 4 deletions(-)
diff --git a/tools/Kconfig b/tools/Kconfig
index 4f13e3b104377..45e53383b2459 100644
--- a/tools/Kconfig
+++ b/tools/Kconfig
@@ -86,4 +86,245 @@ config TOOLS_BUILD_USB
help
Build tools/usb (testusb, ffs-test).
+menuconfig TOOLS_BUILD_SELFTESTS
+ bool "Kernel selftests"
+ help
+ Build the selected targets under tools/testing/selftests, as
+ "make kselftest-all" would, without running them. As there, a
+ selftest that fails to build does not fail the build unless
+ FORCE_TARGETS=1 is passed to make.
+
+if TOOLS_BUILD_SELFTESTS
+
+config TOOLS_BUILD_SELFTESTS_ACCT
+ bool "acct"
+
+config TOOLS_BUILD_SELFTESTS_ALLOC_TAG
+ bool "alloc_tag"
+
+config TOOLS_BUILD_SELFTESTS_BREAKPOINTS
+ bool "breakpoints"
+
+config TOOLS_BUILD_SELFTESTS_CACHESTAT
+ bool "cachestat"
+
+config TOOLS_BUILD_SELFTESTS_CGROUP
+ bool "cgroup"
+
+config TOOLS_BUILD_SELFTESTS_CONNECTOR
+ bool "connector"
+
+config TOOLS_BUILD_SELFTESTS_CORE
+ bool "core"
+
+config TOOLS_BUILD_SELFTESTS_COREDUMP
+ bool "coredump"
+
+config TOOLS_BUILD_SELFTESTS_DAMON
+ bool "damon"
+
+config TOOLS_BUILD_SELFTESTS_DMABUF_HEAPS
+ bool "dmabuf-heaps"
+
+config TOOLS_BUILD_SELFTESTS_DRIVERS_DMA_BUF
+ bool "drivers/dma-buf"
+
+config TOOLS_BUILD_SELFTESTS_DRIVERS_NTSYNC
+ bool "drivers/ntsync"
+
+config TOOLS_BUILD_SELFTESTS_EFIVARFS
+ bool "efivarfs"
+
+config TOOLS_BUILD_SELFTESTS_FILELOCK
+ bool "filelock"
+
+config TOOLS_BUILD_SELFTESTS_FILESYSTEMS_BINDERFS
+ bool "filesystems/binderfs"
+
+config TOOLS_BUILD_SELFTESTS_FILESYSTEMS_EPOLL
+ bool "filesystems/epoll"
+
+config TOOLS_BUILD_SELFTESTS_FILESYSTEMS_EVENTFD
+ bool "filesystems/eventfd"
+
+config TOOLS_BUILD_SELFTESTS_FILESYSTEMS_FAILFS
+ bool "filesystems/failfs"
+
+config TOOLS_BUILD_SELFTESTS_FILESYSTEMS_FAT
+ bool "filesystems/fat"
+
+config TOOLS_BUILD_SELFTESTS_FILESYSTEMS_MNTNS_UNBINDABLE
+ bool "filesystems/mntns_unbindable"
+
+config TOOLS_BUILD_SELFTESTS_FILESYSTEMS_MOUNT_CYCLE
+ bool "filesystems/mount_cycle"
+
+config TOOLS_BUILD_SELFTESTS_FILESYSTEMS_NSFS
+ bool "filesystems/nsfs"
+
+config TOOLS_BUILD_SELFTESTS_FILESYSTEMS_UMOUNT_PROPAGATION
+ bool "filesystems/umount_propagation"
+
+config TOOLS_BUILD_SELFTESTS_FILESYSTEMS_XATTR
+ bool "filesystems/xattr"
+
+config TOOLS_BUILD_SELFTESTS_FIRMWARE
+ bool "firmware"
+
+config TOOLS_BUILD_SELFTESTS_FPU
+ bool "fpu"
+
+config TOOLS_BUILD_SELFTESTS_FTRACE
+ bool "ftrace"
+
+config TOOLS_BUILD_SELFTESTS_GPIO
+ bool "gpio"
+
+config TOOLS_BUILD_SELFTESTS_INTEL_PSTATE
+ bool "intel_pstate"
+ depends on X86
+
+config TOOLS_BUILD_SELFTESTS_IPC
+ bool "ipc"
+
+config TOOLS_BUILD_SELFTESTS_IR
+ bool "ir"
+
+config TOOLS_BUILD_SELFTESTS_KCMP
+ bool "kcmp"
+
+config TOOLS_BUILD_SELFTESTS_KEXEC
+ bool "kexec"
+ depends on X86_64
+
+config TOOLS_BUILD_SELFTESTS_KSELFTEST_HARNESS
+ bool "kselftest_harness"
+
+config TOOLS_BUILD_SELFTESTS_LSM
+ bool "lsm"
+
+config TOOLS_BUILD_SELFTESTS_MEDIA_TESTS
+ bool "media_tests"
+
+config TOOLS_BUILD_SELFTESTS_MEMBARRIER
+ bool "membarrier"
+
+config TOOLS_BUILD_SELFTESTS_MINCORE
+ bool "mincore"
+
+config TOOLS_BUILD_SELFTESTS_MOUNT
+ bool "mount"
+
+config TOOLS_BUILD_SELFTESTS_MOUNT_SETATTR
+ bool "mount_setattr"
+
+config TOOLS_BUILD_SELFTESTS_MOVE_MOUNT_SET_GROUP
+ bool "move_mount_set_group"
+
+config TOOLS_BUILD_SELFTESTS_MSEAL_SYSTEM_MAPPINGS
+ bool "mseal_system_mappings"
+
+config TOOLS_BUILD_SELFTESTS_NCI
+ bool "nci"
+
+config TOOLS_BUILD_SELFTESTS_NET_CAN
+ bool "net/can"
+
+config TOOLS_BUILD_SELFTESTS_NET_FORWARDING
+ bool "net/forwarding"
+
+config TOOLS_BUILD_SELFTESTS_NET_MPTCP
+ bool "net/mptcp"
+
+config TOOLS_BUILD_SELFTESTS_PCI_ENDPOINT
+ bool "pci_endpoint"
+
+config TOOLS_BUILD_SELFTESTS_PERF_EVENTS
+ bool "perf_events"
+
+config TOOLS_BUILD_SELFTESTS_PID_NAMESPACE
+ bool "pid_namespace"
+
+config TOOLS_BUILD_SELFTESTS_PIDFD
+ bool "pidfd"
+
+config TOOLS_BUILD_SELFTESTS_PIPE
+ bool "pipe"
+
+config TOOLS_BUILD_SELFTESTS_PROC
+ bool "proc"
+
+config TOOLS_BUILD_SELFTESTS_PTP
+ bool "ptp"
+
+config TOOLS_BUILD_SELFTESTS_PTRACE
+ bool "ptrace"
+
+config TOOLS_BUILD_SELFTESTS_RESCTRL
+ bool "resctrl"
+ depends on X86
+
+config TOOLS_BUILD_SELFTESTS_RING_BUFFER
+ bool "ring-buffer"
+
+config TOOLS_BUILD_SELFTESTS_RLIMITS
+ bool "rlimits"
+
+config TOOLS_BUILD_SELFTESTS_RSEQ
+ bool "rseq"
+
+config TOOLS_BUILD_SELFTESTS_RTC
+ bool "rtc"
+
+config TOOLS_BUILD_SELFTESTS_SCHED
+ bool "sched"
+
+config TOOLS_BUILD_SELFTESTS_SIGNAL
+ bool "signal"
+
+config TOOLS_BUILD_SELFTESTS_SIZE
+ bool "size"
+
+config TOOLS_BUILD_SELFTESTS_SPLICE
+ bool "splice"
+
+config TOOLS_BUILD_SELFTESTS_SYNC
+ bool "sync"
+
+config TOOLS_BUILD_SELFTESTS_SYSCALL_USER_DISPATCH
+ bool "syscall_user_dispatch"
+
+config TOOLS_BUILD_SELFTESTS_TDX
+ bool "tdx"
+ depends on X86
+
+config TOOLS_BUILD_SELFTESTS_THERMAL_INTEL_POWER_FLOOR
+ bool "thermal/intel/power_floor"
+ depends on X86
+
+config TOOLS_BUILD_SELFTESTS_THERMAL_INTEL_WORKLOAD_HINT
+ bool "thermal/intel/workload_hint"
+ depends on X86
+
+config TOOLS_BUILD_SELFTESTS_TIMENS
+ bool "timens"
+
+config TOOLS_BUILD_SELFTESTS_TMPFS
+ bool "tmpfs"
+
+config TOOLS_BUILD_SELFTESTS_USER_EVENTS
+ bool "user_events"
+
+config TOOLS_BUILD_SELFTESTS_VDSO
+ bool "vDSO"
+
+config TOOLS_BUILD_SELFTESTS_WATCHDOG
+ bool "watchdog"
+
+config TOOLS_BUILD_SELFTESTS_X86
+ bool "x86"
+ depends on X86
+
+endif # TOOLS_BUILD_SELFTESTS
+
endif # TOOLS_BUILD
diff --git a/tools/Makefile.kbuild b/tools/Makefile.kbuild
index 4b3ea73bc8ab9..6527ab9f79a2c 100644
--- a/tools/Makefile.kbuild
+++ b/tools/Makefile.kbuild
@@ -44,10 +44,11 @@ endif
squote := '
escsq = $(subst $(squote),'\$(squote)',$1)
-# $(call build,<output directory>,<make arguments>,<files to check>,<CONFIG_ symbol>)
+# $(call build,<output directory>,<make arguments>,<files to check>,<CONFIG_ symbol>[,<on failure>])
# Builds in an empty directory when the make arguments or LDFLAGS changed, or
-# when one of the files is newer than the last build. "make -n" only shows
-# the build.
+# when one of the files is newer than the last build. A failure fails the
+# build, unless commands to run instead are given. "make -n" only shows the
+# build.
build-key = $(call escsq,$(2) LDFLAGS=$(USERLDFLAGS))
dry-run := $(findstring n,$(firstword -$(MAKEFLAGS)))
@@ -58,7 +59,7 @@ define build
fi;) \
mkdir -p $(1) && $(MAKE) $(2) && \
$(if $(dry-run),:,printf '%s' '$(build-key)' > $(1)/.tools_build) || \
- { echo >&2 "tools_build: $(patsubst $(outdir)/%,%,$(1)) failed to build; set CONFIG_$(4)=n to skip it"; false; }
+ { echo >&2 "tools_build: $(patsubst $(outdir)/%,%,$(1)) failed to build; set CONFIG_$(4)=n to skip it"; $(or $(5),false); }
endef
# Programs in tools/<name>, which track their own header dependencies
@@ -89,6 +90,115 @@ PHONY += perf
perf: FORCE
$(call build,$(outdir)/perf,-C $(toolsdir)/perf -f Makefile.perf O=$(outdir)/perf $(perf-flags) $(perf-flags-y),,TOOLS_BUILD_PERF)
+# Selftests in tools/testing/selftests/<name>
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_ACCT) += acct
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_ALLOC_TAG) += alloc_tag
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_BREAKPOINTS) += breakpoints
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_CACHESTAT) += cachestat
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_CGROUP) += cgroup
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_CONNECTOR) += connector
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_CORE) += core
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_COREDUMP) += coredump
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_DAMON) += damon
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_DMABUF_HEAPS) += dmabuf-heaps
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_DRIVERS_DMA_BUF) += drivers/dma-buf
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_DRIVERS_NTSYNC) += drivers/ntsync
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_EFIVARFS) += efivarfs
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FILELOCK) += filelock
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FILESYSTEMS_BINDERFS) += filesystems/binderfs
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FILESYSTEMS_EPOLL) += filesystems/epoll
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FILESYSTEMS_EVENTFD) += filesystems/eventfd
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FILESYSTEMS_FAILFS) += filesystems/failfs
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FILESYSTEMS_FAT) += filesystems/fat
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FILESYSTEMS_MNTNS_UNBINDABLE) += filesystems/mntns_unbindable
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FILESYSTEMS_MOUNT_CYCLE) += filesystems/mount_cycle
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FILESYSTEMS_NSFS) += filesystems/nsfs
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FILESYSTEMS_UMOUNT_PROPAGATION) += filesystems/umount_propagation
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FILESYSTEMS_XATTR) += filesystems/xattr
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FIRMWARE) += firmware
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FPU) += fpu
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_FTRACE) += ftrace
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_GPIO) += gpio
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_INTEL_PSTATE) += intel_pstate
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_IPC) += ipc
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_IR) += ir
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_KCMP) += kcmp
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_KEXEC) += kexec
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_KSELFTEST_HARNESS) += kselftest_harness
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_LSM) += lsm
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_MEDIA_TESTS) += media_tests
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_MEMBARRIER) += membarrier
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_MINCORE) += mincore
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_MOUNT) += mount
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_MOUNT_SETATTR) += mount_setattr
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_MOVE_MOUNT_SET_GROUP) += move_mount_set_group
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_MSEAL_SYSTEM_MAPPINGS) += mseal_system_mappings
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_NCI) += nci
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_NET_CAN) += net/can
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_NET_FORWARDING) += net/forwarding
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_NET_MPTCP) += net/mptcp
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_PCI_ENDPOINT) += pci_endpoint
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_PERF_EVENTS) += perf_events
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_PID_NAMESPACE) += pid_namespace
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_PIDFD) += pidfd
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_PIPE) += pipe
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_PROC) += proc
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_PTP) += ptp
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_PTRACE) += ptrace
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_RESCTRL) += resctrl
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_RING_BUFFER) += ring-buffer
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_RLIMITS) += rlimits
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_RSEQ) += rseq
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_RTC) += rtc
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_SCHED) += sched
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_SIGNAL) += signal
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_SIZE) += size
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_SPLICE) += splice
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_SYNC) += sync
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_SYSCALL_USER_DISPATCH) += syscall_user_dispatch
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_TDX) += tdx
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_THERMAL_INTEL_POWER_FLOOR) += thermal/intel/power_floor
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_THERMAL_INTEL_WORKLOAD_HINT) += thermal/intel/workload_hint
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_TIMENS) += timens
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_TMPFS) += tmpfs
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_USER_EVENTS) += user_events
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_VDSO) += vDSO
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_WATCHDOG) += watchdog
+selftests-$(CONFIG_TOOLS_BUILD_SELFTESTS_X86) += x86
+
+selftest-flags := CC='$(call escsq,$(tools-cc))' KHDR_INCLUDES='-isystem $(CURDIR)/usr/include'
+
+# Unlike tools/build, the selftests do not track header dependencies. A
+# selftest is built again from scratch when its own directory, a header or
+# makefile any selftest may share, or the kernel sources and headers it
+# includes are newer than its last build.
+selftest-shared := $(outdir)/selftests/.shared
+selftest-extra-vDSO := $(abs_srctree)/arch/$(SRCARCH) $(abs_srctree)/include
+selftest-extra-x86 := $(abs_srctree)/arch/x86/include
+
+$(selftest-shared): FORCE
+ $(Q)mkdir -p $(@D); \
+ newest=$$(find $(CURDIR)/usr/include $(toolsdir)/include $(toolsdir)/arch $(toolsdir)/testing/selftests \
+ -type f \( -name '*.h' -o -name '*.mk' -o -name Makefile \) -printf '%T@\n' | \
+ sort -n | tail -n 1); \
+ touch -d "@$${newest:-0}" $@
+
+# As with "make kselftest-all", a selftest that fails to build does not fail
+# the build unless FORCE_TARGETS is set. kselftest_deps.sh lists the libraries
+# it needs that the compiler cannot link with. It leaves files behind in
+# TMPDIR, so it gets one of its own.
+selftest-failed = (cd $(toolsdir)/testing/selftests && tmp=$$(mktemp -d) && \
+ TMPDIR=$$tmp ./kselftest_deps.sh '$(call escsq,$(tools-cc))' $(1) | grep '^FAIL' >&2; \
+ rm -rf "$$tmp"); $(if $(FORCE_TARGETS),false,:)
+
+selftest-targets := $(addprefix selftest-,$(selftests-y))
+
+__tools_build: $(selftest-targets)
+
+PHONY += $(selftest-targets)
+$(selftest-targets): selftest-%: $(selftest-shared) FORCE
+ $(call build,$(outdir)/selftests/$*,-C $(toolsdir)/testing/selftests/$* OUTPUT=$(outdir)/selftests/$* $(selftest-flags),$(selftest-shared) $(toolsdir)/testing/selftests/$* $(selftest-extra-$*),TOOLS_BUILD_SELFTESTS_$(shell echo $* | tr a-z/- A-Z__),$(call selftest-failed,$*))
+
PHONY += FORCE
FORCE:
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [RFC PATCH v2 5/7] tools: build kernel selftests in tools_build
2026-10-16 14:31 ` [RFC PATCH v2 5/7] tools: build kernel selftests " Sasha Levin
@ 2026-10-16 16:17 ` Shuah Khan
0 siblings, 0 replies; 10+ messages in thread
From: Shuah Khan @ 2026-10-16 16:17 UTC (permalink / raw)
To: Sasha Levin, Nathan Chancellor, Nicolas Schier, linux-kbuild
Cc: Shuah Khan, linux-kselftest, Peter Zijlstra, Ingo Molnar,
Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, linux-perf-users, Thomas Weißschuh,
Andrew Morton, linux-kernel, Shuah Khan
On 10/16/26 08:31, Sasha Levin wrote:
> Add a "Kernel selftests" sub-menu with one entry per selftests directory
> that builds with only a C library and does not write into the source
> tree. Each is built as "make kselftest-all" builds it, with KHDR_INCLUDES
> pointing at the UAPI headers installed in the object tree, but by its own
> make, so the selected ones build in parallel. Selftests whose Makefile
> does not use KHDR_INCLUDES still build against the C library's copy of
> the UAPI headers.
>
> As with "make kselftest-all", a selftest that fails to build does not
> fail the build unless FORCE_TARGETS is set. kselftest_deps.sh then lists
> the libraries the selftest needs that the compiler cannot link with.
>
> The selftests do not track header dependencies, so a selftest is built
> again from scratch when its own directory, a header or makefile any
> selftest may share, or the kernel sources and headers it includes (the
> vDSO test includes the architecture's vDSO code) are newer than its last
> build.
>
> Selftests that need libraries beyond the C library, a vmlinux with BTF,
> or a sanitizer runtime are left out for now.
>
> Assisted-by: LLM
> Signed-off-by: Sasha Levin <sashal@kernel.org>
Thank you.
Reviewed-by: Shuah Khan <skhan@linuxfoundation.org>
thanks,
-- Shuah
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC PATCH v2 6/7] kbuild: build the tools selected in tools/Kconfig as part of "make all"
2026-10-16 14:31 [RFC PATCH v2 0/7] kbuild: build the userspace tools in tools/ with the kernel Sasha Levin
` (4 preceding siblings ...)
2026-10-16 14:31 ` [RFC PATCH v2 5/7] tools: build kernel selftests " Sasha Levin
@ 2026-10-16 14:31 ` Sasha Levin
2026-10-16 14:31 ` [RFC PATCH v2 7/7] Documentation: describe building tools with the kernel Sasha Levin
6 siblings, 0 replies; 10+ messages in thread
From: Sasha Levin @ 2026-10-16 14:31 UTC (permalink / raw)
To: Nathan Chancellor, Nicolas Schier, linux-kbuild
Cc: Sasha Levin, Shuah Khan, linux-kselftest, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, linux-perf-users, Thomas Weißschuh,
Andrew Morton, linux-kernel
With CONFIG_TOOLS_BUILD set, make "all" depend on tools_build, so the
selected tools are built with every kernel build, and allmodconfig and
allyesconfig builds catch changes that break them.
"make vmlinux", "make modules", single target and external module
builds are unaffected.
Assisted-by: LLM
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Makefile | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Makefile b/Makefile
index af5d0a9d51df9..1c55086ea5c8b 100644
--- a/Makefile
+++ b/Makefile
@@ -1638,6 +1638,10 @@ PHONY += tools_build
tools_build: headers
$(Q)$(MAKE) -f $(srctree)/tools/Makefile.kbuild
+ifdef CONFIG_TOOLS_BUILD
+all: tools_build
+endif
+
# ---------------------------------------------------------------------------
# Kernel selftest
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [RFC PATCH v2 7/7] Documentation: describe building tools with the kernel
2026-10-16 14:31 [RFC PATCH v2 0/7] kbuild: build the userspace tools in tools/ with the kernel Sasha Levin
` (5 preceding siblings ...)
2026-10-16 14:31 ` [RFC PATCH v2 6/7] kbuild: build the tools selected in tools/Kconfig as part of "make all" Sasha Levin
@ 2026-10-16 14:31 ` Sasha Levin
6 siblings, 0 replies; 10+ messages in thread
From: Sasha Levin @ 2026-10-16 14:31 UTC (permalink / raw)
To: Nathan Chancellor, Nicolas Schier, linux-kbuild
Cc: Sasha Levin, Shuah Khan, linux-kselftest, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, linux-perf-users, Thomas Weißschuh,
Andrew Morton, linux-kernel
Mention CONFIG_TOOLS_BUILD and "make tools_build" in the submit
checklist, ask for libc-only selftests to be added to tools/Kconfig,
and note that USERCFLAGS and USERLDFLAGS also apply to the tools.
Assisted-by: LLM
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/dev-tools/kselftest.rst | 4 ++++
Documentation/kbuild/kbuild.rst | 4 +++-
Documentation/process/submit-checklist.rst | 5 +++++
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/Documentation/dev-tools/kselftest.rst b/Documentation/dev-tools/kselftest.rst
index 64c0ec7428a27..407d539e49b01 100644
--- a/Documentation/dev-tools/kselftest.rst
+++ b/Documentation/dev-tools/kselftest.rst
@@ -315,6 +315,10 @@ Contributing new tests (details)
TARGETS += android
+ * If the test builds with only a C library, add an entry for it to the
+ "Kernel selftests" menu in tools/Kconfig and to tools/Makefile.kbuild,
+ so that it is built together with the kernel.
+
* All changes should pass::
kselftest-{all,install,clean,gen_tar}
diff --git a/Documentation/kbuild/kbuild.rst b/Documentation/kbuild/kbuild.rst
index 5a9013bacfb75..84da035fc66f6 100644
--- a/Documentation/kbuild/kbuild.rst
+++ b/Documentation/kbuild/kbuild.rst
@@ -114,12 +114,14 @@ Additional libraries to link against when building host programs.
USERCFLAGS
----------
-Additional options used for $(CC) when compiling userprogs.
+Additional options used for $(CC) when compiling userprogs and the tools
+selected in tools/Kconfig.
USERLDFLAGS
-----------
Additional options used for $(LD) when linking userprogs. userprogs are linked
with CC, so $(USERLDFLAGS) should include "-Wl," prefix as applicable.
+The tools selected in tools/Kconfig get these options in LDFLAGS.
KBUILD_KCONFIG
--------------
diff --git a/Documentation/process/submit-checklist.rst b/Documentation/process/submit-checklist.rst
index beb7f94279fdb..9857b05824c2d 100644
--- a/Documentation/process/submit-checklist.rst
+++ b/Documentation/process/submit-checklist.rst
@@ -91,6 +91,11 @@ Build your code
Use ``make htmldocs`` or ``make pdfdocs`` to check the build and
fix any issues.
+ e) Changes to tools/ or to UAPI headers do not break the userspace tools
+ selected by ``CONFIG_TOOLS_BUILD``. ``allmodconfig`` turns it on when
+ the compiler can link glibc programs for the target (currently x86_64
+ and arm64), and ``make tools_build`` builds only the tools.
+
2) Builds on multiple CPU architectures by using local cross-compile tools
or some other build farm.
Note that testing against architectures of different word sizes
--
2.53.0
^ permalink raw reply related [flat|nested] 10+ messages in thread