From: Ian Rogers <irogers@google.com>
To: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Ian Rogers <irogers@google.com>, Quentin Monnet <qmo@kernel.org>,
Miguel Ojeda <ojeda@kernel.org>,
Nathan Chancellor <nathan@kernel.org>,
Nicolas Schier <nsc@kernel.org>,
Nick Desaulniers <ndesaulniers@google.com>,
Bill Wendling <morbo@google.com>,
Justin Stitt <justinstitt@google.com>
Cc: linux-perf-users@vger.kernel.org, bpf@vger.kernel.org,
rust-for-linux@vger.kernel.org, linux-kbuild@vger.kernel.org,
llvm@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: [RFC PATCH v1 2/3] perf build: Prefer zlib-rs over zlib when available
Date: Thu, 29 Oct 2026 09:29:57 -0700 [thread overview]
Message-ID: <20261029162958.3224280-3-irogers@google.com> (raw)
In-Reply-To: <20261029162958.3224280-1-irogers@google.com>
Detect and prefer zlib-rs over C zlib in the perf build unless disabled
with NO_ZLIB_RS=1 (or NO_ZLIB=1 / NO_RUST=1):
- Move Rust compiler detection ahead of zlib detection in
tools/perf/Makefile.config and use feature_check + feature_rust_lib for
zlib-rs, setting both HAVE_ZLIB_SUPPORT and HAVE_ZLIB_RS_SUPPORT when
zlib-rs is used and falling back to C zlib (-lz) otherwise.
- Build and clean libz_rs.a in $(OUTPUT)libz_rs/, pass ZLIB_CFLAGS when
building static libbpf, and share RUST_OUTPUT with the host bootstrap
bpftool build in tools/perf/bpf_skel.mak.
- Expose 'zlib-rs' in 'perf check feature' / 'perf version --build-options'
and document it in perf-check.txt.
- Add zlib-rs package mappings to tools/perf/scripts/install-build-deps.sh
and NO_ZLIB / NO_ZLIB_RS build tests to tools/perf/tests/make.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/.gitignore | 1 +
tools/perf/Documentation/perf-check.txt | 1 +
tools/perf/Makefile.config | 89 ++++++++++++++----------
tools/perf/Makefile.perf | 32 ++++++++-
tools/perf/bpf_skel.mak | 8 ++-
tools/perf/builtin-check.c | 1 +
tools/perf/scripts/install-build-deps.sh | 6 ++
tools/perf/tests/make | 9 +++
8 files changed, 105 insertions(+), 42 deletions(-)
diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore
index 3b968c5158b8..8a5df9c9e8ae 100644
--- a/tools/perf/.gitignore
+++ b/tools/perf/.gitignore
@@ -55,6 +55,7 @@ libbpf/
libperf/
libsubcmd/
libsymbol/
+libz_rs/
fixdep
Documentation/doc.dep
python_ext_build/
diff --git a/tools/perf/Documentation/perf-check.txt b/tools/perf/Documentation/perf-check.txt
index 1406a41c5d09..dda75b1d9cbd 100644
--- a/tools/perf/Documentation/perf-check.txt
+++ b/tools/perf/Documentation/perf-check.txt
@@ -66,6 +66,7 @@ feature::
numa_num_possible_cpus / HAVE_LIBNUMA_SUPPORT
python-module / HAVE_PYTHON_MODULE_SUPPORT
zlib / HAVE_ZLIB_SUPPORT
+ zlib-rs / HAVE_ZLIB_RS_SUPPORT
zstd / HAVE_ZSTD_SUPPORT
OPTIONS
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index b4764f69f47f..4313fca53aa7 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -532,13 +532,57 @@ ifdef CORESIGHT
endif
endif
-ifndef NO_ZLIB
- ifeq ($(feature-zlib), 1)
- CFLAGS += -DHAVE_ZLIB_SUPPORT
- EXTLIBS += -lz
- $(call detected,CONFIG_ZLIB)
+ifndef NO_RUST
+ $(call feature_check,rust)
+ ifneq ($(feature-rust), 1)
+ $(warning Rust is not found. Test workloads with rust are disabled.)
+ NO_RUST := 1
else
- NO_ZLIB := 1
+ NO_RUST := 0
+ CFLAGS += -DHAVE_RUST_SUPPORT
+ $(call detected,CONFIG_RUST_SUPPORT)
+ endif
+
+ ifneq ($(CROSS_COMPILE),)
+ ifeq ($(RUST_TARGET_FLAGS_$(ARCH)),)
+ $(error Unknown rust cross compilation architecture $(ARCH))
+ endif
+
+ RUST_FLAGS += --target=$(RUST_TARGET_FLAGS_$(ARCH))
+ endif
+endif
+
+# Building zlib-rs from Cargo crate sources requires a working rustc.
+ifneq ($(NO_RUST), 0)
+ NO_ZLIB_RS := 1
+endif
+
+# Prefer zlib-rs over C zlib when available, unless disabled via NO_ZLIB=1 or
+# NO_ZLIB_RS=1. Both provide the standard zlib C API (HAVE_ZLIB_SUPPORT), while
+# HAVE_ZLIB_RS_SUPPORT records that zlib-rs is the implementation in use.
+ifndef NO_ZLIB
+ ifndef NO_ZLIB_RS
+ $(call feature_check,zlib-rs)
+ ifeq ($(feature-zlib-rs), 1)
+ ZLIB_RS := 1
+ $(call feature_rust_lib,zlib-rs)
+ ZLIB_CFLAGS := $(FEATURE_CFLAGS-zlib-rs)
+ ZLIB_LIBS := $(FEATURE_LIBS-zlib-rs)
+ CFLAGS += -DHAVE_ZLIB_SUPPORT -DHAVE_ZLIB_RS_SUPPORT $(ZLIB_CFLAGS)
+ EXTLIBS += $(ZLIB_LIBS)
+ $(call detected,CONFIG_ZLIB)
+ $(call detected,CONFIG_ZLIB_RS)
+ endif
+ endif
+ ifndef ZLIB_RS
+ ifeq ($(feature-zlib), 1)
+ ZLIB_LIBS := -lz
+ CFLAGS += -DHAVE_ZLIB_SUPPORT
+ EXTLIBS += $(ZLIB_LIBS)
+ $(call detected,CONFIG_ZLIB)
+ else
+ NO_ZLIB := 1
+ endif
endif
endif
@@ -908,7 +952,7 @@ ifdef BUILD_NONDISTRO
else ifeq ($(feature-libbfd-liberty), 1)
EXTLIBS += -lbfd -lopcodes -liberty
else ifeq ($(feature-libbfd-liberty-z), 1)
- EXTLIBS += -lbfd -lopcodes -liberty -lz
+ EXTLIBS += -lbfd -lopcodes -liberty $(ZLIB_LIBS)
endif
CFLAGS += -DHAVE_LIBBFD_SUPPORT
@@ -1132,37 +1176,6 @@ ifneq ($(NO_LIBTRACEEVENT),1)
endif
endif
-ifndef NO_RUST
- $(call feature_check,rust)
- ifneq ($(feature-rust), 1)
- $(warning Rust is not found. Test workloads with rust are disabled.)
- NO_RUST := 1
- else
- NO_RUST := 0
- CFLAGS += -DHAVE_RUST_SUPPORT
- $(call detected,CONFIG_RUST_SUPPORT)
- endif
-
- ifneq ($(CROSS_COMPILE),)
- RUST_TARGET_FLAGS_arm := arm-unknown-linux-gnueabi
- RUST_TARGET_FLAGS_arm64 := aarch64-unknown-linux-gnu
- RUST_TARGET_FLAGS_loongarch := loongarch64-unknown-linux-gnu
- RUST_TARGET_FLAGS_m68k := m68k-unknown-linux-gnu
- RUST_TARGET_FLAGS_mips := mipsel-unknown-linux-gnu
- RUST_TARGET_FLAGS_powerpc := powerpc64le-unknown-linux-gnu
- RUST_TARGET_FLAGS_riscv := riscv64gc-unknown-linux-gnu
- RUST_TARGET_FLAGS_s390 := s390x-unknown-linux-gnu
- RUST_TARGET_FLAGS_x86 := x86_64-unknown-linux-gnu
- RUST_TARGET_FLAGS_x86_64 := x86_64-unknown-linux-gnu
-
- ifeq ($(RUST_TARGET_FLAGS_$(ARCH)),)
- $(error Unknown rust cross compilation architecture $(ARCH))
- endif
-
- RUST_FLAGS += --target=$(RUST_TARGET_FLAGS_$(ARCH))
- endif
-endif
-
# Among the variables below, these:
# perfexecdir
# libbpf_include_dir
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index b74b534e1153..baad492277df 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -75,6 +75,8 @@ include ../scripts/utilities.mak
#
# Define NO_ZLIB if you do not want to support compressed kernel modules
#
+# Define NO_ZLIB_RS if you do not want to use zlib-rs for zlib support
+#
# Define NO_BABELTRACE2 if you do not want babeltrace2-ctf-writer support
# for CTF data format.
#
@@ -417,6 +419,15 @@ ifdef LIBBPF_STATIC
CFLAGS += -I$(LIBBPF_OUTPUT)/include
endif
+ifneq ($(OUTPUT),)
+ LIBZ_RS_OUTPUT = $(abspath $(OUTPUT))/libz_rs
+else
+ LIBZ_RS_OUTPUT = $(CURDIR)/libz_rs
+endif
+ifdef ZLIB_RS
+ LIBZ_RS = $(filter %/libz_rs.a,$(ZLIB_LIBS))
+endif
+
ifneq ($(OUTPUT),)
LIBSUBCMD_OUTPUT = $(abspath $(OUTPUT))/libsubcmd
else
@@ -741,6 +752,11 @@ ifdef LIBBPF_STATIC
prepare: $(LIBBPF)
endif
+ifneq ($(LIBZ_RS),)
+prepare: $(LIBZ_RS)
+bpf-skel-prepare: $(LIBZ_RS)
+endif
+
$(OUTPUT)%.o: %.c prepare FORCE
$(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
@@ -808,12 +824,22 @@ $(LIBAPI)-clean:
$(LIBBPF): FORCE | $(LIBBPF_OUTPUT)
$(Q)$(MAKE) -C $(LIBBPF_DIR) FEATURES_DUMP=$(FEATURE_DUMP_EXPORT) \
O= OUTPUT=$(LIBBPF_OUTPUT)/ DESTDIR=$(LIBBPF_DESTDIR) prefix= subdir= \
- EXTRA_CFLAGS="-fPIC" $@ install_headers
+ EXTRA_CFLAGS="-fPIC $(ZLIB_CFLAGS)" $@ install_headers
$(LIBBPF)-clean:
$(call QUIET_CLEAN, libbpf)
$(Q)$(RM) -r -- $(LIBBPF_OUTPUT)
+ifneq ($(LIBZ_RS),)
+$(LIBZ_RS): | $(LIBZ_RS_OUTPUT)
+ $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.rust LIBZ_RS_OUTPUT=$(LIBZ_RS_OUTPUT)/ \
+ RUSTC="$(RUSTC)" RUST_FLAGS="$(RUST_FLAGS)" $@
+endif
+
+libz-rs-clean:
+ $(call QUIET_CLEAN, libz_rs)
+ $(Q)$(RM) -r -- $(LIBZ_RS_OUTPUT)
+
$(LIBPERF): FORCE | $(LIBPERF_OUTPUT)
$(Q)$(MAKE) -C $(LIBPERF_DIR) O=$(LIBPERF_OUTPUT) \
DESTDIR=$(LIBPERF_DESTDIR) prefix= subdir= \
@@ -1026,7 +1052,7 @@ python-clean:
$(RM) $(OUTPUT)python/perf.pyi; \
fi
-$(LIBAPI_OUTPUT) $(LIBBPF_OUTPUT) $(LIBPERF_OUTPUT) $(LIBSUBCMD_OUTPUT) $(LIBSYMBOL_OUTPUT):
+$(LIBAPI_OUTPUT) $(LIBBPF_OUTPUT) $(LIBPERF_OUTPUT) $(LIBSUBCMD_OUTPUT) $(LIBSYMBOL_OUTPUT) $(LIBZ_RS_OUTPUT):
$(Q)$(MKDIR) -p $@
bpf-skel-clean:
@@ -1050,7 +1076,7 @@ else # When an OUTPUT directory is present, clean up the copied pmu-events/arch
endif
clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBSYMBOL)-clean $(LIBPERF)-clean \
- arm64-sysreg-defs-clean fixdep-clean python-clean bpf-skel-clean \
+ libz-rs-clean arm64-sysreg-defs-clean fixdep-clean python-clean bpf-skel-clean \
pmu-events-clean
$(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive \
$(OUTPUT)perf-iostat $(LANG_BINDINGS)
diff --git a/tools/perf/bpf_skel.mak b/tools/perf/bpf_skel.mak
index f2559de39f96..d2ac4c4a7402 100644
--- a/tools/perf/bpf_skel.mak
+++ b/tools/perf/bpf_skel.mak
@@ -39,9 +39,15 @@ ifneq ($(WERROR),0)
CLANG_OPTIONS += -Werror
endif
+# When not cross-compiling, share the top-level $(OUTPUT)libz_rs/ directory
+# with the host bootstrap bpftool build so libz_rs.a is not compiled twice.
+ifeq ($(CROSS_COMPILE),)
+BPFTOOL_RUST_OUTPUT := RUST_OUTPUT=$(abspath $(or $(OUTPUT),.))/
+endif
+
$(BPFTOOL):
$(Q)mkdir -p $(SKEL_TOOL_TMP_OUT)
- $(Q)CFLAGS= $(MAKE) -C ../bpf/bpftool OUTPUT=$(SKEL_TOOL_TMP_OUT)/ bootstrap
+ $(Q)CFLAGS= $(MAKE) -C ../bpf/bpftool OUTPUT=$(SKEL_TOOL_TMP_OUT)/ $(BPFTOOL_RUST_OUTPUT) bootstrap
# Paths to search for a kernel to generate vmlinux.h from.
VMLINUX_BTF_ELF_PATHS ?= $(if $(O),$(O)/vmlinux) \
diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c
index 1e43e097e7a7..fe1fc40561a9 100644
--- a/tools/perf/builtin-check.c
+++ b/tools/perf/builtin-check.c
@@ -59,6 +59,7 @@ struct feature_status supported_features[] = {
FEATURE_STATUS("lzma", HAVE_LZMA_SUPPORT),
FEATURE_STATUS("numa_num_possible_cpus", HAVE_LIBNUMA_SUPPORT),
FEATURE_STATUS("zlib", HAVE_ZLIB_SUPPORT),
+ FEATURE_STATUS("zlib-rs", HAVE_ZLIB_RS_SUPPORT),
FEATURE_STATUS("zstd", HAVE_ZSTD_SUPPORT),
FEATURE_STATUS("rust", HAVE_RUST_SUPPORT),
diff --git a/tools/perf/scripts/install-build-deps.sh b/tools/perf/scripts/install-build-deps.sh
index 3e53c7bf0f85..605dd9073589 100755
--- a/tools/perf/scripts/install-build-deps.sh
+++ b/tools/perf/scripts/install-build-deps.sh
@@ -146,6 +146,9 @@ fedora_pkg_for() {
zlib)
echo "zlib-devel"
;;
+ zlib-rs)
+ echo "rust-libz-rs-sys-devel"
+ ;;
lzma)
echo "xz-devel"
;;
@@ -305,6 +308,9 @@ debian_pkg_for() {
zlib)
echo "zlib1g-dev"
;;
+ zlib-rs)
+ echo "librust-libz-rs-sys-dev"
+ ;;
lzma)
echo "liblzma-dev"
;;
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 7524de522802..96567d9ea2a4 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -99,6 +99,8 @@ make_no_babeltrace2 := NO_BABELTRACE2=1
make_with_coresight := CORESIGHT=1
make_no_sdt := NO_SDT=1
make_no_libpfm4 := NO_LIBPFM4=1
+make_no_zlib := NO_ZLIB=1
+make_no_zlib_rs := NO_ZLIB_RS=1
make_with_gtk4 := GTK4=1
make_refcnt_check := EXTRA_CFLAGS="-DREFCNT_CHECKING=1"
make_tags := tags
@@ -193,6 +195,8 @@ run += make_no_sdt
run += make_no_babeltrace2
run += make_with_coresight
run += make_no_libpfm4
+run += make_no_zlib
+run += make_no_zlib_rs
run += make_refcnt_check
run += make_help
run += make_doc
@@ -302,6 +306,11 @@ test_make_install_pdf_O := $(test_ok)
test_make_libbpf_dynamic := ldd $(PERF_O)/perf | grep -q libbpf
test_make_libbpf_dynamic_O := ldd $$TMP_O/perf | grep -q libbpf
+test_make_no_zlib := test -x $(PERF_O)/perf && ! $(PERF_O)/perf check -q feature zlib && ! $(PERF_O)/perf check -q feature zlib-rs
+test_make_no_zlib_O := test -x $$TMP_O/perf && ! $$TMP_O/perf check -q feature zlib && ! $$TMP_O/perf check -q feature zlib-rs
+test_make_no_zlib_rs := test -x $(PERF_O)/perf && ! $(PERF_O)/perf check -q feature zlib-rs
+test_make_no_zlib_rs_O := test -x $$TMP_O/perf && ! $$TMP_O/perf check -q feature zlib-rs
+
# Feature tests are allowed to fail, so a broken C++ compiler command line
# doesn't fail the build, it just quietly turns off everything that needs a
# C++ compiler. Check a feature that does, otherwise these tests would pass
--
2.56.0.313.g2479322e68-goog
next prev parent reply other threads:[~2026-10-29 16:30 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 16:29 [RFC PATCH v1 0/3] tools: Add Rust library build infrastructure and prefer zlib-rs Ian Rogers
2026-10-29 16:29 ` [RFC PATCH v1 1/3] tools build: Add Rust library build infrastructure and zlib-rs feature test Ian Rogers
2026-10-29 16:57 ` sashiko-bot
2026-10-29 16:29 ` Ian Rogers [this message]
2026-10-29 16:50 ` [RFC PATCH v1 2/3] perf build: Prefer zlib-rs over zlib when available sashiko-bot
2026-10-29 16:29 ` [RFC PATCH v1 3/3] bpftool: " Ian Rogers
2026-10-29 17:06 ` sashiko-bot
2026-10-29 17:32 ` [RFC PATCH v1 0/3] tools: Add Rust library build infrastructure and prefer zlib-rs Miguel Ojeda
2026-10-29 18:23 ` Ian Rogers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261029162958.3224280-3-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=justinstitt@google.com \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=mingo@redhat.com \
--cc=morbo@google.com \
--cc=namhyung@kernel.org \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=nsc@kernel.org \
--cc=ojeda@kernel.org \
--cc=peterz@infradead.org \
--cc=qmo@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.