mirror of
https://github.com/coreutils/coreutils.git
synced 2026-10-28 09:44:34 +08:00
build: reduce size of multi-call binary by reusing test logic
Map the '[' command to which selects appropriate behavior at runtime,
rather than separate binaries for each closely related utility.
$ size src/coreutils-prev
text data bss dec hex filename
1485188 7348 2191968 3684504 383898 src/coreutils-prev
$ size src/coreutils
text data bss dec hex filename
1476092 7348 2191936 3675376 3814f0 src/coreutils
* src/local.mk (noinst_HEADERS): Add src/test.h.
(src___SOURCES): Remove src/lbracket.c. Add src/test.c and
src/test-lbracket.c.
(src_test_SOURCES): New variable.
(src/coreutils.h): Adjust the function name to be
single_binary_main_lbracket instead of single_binary_main__.
* build-aux/gen-single-binary.sh: Likewise. Map '[' to 'test'.
(override_single): Adjust the file name to be coreutils-lbracket.c
instead of coreutils-_.c.
* src/lbracket.c: Remove file.
* cfg.mk (_src): Don't match src/lbracket.c in the regular
expression. Match src/test-lbracket.c and src/test-test.c.
* src/coreutils-lbracket.c: New file.
* src/test-lbracket.c: Likewise.
* src/test-test.c: Likewise.
* src/test.h: Likewise.
* src/test.c: Include test.h.
(LBRACKET): Remove macro.
(PROGRAM_NAME): Use the variable TEST_MODE to determine the program
name.
(main): Use the variable TEST_MODE instead of the LBRACKET macro to
implement behavior specific to '['.
* NEWS: Mention the improvement.
This commit is contained in:
1 parent
8bc9a81246
commit
664b8663dd
10 files changed
+83
-22
No files matched your search
@@ -79,6 +79,10 @@ GNU coreutils NEWS -*- outline -*-
|
||||
|
||||
** Build-related
|
||||
|
||||
The multi-call binary built with configure --enable-single-binary
|
||||
in size by around 9KB through the more efficient reuse of the 'test' utility
|
||||
by '['.
|
||||
|
||||
configure no longer accepts the --with-linux-crypto option, which allowed
|
||||
cksum, md5sum, and sha*sum to use the Linux AF_ALG API. This API will be
|
||||
deprecated in Linux 7.2 and is less performant than OpenSSL.
|
||||
|
||||
@@ -62,12 +62,20 @@ echo "## Automatically generated by $me. DO NOT EDIT BY HAND!"
|
||||
override_single() {
|
||||
from="$1"; to="$2";
|
||||
|
||||
eval "src_${from}_SOURCES='src/coreutils-${from}.c'"
|
||||
# Use coreutils-lbracket.c instead of coreutils-_.c.
|
||||
if test "$from" = _; then
|
||||
src_name=lbracket
|
||||
else
|
||||
src_name="$from";
|
||||
fi
|
||||
eval "src_${from}_SOURCES='src/coreutils-${src_name}.c'"
|
||||
eval "src_from_LDADD=\$src_${from}_LDADD"
|
||||
eval "src_${from}_LDADD='$src_from_LDADD src/libsinglebin_${to}.a'"
|
||||
eval "src_libsinglebin_${from}_a_DEPENDENCIES='src/libsinglebin_${to}.a'"
|
||||
echo "src_libsinglebin_${from}_a_DEPENDENCIES = src/libsinglebin_${to}.a"
|
||||
}
|
||||
# This is for the '[' program. Automake transliterates '[' and '/' to '_'.
|
||||
override_single _ test
|
||||
override_single dir ls
|
||||
override_single vdir ls
|
||||
override_single arch uname
|
||||
@@ -104,10 +112,16 @@ for cmd in $ALL_PROGRAMS; do
|
||||
|
||||
# CFLAGS
|
||||
# Hack any other program defining a main() replacing its main by
|
||||
# single_binary_main_$PROGRAM_NAME.
|
||||
echo "${base}_CFLAGS = \"-Dmain=single_binary_main_${cmd} (int, char **);" \
|
||||
" int single_binary_main_${cmd}\" " \
|
||||
"-Dusage=_usage_${cmd} \$(src_coreutils_CFLAGS)"
|
||||
# single_binary_main_$PROGRAM_NAME. Use single_binary_main_lbracket
|
||||
# instead of single_binary_main__.
|
||||
if test "$cmd" = _; then
|
||||
fn=lbracket
|
||||
else
|
||||
fn="$cmd"
|
||||
fi
|
||||
echo "${base}_CFLAGS = \"-Dmain=single_binary_main_${fn} (int, char **);" \
|
||||
" int single_binary_main_${fn}\" " \
|
||||
"-Dusage=_usage_${fn} \$(src_coreutils_CFLAGS)"
|
||||
var=src_${cmd}_CFLAGS
|
||||
eval "value=\$$var"
|
||||
if [ "x$value" != "x" ]; then
|
||||
|
||||
@@ -929,8 +929,9 @@ _x_system_c := (libstdbuf|make-prime-list)\.c
|
||||
exclude_file_name_regexp--sc_system_h_headers = \
|
||||
^src/($(_x_system_h)|$(_x_system_c))$$
|
||||
|
||||
_src := (false|lbracket|chown-(chgrp|chown)
|
||||
_src := $(_src)|ls-(dir|ls|vdir)|make-prime-list|tac-pipe|uname-(arch|uname))
|
||||
_src := (false|chown-(chgrp|chown)
|
||||
_src := $(_src)|ls-(dir|ls|vdir)|make-prime-list|tac-pipe|test-(lbracket|test)
|
||||
_src := $(_src)|uname-(arch|uname))
|
||||
_gl_src = (xdecto.max|cl-strtold)
|
||||
exclude_file_name_regexp--sc_require_config_h_first = \
|
||||
(^lib/buffer-lcm\.c|gl/lib/$(_gl_src)\.c|src/$(_src)\.c)$$
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/* lbracket -- wrapper to test with the right test_mode.
|
||||
Copyright (C) 2026 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
#include "system.h"
|
||||
|
||||
#include "test.h"
|
||||
/* Ensure that the main for test is declared even if the tool is not being
|
||||
built in this single-binary. */
|
||||
int single_binary_main_test (int argc, char **argv);
|
||||
int single_binary_main_lbracket (int argc, char **argv);
|
||||
|
||||
int
|
||||
single_binary_main_lbracket (int argc, char **argv)
|
||||
{
|
||||
test_mode = TEST_LBRACKET;
|
||||
return single_binary_main_test (argc, argv);
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
#define LBRACKET 1
|
||||
#include "test.c"
|
||||
+9
-3
@@ -66,6 +66,7 @@ noinst_HEADERS = \
|
||||
src/system.h \
|
||||
src/temp-stream.h \
|
||||
src/term-sig.h \
|
||||
src/test.h \
|
||||
src/uname.h \
|
||||
src/wc.h
|
||||
|
||||
@@ -381,7 +382,8 @@ src_ginstall_SOURCES = src/install.c src/prog-fprintf.c $(copy_sources) \
|
||||
$(selinux_sources)
|
||||
|
||||
# This is for the '[' program. Automake transliterates '[' and '/' to '_'.
|
||||
src___SOURCES = src/lbracket.c
|
||||
src___SOURCES = src/test.c src/test-lbracket.c
|
||||
src_test_SOURCES = src/test.c src/test-test.c
|
||||
|
||||
nodist_src_coreutils_SOURCES = src/coreutils.h
|
||||
src_coreutils_SOURCES = src/coreutils.c
|
||||
@@ -768,7 +770,7 @@ src/speedlist.h: src/termios.c lib/config.h src/speedgen
|
||||
# SINGLE_BINARY_PROGRAM(program_name_str, main_name)
|
||||
# once for each program list on $(single_binary_progs). Note that
|
||||
# for [ the macro invocation is:
|
||||
# SINGLE_BINARY_PROGRAM("[", _)
|
||||
# SINGLE_BINARY_PROGRAM("[", lbracket)
|
||||
DISTCLEANFILES += src/coreutils.h
|
||||
src/coreutils.h: Makefile
|
||||
$(AM_V_GEN)rm -f $@
|
||||
@@ -776,7 +778,11 @@ src/coreutils.h: Makefile
|
||||
$(AM_V_at)for prog in x $(single_binary_progs); do \
|
||||
test $$prog = x && continue; \
|
||||
prog=`basename $$prog`; \
|
||||
main=`echo $$prog | tr '[' '_'`; \
|
||||
main=`if test $$prog = '['; then \
|
||||
echo lbracket; \
|
||||
else \
|
||||
echo $$prog; \
|
||||
fi`; \
|
||||
echo "SINGLE_BINARY_PROGRAM(\"$$prog\", $$main)"; \
|
||||
done | sort > $@t
|
||||
$(AM_V_at)chmod a-w $@t
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#include "test.h"
|
||||
enum test_modes test_mode = TEST_LBRACKET;
|
||||
@@ -0,0 +1,2 @@
|
||||
#include "test.h"
|
||||
enum test_modes test_mode = TEST_TEST;
|
||||
+3
-10
@@ -26,16 +26,8 @@
|
||||
|
||||
#define TEST_STANDALONE 1
|
||||
|
||||
#ifndef LBRACKET
|
||||
# define LBRACKET 0
|
||||
#endif
|
||||
|
||||
/* The official name of this program (e.g., no 'g' prefix). */
|
||||
#if LBRACKET
|
||||
# define PROGRAM_NAME "["
|
||||
#else
|
||||
# define PROGRAM_NAME "test"
|
||||
#endif
|
||||
#define PROGRAM_NAME (test_mode == TEST_TEST ? "test" : "[")
|
||||
|
||||
#include "system.h"
|
||||
#include "assure.h"
|
||||
@@ -44,6 +36,7 @@
|
||||
#include "quote.h"
|
||||
#include "stat-time.h"
|
||||
#include "strnumcmp.h"
|
||||
#include "test.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
@@ -864,7 +857,7 @@ main (int margc, char **margv)
|
||||
|
||||
argv = margv;
|
||||
|
||||
if (LBRACKET)
|
||||
if (test_mode == TEST_LBRACKET)
|
||||
{
|
||||
/* Recognize --help or --version, but only when invoked in the
|
||||
"[" form, when the last argument is not "]". Use direct
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
enum test_modes
|
||||
{
|
||||
/* This is for the 'test' program. */
|
||||
TEST_TEST,
|
||||
|
||||
/* This is for the '[' program. */
|
||||
TEST_LBRACKET
|
||||
};
|
||||
|
||||
extern enum test_modes test_mode;
|
||||
Reference in new issue
Block a user