On Tue, Nov 18, 2025, 17:02 Pádraig Brady <[email protected]> wrote:
> * Makefile.am: Use ln rather than $(LN_S) for hardlinks.
> * configure.ac: Accept --enable-single-binary=hardlinks.
> * man/local.mk: In hardlink mode, explicitly add the
> hardlink creation rule to mandeps. Given the automake
> generated dependency chain, this ensures that the hardlinks
> are created _after_ the multicall binary, with `make all`
> or `make check` etc.
> * src/local.mk: Define the new src/coreutils_hardlinks rule,
> and only depend on src/coreutils_{symlinks,shebangs} if
> in those modes, so that hardlinks are created _after_
> the multicall binary, and other link types before.
> * NEWS: Mention the new feature.
> Addresses https://github.com/coreutils/coreutils/issues/129
> ---
> Makefile.am | 3 +++
> NEWS | 5 +++++
> configure.ac | 14 ++++++++------
> man/local.mk | 4 ++++
> src/local.mk | 16 ++++++++++++++--
> 5 files changed, 34 insertions(+), 8 deletions(-)
>
> diff --git a/Makefile.am b/Makefile.am
> index 71f093683..83d8b3c11 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -193,6 +193,9 @@ install-exec-hook:
> $(bindir)/$$ctrans$(EXEEXT) $$p \
> >$(DESTDIR)$(bindir)/$$ptrans$(EXEEXT) || exit $$?; \
> chmod a+x,a-w $(DESTDIR)$(bindir)/$$ptrans$(EXEEXT) || exit
> $$?;\
> + elif test "x$(single_binary_install_type)" = xhardlinks; then \
> + ln $(DESTDIR)$(bindir)/$$ctrans$(EXEEXT) \
> + $(DESTDIR)$(bindir)/$$ptrans$(EXEEXT) || exit $$?; \
> else \
> $(LN_S) -s $$ctrans$(EXEEXT) \
> $(DESTDIR)$(bindir)/$$ptrans$(EXEEXT) || exit $$?; \
> diff --git a/NEWS b/NEWS
> index d3909147a..fb8f540bb 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -14,6 +14,11 @@ GNU coreutils NEWS
> -*- outline -*-
>
> ** New Features
>
> + configure accepts a new --enable-single-binary=hardlinks parameter to
> build
> + the selected programs hard linked to a multi-call binary called
> "coreutils".
> + This augments the existing "symlinks" and "shebangs" modes already
> + supported by the --enable-single-binary option.
> +
> 'tail' now accepts the --debug option, which is currently used to
> detail the --follow implementation being used.
>
> diff --git a/configure.ac b/configure.ac
> index 5e99ef386..ebd927aa1 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -105,16 +105,16 @@ AC_DEFUN([gl_GCC_VERSION_IFELSE],
> )
>
> AC_ARG_ENABLE([single-binary],
> - [AS_HELP_STRING([--enable-single-binary=[shebangs|symlinks]],
> + [AS_HELP_STRING([--enable-single-binary=[shebangs|symlinks|hardlinks]],
> [Compile all the tools in a single binary, reducing the overall size.
> - When compiled this way, shebangs (default when enabled) or symlinks
> are
> - installed for each tool that points to the single binary.])],
> + When compiled this way, shebangs (default when enabled), symlinks,
> or
> + hardlinks are installed for each tool, which point to a single
> binary])],
> [gl_single_binary=no ;
> case $enableval in
> yes) gl_single_binary=shebangs ;;
> - no|shebangs|symlinks) gl_single_binary=$enableval ;;
> + no|shebangs|symlinks|hardlinks) gl_single_binary=$enableval ;;
> *) AC_MSG_ERROR([bad value $enableval for single-binary option.
> - Options are: symlinks, shebangs, no.]) ;;
> + Options are: hardlinks, symlinks, shebangs,
> no.]) ;;
> esac],
> [gl_single_binary=no]
> )
> @@ -126,13 +126,15 @@ AC_ARG_ENABLE([single-binary-exceptions],
> [gl_single_binary_exceptions=$enableval],
> [gl_single_binary_exceptions=]
> )
> -if test "$gl_single_binary" = 'symlinks'; then
> +if test "$gl_single_binary" = 'symlinks' ||
> + test "$gl_single_binary" = 'hardlinks'; then
> if ! test "`echo ls | sed \"$program_transform_name\"`" = 'ls'; then
> AC_MSG_ERROR([program name transformations are not currently supported
> with --enable-single-binary=symlinks.])
>
s/symlinks/$gl_single_binary/ (to make the error match the selected option)?
fi
> fi
> AM_CONDITIONAL([SINGLE_BINARY], [test "$gl_single_binary" != no])
> +AM_CONDITIONAL([SINGLE_BINARY_HARD], [test "$gl_single_binary" ==
> hardlinks])
>
> AC_ARG_ENABLE([bold-man-page-references],
> [AS_HELP_STRING([--disable-bold-man-page-references],
> diff --git a/man/local.mk b/man/local.mk
> index 9759eabce..ae9dfeb9c 100644
> --- a/man/local.mk
> +++ b/man/local.mk
> @@ -61,7 +61,11 @@ mandeps += $(top_srcdir)/src/system.h
> $(ALL_MANS): $(mandeps)
>
> if SINGLE_BINARY
> +if SINGLE_BINARY_HARD
> +mandeps += src/coreutils_hardlinks
> +else
> mandeps += src/coreutils$(EXEEXT)
> +endif
> else
> # Most prog.1 man pages depend on src/prog. List the exceptions:
> man/install.1: src/ginstall$(EXEEXT)
> diff --git a/src/local.mk b/src/local.mk
> index d1f1b9462..875879345 100644
> --- a/src/local.mk
> +++ b/src/local.mk
> @@ -529,11 +529,23 @@ EXTRA_src_coreutils_DEPENDENCIES =
> $(single_binary_deps)
>
> include $(top_srcdir)/src/single-binary.mk
>
> -# Creates symlinks or shebangs to the installed programs when building
> -# coreutils single binary.
> +# Creates symlinks, or shebangs to the installed programs
> +# _before_ building coreutils single binary.
> +if !SINGLE_BINARY_HARD
> EXTRA_src_coreutils_DEPENDENCIES +=
> src/coreutils_$(single_binary_install_type)
> +endif
> endif SINGLE_BINARY
>
> +# Creates hardlinks _after_ building the coreutils single binary.
> +CLEANFILES += src/coreutils_hardlinks
> +src/coreutils_hardlinks: src/coreutils$(EXEEXT)
> + $(AM_V_GEN)touch $@
> + $(AM_V_at)for i in x $(single_binary_progs); do \
> + test $$i = x && continue; \
> + rm -f src/$$i$(EXEEXT) || exit $$?; \
> + ln src/coreutils$(EXEEXT) src/$$i$(EXEEXT) || exit $$?; \
> + done
> +
> CLEANFILES += src/coreutils_symlinks
> src/coreutils_symlinks: Makefile
> $(AM_V_GEN)touch $@
> --
> 2.51.1
>
>
>