-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
build: support building all tools in a single binary
Add the --enable-single-binary option to the configure file. When enabled, this option builds a single binary file containing the selected tools. Which tool gets executed depends on the value of argv[0] which can be set implicitly through symlinks to the single program. This setup reduces significantly the size of a complete coreutils install, since code from lib/libcoreutils.a is not duplicated in every one of the more than 100 binaries. Runtime overhead is increased due to more dynamic libraries being loaded, and extra initialization being performed for all utils. Also initially a larger binary is loaded from storage, though this is usually alleviated due to caching and lazy mmaping of unused blocks, and in fact the single binary should have better caching characteristics. Comparing the size of the individual versus single binary on x86_64: $ cd src $ size coreutils $ size -t $(../build-aux/gen-lists-of-programs.sh --list-progs | grep -Ev '(coreutils|libstdbuf)') | tail -n1 text data bss dec hex filename 1097416 5388 88432 1191236 122d44 src/coreutils 4901010 124964 163768 5189742 4f306e (TOTALS) Storage requirements are reduced similarly: $ cd src $ du -h coreutils $ du -ch $(../build-aux/gen-lists-of-programs.sh --list-progs | grep -Ev '(coreutils|libstdbuf)') | tail -n1 1.2M coreutils 5.3M total When installing, the makefile will create either symlinks or shebangs based on the --enable-single-binary setting, for each configured tool. In this way, all the tools are still callable individually, but they are all implemented by the same "coreutils" binary installed on the same directory. * .gitignore: Add new generated files. * Makefile.am: New rules to generate build-aux/gen-single-binary.sh and install symlinks. * NEWS: Mention the new feature. * README: Add "coreutils" to the list of utils. * bootstrap.conf: Regenerate src/single-binary.mk * build-aux/gen-lists-of-programs.sh: New --list-progs option. * build-aux/gen-single-binary.sh: Regenerate * configure.ac: New --enable-single-binary option and other variables. Disallow --enable-single-binary=symlinks with --program-prefix et. al. * man/coreutils.x: Manpage hook. * man/local.mk: Add manpage hook and fix dependencies. * src/coreutils.c: Multicall implementation. * src/local.mk: New rules for the single binary option. * tests/local.mk: Add $single_binary_progs to support require_built_() from init.cfg * tests/misc/env.sh: Avoid the use of symlink to echo. * tests/misc/help-version.sh: Add exception for coreutils. * tests/install/basic-1.sh: Really avoid using ginstall strip functionality if there is an issue with the independent strip command. * src/kill.c: Changes to call exit() in main. * src/readlink.c: Likewise. * src/shuf.c: Likewise. * src/timeout.c: Likewise. * src/truncate.c: Likewise.
- Loading branch information
Showing
29 changed files
with
744 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
#!/bin/sh | ||
|
||
# Generate the list of rules for the single-binary option based on all the other | ||
# binaries found in src/local.mk. | ||
# | ||
# We need to duplicate the specific rules to build each program into a new | ||
# static library target. We can't reuse the existing target since we need to | ||
# create a .a file instead of linking the program. We can't do this at | ||
# ./configure since the file names need to be available when automake runs | ||
# to let it generate all the required rules in Makefile.in. The configure | ||
# step will select which ones will be used to build, but they need to be | ||
# generated beforehand. | ||
# | ||
# Instead of maintaining a duplicated list of rules, we generate the | ||
# single-binary required rules based on the normal configuration found on | ||
# src/local.mk with this script. | ||
|
||
if test "x$1" = "x"; then | ||
echo "Usage: $0 path/to/src/local.mk" >&2 | ||
exit 1 | ||
fi | ||
|
||
set -e | ||
|
||
LOCAL_MK=$1 | ||
GEN_LISTS_OF_PROGRAMS="`dirname "$0"`/gen-lists-of-programs.sh" | ||
|
||
ALL_PROGRAMS=$($GEN_LISTS_OF_PROGRAMS --list-progs \ | ||
| grep -v -F -e coreutils -e libstdbuf.so \ | ||
| tr '[' '_') | ||
|
||
# Compute default SOURCES. automake will assume the source file for the | ||
# src_${cmd} target to be src/${cmd}.c, but we will add rules to generate | ||
# the lib src_libsinglebin_${cmd}_a which won't match the autogenerated source | ||
# file. This loop will initialize the default source file and will be reset | ||
# later if needed. | ||
for cmd in $ALL_PROGRAMS; do | ||
eval "src_${cmd}_SOURCES=src/${cmd}.c" | ||
done | ||
|
||
# Load actual values from src/local.mk. This will read all the variables from | ||
# the local.mk matching the src_${cmd}_... case. | ||
while read l; do | ||
if echo "$l" | grep -E '^src_\w+ +\+?=' > /dev/null; then | ||
var=$(echo $l | cut -f 1 -d ' ') | ||
value=$(echo $l | cut -f 2- -d =) | ||
if [ "$value" != " \$(LDADD)" ]; then | ||
oldvalue="" | ||
if echo $l | grep -F '+=' >/dev/null; then | ||
eval "oldvalue=\${$var}" | ||
fi | ||
eval "$var='$oldvalue "${value//\'/\'\"\'\"\'}"'" | ||
fi | ||
fi | ||
done < $LOCAL_MK | ||
|
||
me=`echo "$0" | sed 's,.*/,,'` | ||
echo "## Automatically generated by $me. DO NOT EDIT BY HAND!" | ||
|
||
# Override the sources for dir and vdir. We use a smaller version of dir and | ||
# vdir that relies on the ls main. | ||
src_dir_SOURCES="src/coreutils-dir.c" | ||
src_dir_LDADD+=" src/libsinglebin_ls.a" | ||
echo src_libsinglebin_dir_a_DEPENDENCIES = src/libsinglebin_ls.a | ||
src_vdir_SOURCES="src/coreutils-vdir.c" | ||
src_vdir_LDADD+=" src/libsinglebin_ls.a" | ||
echo src_libsinglebin_vdir_a_DEPENDENCIES = src/libsinglebin_ls.a | ||
|
||
# Override the sources for arch likewise, using the main from uname. | ||
src_arch_SOURCES="src/coreutils-arch.c" | ||
src_arch_LDADD+=" src/libsinglebin_uname.a" | ||
echo src_libsinglebin_arch_a_DEPENDENCIES = src/libsinglebin_uname.a | ||
|
||
for cmd in $ALL_PROGRAMS; do | ||
echo "# Command $cmd" | ||
echo noinst_LIBRARIES += src/libsinglebin_${cmd}.a | ||
base="src_libsinglebin_${cmd}_a" | ||
# SOURCES | ||
var=src_${cmd}_SOURCES | ||
eval "value=\$$var" | ||
echo "${base}_SOURCES = $value" | ||
|
||
# LDADD | ||
var=src_${cmd}_LDADD | ||
eval "value=\$$var" | ||
if [ "x$value" != "x" ]; then | ||
echo "${base}_ldadd = $value" | ||
fi | ||
|
||
# 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**) " \ | ||
"ATTRIBUTE_NORETURN; int _single_binary_main_${cmd}\" " \ | ||
"-Dusage=_usage_${cmd} \$(src_coreutils_CFLAGS)" | ||
var=src_${cmd}_CFLAGS | ||
eval "value=\$$var" | ||
if [ "x$value" != "x" ]; then | ||
echo "${base}_CFLAGS += $value" | ||
fi | ||
|
||
# CPPFLAGS | ||
var=src_${cmd}_CPPFLAGS | ||
eval "value=\$$var" | ||
if [ "x$value" != "x" ]; then | ||
echo "${base}_CPPFLAGS = $value" | ||
fi | ||
done | ||
|
||
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.