From c60c58f877c7eda09baf81e1794883561181af07 Mon Sep 17 00:00:00 2001 From: Alessandro Di Nepi Date: Fri, 10 Jul 2026 11:06:23 +0200 Subject: [PATCH 1/4] Honor $(STRIP) in install-strip for cross-compilation The install-strip target hard-coded `install -s`, which strips via the install program using the build host's strip and ignores the STRIP variable. When cross-compiling this runs the host strip against a target binary and fails. Pass --strip-program=$(or $(STRIP),strip) so the target strip is used when STRIP is set (as cross toolchains and build systems provide), falling back to plain `strip` for native builds. A plain `make install` is unaffected. --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 5216fb2f7..d8c0928d4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -109,7 +109,7 @@ install-ssl-daemon: stunnel-rsyncd.conf install-all: install install-ssl-daemon install-strip: - $(MAKE) INSTALL_STRIP='-s' install + $(MAKE) INSTALL_STRIP='-s --strip-program=$(or $(STRIP),strip)' install .PHONY: uninstall uninstall: From 882b59a951f9322391e2d238621d48ba8c501601 Mon Sep 17 00:00:00 2001 From: Alessandro Di Nepi Date: Mon, 13 Jul 2026 11:26:50 +0300 Subject: [PATCH 2/4] Make install-strip portable (address review) - Detect the target strip via AC_CHECK_TOOL([STRIP],[strip],[strip]) in configure.ac (picks up the cross-prefixed strip when cross-compiling, defaults to plain strip otherwise) and substitute @STRIP@ in Makefile.in. - Rewrite install-strip to run a normal install then $(STRIP) on the installed rsync binary, dropping the GNU Make $(or ...) and the GNU install --strip-program extension that broke with install-sh/BSD install. Co-Authored-By: Claude Opus 4.8 (1M context) --- Makefile.in | 4 +++- configure.ac | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index d8c0928d4..7896f5dae 100644 --- a/Makefile.in +++ b/Makefile.in @@ -21,6 +21,7 @@ LIBOBJDIR=lib/ INSTALLCMD=@INSTALL@ INSTALLMAN=@INSTALL@ +STRIP=@STRIP@ srcdir=@srcdir@ MKDIR_P=@MKDIR_P@ @@ -109,7 +110,8 @@ install-ssl-daemon: stunnel-rsyncd.conf install-all: install install-ssl-daemon install-strip: - $(MAKE) INSTALL_STRIP='-s --strip-program=$(or $(STRIP),strip)' install + $(MAKE) install + $(STRIP) $(DESTDIR)$(bindir)/rsync$(EXEEXT) .PHONY: uninstall uninstall: diff --git a/configure.ac b/configure.ac index cda60405b..b16734a72 100644 --- a/configure.ac +++ b/configure.ac @@ -59,6 +59,7 @@ AC_PROG_CXX AC_PROG_AWK AC_PROG_EGREP AC_PROG_INSTALL +AC_CHECK_TOOL([STRIP], [strip], [strip]) AC_PROG_MKDIR_P AC_SUBST(SHELL) AC_PATH_PROG([PERL], [perl]) From 022b8a2ccebef865d814e1891f3c5706a89e8c55 Mon Sep 17 00:00:00 2001 From: Zen Dodd Date: Thu, 16 Jul 2026 22:42:23 +1000 Subject: [PATCH 3/4] testsuite: test install-strip tool selection --- testsuite/install-strip_test.py | 55 +++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 testsuite/install-strip_test.py diff --git a/testsuite/install-strip_test.py b/testsuite/install-strip_test.py new file mode 100644 index 000000000..4e9486b55 --- /dev/null +++ b/testsuite/install-strip_test.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 + +import filecmp +import os +import shlex +import subprocess + +from rsyncfns import SCRATCHDIR, TOOLDIR, test_fail + + +make_vars = {} +for line in (TOOLDIR / 'Makefile').read_text().splitlines(): + name, separator, value = line.partition('=') + if separator and name in ('EXEEXT', 'STRIP'): + make_vars[name] = value.strip() + +if not make_vars.get('STRIP'): + test_fail('configured Makefile does not define STRIP') + +rsync = TOOLDIR / f"rsync{make_vars.get('EXEEXT', '')}" +if not rsync.is_file(): + test_fail('cannot find the built rsync binary') + +make = shlex.split(os.environ.get('MAKE', 'make')) +tools = SCRATCHDIR / 'tools' +tools.mkdir() + +for strip_name in ('strip', 'aarch64-linux-gnu-strip'): + destdir = SCRATCHDIR / 'roots' / strip_name + strip_log = SCRATCHDIR / f'{strip_name}.log' + strip = tools / strip_name + strip.write_text('#!/bin/sh\nprintf \'%s\\n\' "$@" >"$STRIP_LOG"\n') + strip.chmod(0o755) + + env = os.environ.copy() + env['STRIP_LOG'] = str(strip_log) + proc = subprocess.run( + [*make, f'DESTDIR={destdir}', 'bindir=/bin', 'mandir=/share/man', + 'with_rrsync=no', 'INSTALL_STRIP=', f'STRIP={strip}', + 'install-strip'], + cwd=TOOLDIR, env=env, capture_output=True, text=True, + ) + if proc.returncode != 0: + test_fail(f'install-strip failed with {strip_name}:\n' + f'{proc.stdout}{proc.stderr}') + + installed = destdir / 'bin' / rsync.name + if not installed.is_file(): + test_fail(f'install-strip did not install {installed}') + if not strip_log.is_file(): + test_fail(f'install-strip did not call {strip_name}') + if strip_log.read_text().splitlines() != [str(installed)]: + test_fail(f'{strip_name} was not called with {installed}') + if not filecmp.cmp(rsync, installed, shallow=False): + test_fail(f'{strip_name} unexpectedly changed the installed test binary') From 4f4562ea3bdc0d55555403fc0896b551df41072b Mon Sep 17 00:00:00 2001 From: Zen Dodd Date: Thu, 16 Jul 2026 23:00:19 +1000 Subject: [PATCH 4/4] compat: fix for Solaris/OpenBSD Signed-off-by: Zen Dodd --- Makefile.in | 3 +- testsuite/install-strip_test.py | 62 +++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/Makefile.in b/Makefile.in index 7896f5dae..4af94d42d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -109,8 +109,7 @@ install-ssl-daemon: stunnel-rsyncd.conf install-all: install install-ssl-daemon -install-strip: - $(MAKE) install +install-strip: install $(STRIP) $(DESTDIR)$(bindir)/rsync$(EXEEXT) .PHONY: uninstall diff --git a/testsuite/install-strip_test.py b/testsuite/install-strip_test.py index 4e9486b55..95401d87b 100644 --- a/testsuite/install-strip_test.py +++ b/testsuite/install-strip_test.py @@ -2,25 +2,69 @@ import filecmp import os +import re import shlex +import shutil import subprocess -from rsyncfns import SCRATCHDIR, TOOLDIR, test_fail +from rsyncfns import SCRATCHDIR, SRCDIR, TOOLDIR, test_fail make_vars = {} for line in (TOOLDIR / 'Makefile').read_text().splitlines(): name, separator, value = line.partition('=') - if separator and name in ('EXEEXT', 'STRIP'): + if separator and name in ('prefix', 'exec_prefix', 'bindir', + 'EXEEXT', 'STRIP'): make_vars[name] = value.strip() if not make_vars.get('STRIP'): test_fail('configured Makefile does not define STRIP') -rsync = TOOLDIR / f"rsync{make_vars.get('EXEEXT', '')}" -if not rsync.is_file(): +source_rsync = TOOLDIR / f"rsync{make_vars.get('EXEEXT', '')}" +if not source_rsync.is_file(): test_fail('cannot find the built rsync binary') +builddir = SCRATCHDIR / 'build' +builddir.mkdir() +makefile_text = (TOOLDIR / 'Makefile').read_text() +if 'install: all\n' not in makefile_text: + test_fail('cannot isolate the install target from the shared build') +if 'Makefile: Makefile.in config.status configure.sh config.h.in\n' not in makefile_text: + test_fail('cannot isolate Makefile regeneration from the shared build') +(builddir / 'Makefile').write_text( + makefile_text + .replace('install: all\n', 'install:\n', 1) + .replace('Makefile: Makefile.in config.status configure.sh config.h.in\n', + 'Makefile:\n', 1) +) + +for name in (source_rsync.name, 'rsync-ssl', 'rrsync', 'rsync.1', + 'rsync-ssl.1', 'rsyncd.conf.5', 'rrsync.1'): + source = TOOLDIR / name + if not source.is_file(): + source = SRCDIR / name + if source.is_file(): + shutil.copy2(source, builddir / name) + + +def expand_make_value(value): + for _ in range(10): + expanded = re.sub( + r'\$\{([^}]+)\}|\$\(([^)]+)\)', + lambda match: make_vars.get(match.group(1) or match.group(2), + match.group(0)), + value, + ) + if expanded == value: + return expanded + value = expanded + test_fail(f'cannot expand Makefile value {value!r}') + + +bindir = expand_make_value(make_vars.get('bindir', '')) +if not bindir or '$' in bindir: + test_fail(f'cannot determine configured bindir from {bindir!r}') + make = shlex.split(os.environ.get('MAKE', 'make')) tools = SCRATCHDIR / 'tools' tools.mkdir() @@ -35,21 +79,19 @@ env = os.environ.copy() env['STRIP_LOG'] = str(strip_log) proc = subprocess.run( - [*make, f'DESTDIR={destdir}', 'bindir=/bin', 'mandir=/share/man', - 'with_rrsync=no', 'INSTALL_STRIP=', f'STRIP={strip}', - 'install-strip'], - cwd=TOOLDIR, env=env, capture_output=True, text=True, + [*make, f'DESTDIR={destdir}', f'STRIP={strip}', 'install-strip'], + cwd=builddir, env=env, capture_output=True, text=True, ) if proc.returncode != 0: test_fail(f'install-strip failed with {strip_name}:\n' f'{proc.stdout}{proc.stderr}') - installed = destdir / 'bin' / rsync.name + installed = destdir / bindir.lstrip('/') / source_rsync.name if not installed.is_file(): test_fail(f'install-strip did not install {installed}') if not strip_log.is_file(): test_fail(f'install-strip did not call {strip_name}') if strip_log.read_text().splitlines() != [str(installed)]: test_fail(f'{strip_name} was not called with {installed}') - if not filecmp.cmp(rsync, installed, shallow=False): + if not filecmp.cmp(source_rsync, installed, shallow=False): test_fail(f'{strip_name} unexpectedly changed the installed test binary')