diff mbox

[v1,1/1] coreutils: allow selection of installed programs

Message ID 1454498088-20233-1-git-send-email-romain.izard.pro@gmail.com
State Rejected
Headers show

Commit Message

Romain Izard Feb. 3, 2016, 11:14 a.m. UTC
As the recent revisions of coreutils use a single multi-call executable,
it is not possible to reduce the installed size of coreutils by removing
the unused programs. But the list of installed programs can be passed
when configuring the package, and it is possible ensure that only
required programs are embedded into the multi-call executable.

A global configuration option selects either the default set of
programs, or a configurable set. In the latter case, each coreutil
program has its own option.

Signed-off-by: Romain Izard <romain.izard.pro@gmail.com>
---
 package/coreutils/Config.in    | 539 +++++++++++++++++++++++++++++++++++++++++
 package/coreutils/coreutils.mk |  64 ++++-
 2 files changed, 600 insertions(+), 3 deletions(-)

Comments

Thomas Petazzoni Feb. 3, 2016, 4:34 p.m. UTC | #1
Dear Romain Izard,

On Wed,  3 Feb 2016 12:14:48 +0100, Romain Izard wrote:

> +menuconfig BR2_PACKAGE_COREUTILS_SELECT
> +	bool "Override the default set of installed coreutils"
> +	depends on BR2_PACKAGE_COREUTILS
> +
> +if BR2_PACKAGE_COREUTILS_SELECT
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SQUARE_BRACKET
> +	bool "["
> +	help
> +	  check file types and compare values
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_ARCH
> +	bool "arch"
> +	help
> +	  print machine hardware name (same as uname -m)
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_BASE32
> +	bool "base32"
> +	help
> +	  base32 encode/decode data and print to standard output
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_BASE64
> +	bool "base64"
> +	help
> +	  base64 encode/decode data and print to standard output
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_BASENAME
> +	bool "basename"
> +	help
> +	  strip directory and suffix from filenames
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_CAT
> +	bool "cat"
> +	help
> +	  concatenate files and print on the standard output
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_CHCON
> +	bool "chcon"
> +	help
> +	  change file security context
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_CHGRP
> +	bool "chgrp"
> +	help
> +	  change group ownership
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_CHMOD
> +	bool "chmod"
> +	help
> +	  change file mode bits
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_CHOWN
> +	bool "chown"
> +	help
> +	  change file owner and group
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_CHROOT
> +	bool "chroot"
> +	help
> +	  run command or interactive shell with special root directory
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_CKSUM
> +	bool "cksum"
> +	help
> +	  checksum and count the bytes in a file
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_COMM
> +	bool "comm"
> +	help
> +	  compare two sorted files line by line
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_CP
> +	bool "cp"
> +	help
> +	  copy files and directories
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_CSPLIT
> +	bool "csplit"
> +	help
> +	  split a file into sections determined by context lines
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_CUT
> +	bool "cut"
> +	help
> +	  remove sections from each line of files
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_DATE
> +	bool "date"
> +	help
> +	  print or set the system date and time
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_DD
> +	bool "dd"
> +	help
> +	  convert and copy a file
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_DF
> +	bool "df"
> +	help
> +	  report file system disk space usage
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_DIR
> +	bool "dir"
> +	help
> +	  list directory contents
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_DIRCOLORS
> +	bool "dircolors"
> +	help
> +	  color setup for ls
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_DIRNAME
> +	bool "dirname"
> +	help
> +	  strip last component from file name
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_DU
> +	bool "du"
> +	help
> +	  estimate file space usage
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_ECHO
> +	bool "echo"
> +	help
> +	  display a line of text
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_ENV
> +	bool "env"
> +	help
> +	  run a program in a modified environment
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_EXPAND
> +	bool "expand"
> +	help
> +	  convert tabs to spaces
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_EXPR
> +	bool "expr"
> +	help
> +	  evaluate expressions
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_FACTOR
> +	bool "factor"
> +	help
> +	  factor numbers
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_FALSE
> +	bool "false"
> +	help
> +	  do nothing, unsuccessfully
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_FMT
> +	bool "fmt"
> +	help
> +	  simple optimal text formatter
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_FOLD
> +	bool "fold"
> +	help
> +	  wrap each input line to fit in specified width
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_GROUPS
> +	bool "groups"
> +	help
> +	  print the groups a user is in
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_HEAD
> +	bool "head"
> +	help
> +	  output the first part of files
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_HOSTID
> +	bool "hostid"
> +	help
> +	  print the numeric identifier for the current host
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_HOSTNAME
> +	bool "hostname"
> +	help
> +	  set or print the name of the current host system
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_ID
> +	bool "id"
> +	help
> +	  print real and effective user and group IDs
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_INSTALL
> +	bool "install"
> +	help
> +	  copy files and set attributes
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_JOIN
> +	bool "join"
> +	help
> +	  join lines of two files on a common field
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_KILL
> +	bool "kill"
> +	help
> +	  send signals to processes, or list signals
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_LINK
> +	bool "link"
> +	help
> +	  call the link function to create a link to a file
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_LN
> +	bool "ln"
> +	help
> +	  make links between files
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_LOGNAME
> +	bool "logname"
> +	help
> +	  print user's login name
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_LS
> +	bool "ls"
> +	help
> +	  list directory contents
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_MD5SUM
> +	bool "md5sum"
> +	help
> +	  compute and check MD5 message digest
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_MKDIR
> +	bool "mkdir"
> +	help
> +	  make directories
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_MKFIFO
> +	bool "mkfifo"
> +	help
> +	  make FIFOs (named pipes)
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_MKNOD
> +	bool "mknod"
> +	help
> +	  make block or character special files
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_MKTEMP
> +	bool "mktemp"
> +	help
> +	  create a temporary file or directory
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_MV
> +	bool "mv"
> +	help
> +	  move (rename) files
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_NICE
> +	bool "nice"
> +	help
> +	  run a program with modified scheduling priority
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_NL
> +	bool "nl"
> +	help
> +	  number lines of files
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_NOHUP
> +	bool "nohup"
> +	help
> +	  run a command immune to hangups, with output to a non-tty
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_NPROC
> +	bool "nproc"
> +	help
> +	  print the number of processing units available
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_NUMFMT
> +	bool "numfmt"
> +	help
> +	  Convert numbers from/to human-readable strings
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_OD
> +	bool "od"
> +	help
> +	  dump files in octal and other formats
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_PASTE
> +	bool "paste"
> +	help
> +	  merge lines of files
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_PATHCHK
> +	bool "pathchk"
> +	help
> +	  check whether file names are valid or portable
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_PINKY
> +	bool "pinky"
> +	help
> +	  lightweight finger
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_PR
> +	bool "pr"
> +	help
> +	  convert text files for printing
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_PRINTENV
> +	bool "printenv"
> +	help
> +	  print all or part of environment
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_PRINTF
> +	bool "printf"
> +	help
> +	  format and print data
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_PTX
> +	bool "ptx"
> +	help
> +	  produce a permuted index of file contents
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_PWD
> +	bool "pwd"
> +	help
> +	  print name of current/working directory
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_READLINK
> +	bool "readlink"
> +	help
> +	  print resolved symbolic links or canonical file names
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_REALPATH
> +	bool "realpath"
> +	help
> +	  print the resolved path
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_RM
> +	bool "rm"
> +	help
> +	  remove files or directories
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_RMDIR
> +	bool "rmdir"
> +	help
> +	  remove empty directories
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_RUNCON
> +	bool "runcon"
> +	help
> +	  run command with specified security context
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SEQ
> +	bool "seq"
> +	help
> +	  print a sequence of numbers
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SHA1SUM
> +	bool "sha1sum"
> +	help
> +	  compute and check SHA1 message digest
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SHA224SUM
> +	bool "sha224sum"
> +	help
> +	  compute and check SHA224 message digest
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SHA256SUM
> +	bool "sha256sum"
> +	help
> +	  compute and check SHA256 message digest
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SHA384SUM
> +	bool "sha384sum"
> +	help
> +	  compute and check SHA384 message digest
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SHA512SUM
> +	bool "sha512sum"
> +	help
> +	  compute and check SHA512 message digest
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SHRED
> +	bool "shred"
> +	help
> +	  overwrite a file to hide its contents, and optionally delete it
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SHUF
> +	bool "shuf"
> +	help
> +	  generate random permutations
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SLEEP
> +	bool "sleep"
> +	help
> +	  delay for a specified amount of time
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SORT
> +	bool "sort"
> +	help
> +	  sort lines of text files
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SPLIT
> +	bool "split"
> +	help
> +	  split a file into pieces
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_STAT
> +	bool "stat"
> +	help
> +	  display file or file system status
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_STDBUF
> +	bool "stdbuf"
> +	depends on !BR2_STATIC_LIBS
> +	help
> +	  run command with specified buffering settings
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_STTY
> +	bool "stty"
> +	help
> +	  change and print terminal line settings
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SUM
> +	bool "sum"
> +	help
> +	  checksum and count the blocks in a file
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_SYNC
> +	bool "sync"
> +	help
> +	  Synchronize cached writes to persistent storage
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_TAC
> +	bool "tac"
> +	help
> +	  concatenate and print files in reverse
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_TAIL
> +	bool "tail"
> +	help
> +	  output the last part of files
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_TEE
> +	bool "tee"
> +	help
> +	  read from standard input and write to standard output and files
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_TEST
> +	bool "test"
> +	help
> +	  check file types and compare values
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_TIMEOUT
> +	bool "timeout"
> +	help
> +	  run a command with a time limit
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_TOUCH
> +	bool "touch"
> +	help
> +	  change file timestamps
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_TR
> +	bool "tr"
> +	help
> +	  translate or delete characters
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_TRUE
> +	bool "true"
> +	help
> +	  do nothing, successfully
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_TRUNCATE
> +	bool "truncate"
> +	help
> +	  shrink or extend the size of a file to the specified size
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_TSORT
> +	bool "tsort"
> +	help
> +	  perform topological sort
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_TTY
> +	bool "tty"
> +	help
> +	  print the file name of the terminal connected to standard input
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_UNAME
> +	bool "uname"
> +	help
> +	  print system information
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_UNEXPAND
> +	bool "unexpand"
> +	help
> +	  convert spaces to tabs
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_UNIQ
> +	bool "uniq"
> +	help
> +	  report or omit repeated lines
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_UNLINK
> +	bool "unlink"
> +	help
> +	  call the unlink function to remove the specified file
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_UPTIME
> +	bool "uptime"
> +	help
> +	  tell how long the system has been running
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_USERS
> +	bool "users"
> +	help
> +	  print the user names of users currently logged in to the current host
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_VDIR
> +	bool "vdir"
> +	help
> +	  list directory contents
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_WC
> +	bool "wc"
> +	help
> +	  print newline, word, and byte counts for each file
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_WHO
> +	bool "who"
> +	help
> +	  show who is logged on
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_WHOAMI
> +	bool "whoami"
> +	help
> +	  print effective userid
> +
> +config BR2_PACKAGE_COREUTILS_SELECT_YES
> +	bool "yes"
> +	help
> +	  output a string repeatedly until killed
> +
> +endif

This is really a loooooong list of options that will be annoying to
maintain I believe.

What about instead having a string option to list the requested
binaries? If empty, then the default programs are built and installed.
If non-empty, then only the programs listed in the string option will
be built and installed.

Best regards,

Thomas
Romain Izard Feb. 3, 2016, 5:13 p.m. UTC | #2
2016-02-03 17:34 GMT+01:00 Thomas Petazzoni
<thomas.petazzoni@free-electrons.com>:
>
> Dear Romain Izard,
>
> On Wed,  3 Feb 2016 12:14:48 +0100, Romain Izard wrote:
>
> > +menuconfig BR2_PACKAGE_COREUTILS_SELECT
> > +     bool "Override the default set of installed coreutils"
> > +     depends on BR2_PACKAGE_COREUTILS
> > +
> > +if BR2_PACKAGE_COREUTILS_SELECT
> >
> > ...
> >
> > +endif
>
> This is really a loooooong list of options that will be annoying to
> maintain I believe.
>

Is the coreutils package moving that fast ?

The list is now done, and it's not that hard to customize
the "gen-list-of-programs.sh" script from coreutils to generate
a new version, even to reproduce the few manual tweaks I used.

And adding/removing an entry from time to time does not look that annoying.
This type of list can be an issue when different development branches
touch the same file, but here I do not expect it to be an issue.

> What about instead having a string option to list the requested binaries?
> If empty, then the default programs are built and installed.  If
> non-empty, then only the programs listed in the string option will be
> built and installed.

That's what I wanted to do in the beginning.

From what I understand from the coreutils configure.ac and m4/* files,
it is not possible to start from an empty list, and then add requested
programs, at least without patching.

As coreutils is one of the longest-lived GNU projects, its autotool
configuration is so elaborate that I do not feel comfortable with
changing it.

As a bonus, as each program is documented (with the headline
from its man page in the coreutils package), the user experience
in Kconfig is quite good, whereas a comma-separated, 30-word
configuration option will be cumbersome to edit and review.

The same pattern also exists in the util-linux package, but with half
as many options.

Best regards,
Romain Izard Feb. 12, 2016, 1:48 p.m. UTC | #3
Hi Thomas,

2016-02-03 18:13 GMT+01:00 Romain Izard <romain.izard.pro@gmail.com>:
> 2016-02-03 17:34 GMT+01:00 Thomas Petazzoni
> <thomas.petazzoni@free-electrons.com>:
>>
>> On Wed,  3 Feb 2016 12:14:48 +0100, Romain Izard wrote:
>>
>> > +menuconfig BR2_PACKAGE_COREUTILS_SELECT
>> > +     bool "Override the default set of installed coreutils"
>> > +     depends on BR2_PACKAGE_COREUTILS
>> > +
>> > +if BR2_PACKAGE_COREUTILS_SELECT
>> >

[...]

>> >
>> > +endif
>>
>> This is really a loooooong list of options that will be annoying to
>> maintain I believe.
>>
>
> Is the coreutils package moving that fast ?
>
> The list is now done, and it's not that hard to customize
> the "gen-list-of-programs.sh" script from coreutils to generate
> a new version, even to reproduce the few manual tweaks I used.
>
> And adding/removing an entry from time to time does not look that annoying.
> This type of list can be an issue when different development branches
> touch the same file, but here I do not expect it to be an issue.
>
>> What about instead having a string option to list the requested binaries?
>> If empty, then the default programs are built and installed.  If
>> non-empty, then only the programs listed in the string option will be
>> built and installed.
>
> That's what I wanted to do in the beginning.
>
> From what I understand from the coreutils configure.ac and m4/* files,
> it is not possible to start from an empty list, and then add requested
> programs, at least without patching.
>
> As coreutils is one of the longest-lived GNU projects, its autotool
> configuration is so elaborate that I do not feel comfortable with
> changing it.
>
> As a bonus, as each program is documented (with the headline
> from its man page in the coreutils package), the user experience
> in Kconfig is quite good, whereas a comma-separated, 30-word
> configuration option will be cumbersome to edit and review.
>
> The same pattern also exists in the util-linux package, but with half
> as many options.

What is your point of view regarding my comments?
Is patching the coreutils mainline to implement your proposed
behavior the only way to proceed on this topic?

Best regards,
Peter Korsgaard Feb. 21, 2016, 10:09 p.m. UTC | #4
>>>>> "Romain" == Romain Izard <romain.izard.pro@gmail.com> writes:

 > As the recent revisions of coreutils use a single multi-call executable,
 > it is not possible to reduce the installed size of coreutils by removing
 > the unused programs. But the list of installed programs can be passed
 > when configuring the package, and it is possible ensure that only
 > required programs are embedded into the multi-call executable.

 > A global configuration option selects either the default set of
 > programs, or a configurable set. In the latter case, each coreutil
 > program has its own option.

 > Signed-off-by: Romain Izard <romain.izard.pro@gmail.com>

Are you really using a setup where this detailed tweaking of coreutils
is needed?

Coreutils isn't super huge:

ls -lh target/usr/bin/coreutils
-rwxr-xr-x 1 peko peko 933K Feb 21 23:01 target/usr/bin/coreutils

And if you are using coreutils instead of busybox you are probably not
very interested in saving every last byte of rootfs size anyway, so I'm
not sure we should have 500+ lines of Config.in for this.
Romain Izard Feb. 22, 2016, 8:40 a.m. UTC | #5
Hi Peter,

2016-02-21 23:09 GMT+01:00 Peter Korsgaard <peter@korsgaard.com>:
>>>>>> "Romain" == Romain Izard <romain.izard.pro@gmail.com> writes:
>
>  > As the recent revisions of coreutils use a single multi-call
>  > executable, it is not possible to reduce the installed size of
>  > coreutils by removing the unused programs. But the list of
>  > installed programs can be passed when configuring the package, and
>  > it is possible ensure that only required programs are embedded into
>  > the multi-call executable.
>
>  > A global configuration option selects either the default set of
>  > programs, or a configurable set. In the latter case, each coreutil
>  > program has its own option.
>
>  > Signed-off-by: Romain Izard <romain.izard.pro@gmail.com>
>
> Are you really using a setup where this detailed tweaking of coreutils
> is needed?
>
> Coreutils isn't super huge:
>
> ls -lh target/usr/bin/coreutils -rwxr-xr-x 1 peko peko 933K Feb 21
> 23:01 target/usr/bin/coreutils
>
> And if you are using coreutils instead of busybox you are probably not
> very interested in saving every last byte of rootfs size anyway, so
> I'm not sure we should have 500+ lines of Config.in for this.
>

My issue is that I'm updating an existing system, and the application
has expensive scripts that rely on the behaviour of coreutils regarding
some options that busybox does not have. As I cannot easily change those
scripts, my goal is to try to provide the same services with an updated
rootfs. To keep everything (including wifi, bluetooth, glib and a lot
more) in less 10 MiB as it did in the past, removing even 300 KiB from
coreutils is a step in the right direction. And I though it was a better
if is was done in a clean way, instead of the ad-hoc patches I had in
the previous generation

But if you think buildroot does not need it, I won't insist.

Best regards,
Gustavo Zacarias Feb. 24, 2016, 9:19 p.m. UTC | #6
On 22/02/16 05:40, Romain Izard wrote:

> My issue is that I'm updating an existing system, and the application
> has expensive scripts that rely on the behaviour of coreutils regarding
> some options that busybox does not have. As I cannot easily change those
> scripts, my goal is to try to provide the same services with an updated
> rootfs. To keep everything (including wifi, bluetooth, glib and a lot
> more) in less 10 MiB as it did in the past, removing even 300 KiB from
> coreutils is a step in the right direction. And I though it was a better
> if is was done in a clean way, instead of the ad-hoc patches I had in
> the previous generation
>
> But if you think buildroot does not need it, I won't insist.
>
> Best regards,

Hi Romain.
How about adding a more lightweight option to the coreutils package to 
disable the single-binary mode?
That way if all you want is 1-2 binaries you can purge the rest from a 
post-build script to save space, if you want more then single-binary 
mode makes sense to kill code duplication.
Regards.
Yann E. MORIN Feb. 24, 2016, 9:48 p.m. UTC | #7
Gustavo, Romain, All,

On 2016-02-24 18:19 -0300, Gustavo Zacarias spake thusly:
> On 22/02/16 05:40, Romain Izard wrote:
> 
> >My issue is that I'm updating an existing system, and the application
> >has expensive scripts that rely on the behaviour of coreutils regarding
> >some options that busybox does not have. As I cannot easily change those
> >scripts, my goal is to try to provide the same services with an updated
> >rootfs. To keep everything (including wifi, bluetooth, glib and a lot
> >more) in less 10 MiB as it did in the past, removing even 300 KiB from
> >coreutils is a step in the right direction. And I though it was a better
> >if is was done in a clean way, instead of the ad-hoc patches I had in
> >the previous generation
> >
> >But if you think buildroot does not need it, I won't insist.
> >
> >Best regards,
> 
> Hi Romain.
> How about adding a more lightweight option to the coreutils package to
> disable the single-binary mode?

Yes, that is a great ides, maybe a choice like:

    choice
        bool "Single-binary mode"
        default BR2_PKG_COREUTILS_SINGLE_SYMLINKS

    config BR2_PKG_COREUTILS_SINGLE_NONE
        bool "none"

    config BR2_PKG_COREUTILS_SINGLE_SYMLINKS
        bool "symlinks"

    config BR2_PKG_COREUTILS_SINGLE_SHEBANGS
        bool "shebangs"

    endchoice

And the corresponding code in the .mk file, of course.

Regards,
Yann E. MORIN.

> That way if all you want is 1-2 binaries you can purge the rest from a
> post-build script to save space, if you want more then single-binary mode
> makes sense to kill code duplication.
> Regards.
> 
> _______________________________________________
> buildroot mailing list
> buildroot@busybox.net
> http://lists.busybox.net/mailman/listinfo/buildroot
Peter Korsgaard Feb. 24, 2016, 9:58 p.m. UTC | #8
>>>>> "Yann" == Yann E MORIN <yann.morin.1998@free.fr> writes:

Hi,

>> How about adding a more lightweight option to the coreutils package to
 >> disable the single-binary mode?

 > Yes, that is a great ides, maybe a choice like:

 >     choice
 >         bool "Single-binary mode"
 >         default BR2_PKG_COREUTILS_SINGLE_SYMLINKS

 >     config BR2_PKG_COREUTILS_SINGLE_NONE
 >         bool "none"

 >     config BR2_PKG_COREUTILS_SINGLE_SYMLINKS
 >         bool "symlinks"

 >     config BR2_PKG_COREUTILS_SINGLE_SHEBANGS
 >         bool "shebangs"

 >     endchoice

 > And the corresponding code in the .mk file, of course.

Didn't we just discuss on IRC that shebangs didn't have any advantages
over symlinks? If so, I would prefer to keep things simple and only have
a choice between symlinks (default) or classical multiple binaries.
Yann E. MORIN Feb. 24, 2016, 10:19 p.m. UTC | #9
Peter, All,

On 2016-02-24 22:58 +0100, Peter Korsgaard spake thusly:
> >>>>> "Yann" == Yann E MORIN <yann.morin.1998@free.fr> writes:
> >> How about adding a more lightweight option to the coreutils package to
>  >> disable the single-binary mode?
> 
>  > Yes, that is a great ides, maybe a choice like:
>  >     choice
>  >         bool "Single-binary mode"
>  >         default BR2_PKG_COREUTILS_SINGLE_SYMLINKS
>  >     config BR2_PKG_COREUTILS_SINGLE_NONE
>  >         bool "none"
>  >     config BR2_PKG_COREUTILS_SINGLE_SYMLINKS
>  >         bool "symlinks"
>  >     config BR2_PKG_COREUTILS_SINGLE_SHEBANGS
>  >         bool "shebangs"
>  >     endchoice
>  > And the corresponding code in the .mk file, of course.
> 
> Didn't we just discuss on IRC that shebangs didn't have any advantages
> over symlinks? If so, I would prefer to keep things simple and only have
> a choice between symlinks (default) or classical multiple binaries.

Well, shebangs is the current situation, so users may rely on it (for
whatever ill reason), so we should support that.

However, I won't battle over it, as my preference would go with hardlinks
instead, but that option is not available. Meh... ;-)

Regards,
Yann E. MORIN.
Romain Izard Feb. 25, 2016, 10:54 a.m. UTC | #10
2016-02-24 23:19 GMT+01:00 Yann E. MORIN <yann.morin.1998@free.fr>:
> On 2016-02-24 22:58 +0100, Peter Korsgaard spake thusly:
>
>> Didn't we just discuss on IRC that shebangs didn't have any
>> advantages over symlinks? If so, I would prefer to keep things simple
>> and only have a choice between symlinks (default) or classical
>> multiple binaries.
>
> Well, shebangs is the current situation, so users may rely on it (for
> whatever ill reason), so we should support that.
>
> However, I won't battle over it, as my preference would go with
> hardlinks instead, but that option is not available. Meh... ;-)

The issue is that the single binary mode is much more space-efficient
than the classical mode. For my subset of 52 executables, it takes 704
KiB for the single-binary mode with shebangs, and 1.9 MiB with separate
programs (after stripping). I get a similar ratio if I compress it.

The classical mode is in fact worse than taking the coreutils package
without filtering, which takes 1.5 MiB.

Best regards,
Peter Korsgaard Feb. 25, 2016, 10:59 a.m. UTC | #11
>>>>> "Romain" == Romain Izard <romain.izard.pro@gmail.com> writes:

Hi,

>> However, I won't battle over it, as my preference would go with
 >> hardlinks instead, but that option is not available. Meh... ;-)

 > The issue is that the single binary mode is much more space-efficient
 > than the classical mode. For my subset of 52 executables, it takes 704
 > KiB for the single-binary mode with shebangs, and 1.9 MiB with separate
 > programs (after stripping). I get a similar ratio if I compress it.

 > The classical mode is in fact worse than taking the coreutils package
 > without filtering, which takes 1.5 MiB.

Crap, so that's no option then. I'll think some more about it.
Yann E. MORIN Feb. 25, 2016, 7:30 p.m. UTC | #12
Romain, Peter, All,

On 2016-02-25 11:59 +0100, Peter Korsgaard spake thusly:
> >>>>> "Romain" == Romain Izard <romain.izard.pro@gmail.com> writes:
> >> However, I won't battle over it, as my preference would go with
>  >> hardlinks instead, but that option is not available. Meh... ;-)
>  > The issue is that the single binary mode is much more space-efficient
>  > than the classical mode. For my subset of 52 executables, it takes 704
>  > KiB for the single-binary mode with shebangs, and 1.9 MiB with separate
>  > programs (after stripping). I get a similar ratio if I compress it.
> 
>  > The classical mode is in fact worse than taking the coreutils package
>  > without filtering, which takes 1.5 MiB.
> 
> Crap, so that's no option then. I'll think some more about it.

OK, so we're back to Thomas' initial proposal: provide a single string
option that the user can set to the list of programs he wants:

    config BR2_PKG_COREUTILS_PROGRAMS
        bool "install programs"
        help
          List the programs you want. Leave empty to install all.  

Regards,
Yann E. MORIN.
Arnout Vandecappelle Feb. 25, 2016, 10:31 p.m. UTC | #13
On 02/25/16 11:54, Romain Izard wrote:
> 2016-02-24 23:19 GMT+01:00 Yann E. MORIN <yann.morin.1998@free.fr>:
>> On 2016-02-24 22:58 +0100, Peter Korsgaard spake thusly:
>>
>>> Didn't we just discuss on IRC that shebangs didn't have any
>>> advantages over symlinks? If so, I would prefer to keep things simple
>>> and only have a choice between symlinks (default) or classical
>>> multiple binaries.
>>
>> Well, shebangs is the current situation, so users may rely on it (for
>> whatever ill reason), so we should support that.
>>
>> However, I won't battle over it, as my preference would go with
>> hardlinks instead, but that option is not available. Meh... ;-)
> 
> The issue is that the single binary mode is much more space-efficient
> than the classical mode. For my subset of 52 executables, it takes 704

 You really need half of the coreutils programs because they have some feature
that is not supported by busybox? Or are you trying to eliminate busybox entirely?

 If you know which extra features you need, perhaps you can just port them to
busybox? Upstream is really receptive to adding (sensible) features, as long as
they are hidden behind a config option.


 Note: unlike the others, and don't have a problem with this huge menu. But
since all the other core maintainers have voiced objections against it, I doubt
it will go in.

 Regards,
 Arnout

> KiB for the single-binary mode with shebangs, and 1.9 MiB with separate
> programs (after stripping). I get a similar ratio if I compress it.
> 
> The classical mode is in fact worse than taking the coreutils package
> without filtering, which takes 1.5 MiB.
> 
> Best regards,
>
Romain Izard Feb. 26, 2016, 8:26 a.m. UTC | #14
2016-02-25 23:31 GMT+01:00 Arnout Vandecappelle <arnout@mind.be>:
> On 02/25/16 11:54, Romain Izard wrote:
>>
>> The issue is that the single binary mode is much more space-efficient
>> than the classical mode. For my subset of 52 executables, it takes
>> 704
>
>  You really need half of the coreutils programs because they have some
>  feature that is not supported by busybox? Or are you trying to
>  eliminate busybox entirely?
>
No busybox, that's the target. This is not necessarily a great idea, but
it works. I agree that without this constraint, it could be possible to
build only a few programs in coreutils.

That use case works better with my patch, but the string option can also
work as you do not need to handle very long strings if you take two or
three executables.

>  If you know which extra features you need, perhaps you can just port
>  them to busybox? Upstream is really receptive to adding (sensible)
>  features, as long as they are hidden behind a config option.
>
>  Note: unlike the others, and don't have a problem with this huge
>  menu. But since all the other core maintainers have voiced objections
>  against it, I doubt it will go in.
>
It would be a good surprise for me if it went in.

Best regards,
diff mbox

Patch

diff --git a/package/coreutils/Config.in b/package/coreutils/Config.in
index d9f614a..2e0038e 100644
--- a/package/coreutils/Config.in
+++ b/package/coreutils/Config.in
@@ -14,6 +14,545 @@  config BR2_PACKAGE_COREUTILS
 
 	  http://www.gnu.org/software/coreutils/
 
+menuconfig BR2_PACKAGE_COREUTILS_SELECT
+	bool "Override the default set of installed coreutils"
+	depends on BR2_PACKAGE_COREUTILS
+
+if BR2_PACKAGE_COREUTILS_SELECT
+
+config BR2_PACKAGE_COREUTILS_SELECT_SQUARE_BRACKET
+	bool "["
+	help
+	  check file types and compare values
+
+config BR2_PACKAGE_COREUTILS_SELECT_ARCH
+	bool "arch"
+	help
+	  print machine hardware name (same as uname -m)
+
+config BR2_PACKAGE_COREUTILS_SELECT_BASE32
+	bool "base32"
+	help
+	  base32 encode/decode data and print to standard output
+
+config BR2_PACKAGE_COREUTILS_SELECT_BASE64
+	bool "base64"
+	help
+	  base64 encode/decode data and print to standard output
+
+config BR2_PACKAGE_COREUTILS_SELECT_BASENAME
+	bool "basename"
+	help
+	  strip directory and suffix from filenames
+
+config BR2_PACKAGE_COREUTILS_SELECT_CAT
+	bool "cat"
+	help
+	  concatenate files and print on the standard output
+
+config BR2_PACKAGE_COREUTILS_SELECT_CHCON
+	bool "chcon"
+	help
+	  change file security context
+
+config BR2_PACKAGE_COREUTILS_SELECT_CHGRP
+	bool "chgrp"
+	help
+	  change group ownership
+
+config BR2_PACKAGE_COREUTILS_SELECT_CHMOD
+	bool "chmod"
+	help
+	  change file mode bits
+
+config BR2_PACKAGE_COREUTILS_SELECT_CHOWN
+	bool "chown"
+	help
+	  change file owner and group
+
+config BR2_PACKAGE_COREUTILS_SELECT_CHROOT
+	bool "chroot"
+	help
+	  run command or interactive shell with special root directory
+
+config BR2_PACKAGE_COREUTILS_SELECT_CKSUM
+	bool "cksum"
+	help
+	  checksum and count the bytes in a file
+
+config BR2_PACKAGE_COREUTILS_SELECT_COMM
+	bool "comm"
+	help
+	  compare two sorted files line by line
+
+config BR2_PACKAGE_COREUTILS_SELECT_CP
+	bool "cp"
+	help
+	  copy files and directories
+
+config BR2_PACKAGE_COREUTILS_SELECT_CSPLIT
+	bool "csplit"
+	help
+	  split a file into sections determined by context lines
+
+config BR2_PACKAGE_COREUTILS_SELECT_CUT
+	bool "cut"
+	help
+	  remove sections from each line of files
+
+config BR2_PACKAGE_COREUTILS_SELECT_DATE
+	bool "date"
+	help
+	  print or set the system date and time
+
+config BR2_PACKAGE_COREUTILS_SELECT_DD
+	bool "dd"
+	help
+	  convert and copy a file
+
+config BR2_PACKAGE_COREUTILS_SELECT_DF
+	bool "df"
+	help
+	  report file system disk space usage
+
+config BR2_PACKAGE_COREUTILS_SELECT_DIR
+	bool "dir"
+	help
+	  list directory contents
+
+config BR2_PACKAGE_COREUTILS_SELECT_DIRCOLORS
+	bool "dircolors"
+	help
+	  color setup for ls
+
+config BR2_PACKAGE_COREUTILS_SELECT_DIRNAME
+	bool "dirname"
+	help
+	  strip last component from file name
+
+config BR2_PACKAGE_COREUTILS_SELECT_DU
+	bool "du"
+	help
+	  estimate file space usage
+
+config BR2_PACKAGE_COREUTILS_SELECT_ECHO
+	bool "echo"
+	help
+	  display a line of text
+
+config BR2_PACKAGE_COREUTILS_SELECT_ENV
+	bool "env"
+	help
+	  run a program in a modified environment
+
+config BR2_PACKAGE_COREUTILS_SELECT_EXPAND
+	bool "expand"
+	help
+	  convert tabs to spaces
+
+config BR2_PACKAGE_COREUTILS_SELECT_EXPR
+	bool "expr"
+	help
+	  evaluate expressions
+
+config BR2_PACKAGE_COREUTILS_SELECT_FACTOR
+	bool "factor"
+	help
+	  factor numbers
+
+config BR2_PACKAGE_COREUTILS_SELECT_FALSE
+	bool "false"
+	help
+	  do nothing, unsuccessfully
+
+config BR2_PACKAGE_COREUTILS_SELECT_FMT
+	bool "fmt"
+	help
+	  simple optimal text formatter
+
+config BR2_PACKAGE_COREUTILS_SELECT_FOLD
+	bool "fold"
+	help
+	  wrap each input line to fit in specified width
+
+config BR2_PACKAGE_COREUTILS_SELECT_GROUPS
+	bool "groups"
+	help
+	  print the groups a user is in
+
+config BR2_PACKAGE_COREUTILS_SELECT_HEAD
+	bool "head"
+	help
+	  output the first part of files
+
+config BR2_PACKAGE_COREUTILS_SELECT_HOSTID
+	bool "hostid"
+	help
+	  print the numeric identifier for the current host
+
+config BR2_PACKAGE_COREUTILS_SELECT_HOSTNAME
+	bool "hostname"
+	help
+	  set or print the name of the current host system
+
+config BR2_PACKAGE_COREUTILS_SELECT_ID
+	bool "id"
+	help
+	  print real and effective user and group IDs
+
+config BR2_PACKAGE_COREUTILS_SELECT_INSTALL
+	bool "install"
+	help
+	  copy files and set attributes
+
+config BR2_PACKAGE_COREUTILS_SELECT_JOIN
+	bool "join"
+	help
+	  join lines of two files on a common field
+
+config BR2_PACKAGE_COREUTILS_SELECT_KILL
+	bool "kill"
+	help
+	  send signals to processes, or list signals
+
+config BR2_PACKAGE_COREUTILS_SELECT_LINK
+	bool "link"
+	help
+	  call the link function to create a link to a file
+
+config BR2_PACKAGE_COREUTILS_SELECT_LN
+	bool "ln"
+	help
+	  make links between files
+
+config BR2_PACKAGE_COREUTILS_SELECT_LOGNAME
+	bool "logname"
+	help
+	  print user's login name
+
+config BR2_PACKAGE_COREUTILS_SELECT_LS
+	bool "ls"
+	help
+	  list directory contents
+
+config BR2_PACKAGE_COREUTILS_SELECT_MD5SUM
+	bool "md5sum"
+	help
+	  compute and check MD5 message digest
+
+config BR2_PACKAGE_COREUTILS_SELECT_MKDIR
+	bool "mkdir"
+	help
+	  make directories
+
+config BR2_PACKAGE_COREUTILS_SELECT_MKFIFO
+	bool "mkfifo"
+	help
+	  make FIFOs (named pipes)
+
+config BR2_PACKAGE_COREUTILS_SELECT_MKNOD
+	bool "mknod"
+	help
+	  make block or character special files
+
+config BR2_PACKAGE_COREUTILS_SELECT_MKTEMP
+	bool "mktemp"
+	help
+	  create a temporary file or directory
+
+config BR2_PACKAGE_COREUTILS_SELECT_MV
+	bool "mv"
+	help
+	  move (rename) files
+
+config BR2_PACKAGE_COREUTILS_SELECT_NICE
+	bool "nice"
+	help
+	  run a program with modified scheduling priority
+
+config BR2_PACKAGE_COREUTILS_SELECT_NL
+	bool "nl"
+	help
+	  number lines of files
+
+config BR2_PACKAGE_COREUTILS_SELECT_NOHUP
+	bool "nohup"
+	help
+	  run a command immune to hangups, with output to a non-tty
+
+config BR2_PACKAGE_COREUTILS_SELECT_NPROC
+	bool "nproc"
+	help
+	  print the number of processing units available
+
+config BR2_PACKAGE_COREUTILS_SELECT_NUMFMT
+	bool "numfmt"
+	help
+	  Convert numbers from/to human-readable strings
+
+config BR2_PACKAGE_COREUTILS_SELECT_OD
+	bool "od"
+	help
+	  dump files in octal and other formats
+
+config BR2_PACKAGE_COREUTILS_SELECT_PASTE
+	bool "paste"
+	help
+	  merge lines of files
+
+config BR2_PACKAGE_COREUTILS_SELECT_PATHCHK
+	bool "pathchk"
+	help
+	  check whether file names are valid or portable
+
+config BR2_PACKAGE_COREUTILS_SELECT_PINKY
+	bool "pinky"
+	help
+	  lightweight finger
+
+config BR2_PACKAGE_COREUTILS_SELECT_PR
+	bool "pr"
+	help
+	  convert text files for printing
+
+config BR2_PACKAGE_COREUTILS_SELECT_PRINTENV
+	bool "printenv"
+	help
+	  print all or part of environment
+
+config BR2_PACKAGE_COREUTILS_SELECT_PRINTF
+	bool "printf"
+	help
+	  format and print data
+
+config BR2_PACKAGE_COREUTILS_SELECT_PTX
+	bool "ptx"
+	help
+	  produce a permuted index of file contents
+
+config BR2_PACKAGE_COREUTILS_SELECT_PWD
+	bool "pwd"
+	help
+	  print name of current/working directory
+
+config BR2_PACKAGE_COREUTILS_SELECT_READLINK
+	bool "readlink"
+	help
+	  print resolved symbolic links or canonical file names
+
+config BR2_PACKAGE_COREUTILS_SELECT_REALPATH
+	bool "realpath"
+	help
+	  print the resolved path
+
+config BR2_PACKAGE_COREUTILS_SELECT_RM
+	bool "rm"
+	help
+	  remove files or directories
+
+config BR2_PACKAGE_COREUTILS_SELECT_RMDIR
+	bool "rmdir"
+	help
+	  remove empty directories
+
+config BR2_PACKAGE_COREUTILS_SELECT_RUNCON
+	bool "runcon"
+	help
+	  run command with specified security context
+
+config BR2_PACKAGE_COREUTILS_SELECT_SEQ
+	bool "seq"
+	help
+	  print a sequence of numbers
+
+config BR2_PACKAGE_COREUTILS_SELECT_SHA1SUM
+	bool "sha1sum"
+	help
+	  compute and check SHA1 message digest
+
+config BR2_PACKAGE_COREUTILS_SELECT_SHA224SUM
+	bool "sha224sum"
+	help
+	  compute and check SHA224 message digest
+
+config BR2_PACKAGE_COREUTILS_SELECT_SHA256SUM
+	bool "sha256sum"
+	help
+	  compute and check SHA256 message digest
+
+config BR2_PACKAGE_COREUTILS_SELECT_SHA384SUM
+	bool "sha384sum"
+	help
+	  compute and check SHA384 message digest
+
+config BR2_PACKAGE_COREUTILS_SELECT_SHA512SUM
+	bool "sha512sum"
+	help
+	  compute and check SHA512 message digest
+
+config BR2_PACKAGE_COREUTILS_SELECT_SHRED
+	bool "shred"
+	help
+	  overwrite a file to hide its contents, and optionally delete it
+
+config BR2_PACKAGE_COREUTILS_SELECT_SHUF
+	bool "shuf"
+	help
+	  generate random permutations
+
+config BR2_PACKAGE_COREUTILS_SELECT_SLEEP
+	bool "sleep"
+	help
+	  delay for a specified amount of time
+
+config BR2_PACKAGE_COREUTILS_SELECT_SORT
+	bool "sort"
+	help
+	  sort lines of text files
+
+config BR2_PACKAGE_COREUTILS_SELECT_SPLIT
+	bool "split"
+	help
+	  split a file into pieces
+
+config BR2_PACKAGE_COREUTILS_SELECT_STAT
+	bool "stat"
+	help
+	  display file or file system status
+
+config BR2_PACKAGE_COREUTILS_SELECT_STDBUF
+	bool "stdbuf"
+	depends on !BR2_STATIC_LIBS
+	help
+	  run command with specified buffering settings
+
+config BR2_PACKAGE_COREUTILS_SELECT_STTY
+	bool "stty"
+	help
+	  change and print terminal line settings
+
+config BR2_PACKAGE_COREUTILS_SELECT_SUM
+	bool "sum"
+	help
+	  checksum and count the blocks in a file
+
+config BR2_PACKAGE_COREUTILS_SELECT_SYNC
+	bool "sync"
+	help
+	  Synchronize cached writes to persistent storage
+
+config BR2_PACKAGE_COREUTILS_SELECT_TAC
+	bool "tac"
+	help
+	  concatenate and print files in reverse
+
+config BR2_PACKAGE_COREUTILS_SELECT_TAIL
+	bool "tail"
+	help
+	  output the last part of files
+
+config BR2_PACKAGE_COREUTILS_SELECT_TEE
+	bool "tee"
+	help
+	  read from standard input and write to standard output and files
+
+config BR2_PACKAGE_COREUTILS_SELECT_TEST
+	bool "test"
+	help
+	  check file types and compare values
+
+config BR2_PACKAGE_COREUTILS_SELECT_TIMEOUT
+	bool "timeout"
+	help
+	  run a command with a time limit
+
+config BR2_PACKAGE_COREUTILS_SELECT_TOUCH
+	bool "touch"
+	help
+	  change file timestamps
+
+config BR2_PACKAGE_COREUTILS_SELECT_TR
+	bool "tr"
+	help
+	  translate or delete characters
+
+config BR2_PACKAGE_COREUTILS_SELECT_TRUE
+	bool "true"
+	help
+	  do nothing, successfully
+
+config BR2_PACKAGE_COREUTILS_SELECT_TRUNCATE
+	bool "truncate"
+	help
+	  shrink or extend the size of a file to the specified size
+
+config BR2_PACKAGE_COREUTILS_SELECT_TSORT
+	bool "tsort"
+	help
+	  perform topological sort
+
+config BR2_PACKAGE_COREUTILS_SELECT_TTY
+	bool "tty"
+	help
+	  print the file name of the terminal connected to standard input
+
+config BR2_PACKAGE_COREUTILS_SELECT_UNAME
+	bool "uname"
+	help
+	  print system information
+
+config BR2_PACKAGE_COREUTILS_SELECT_UNEXPAND
+	bool "unexpand"
+	help
+	  convert spaces to tabs
+
+config BR2_PACKAGE_COREUTILS_SELECT_UNIQ
+	bool "uniq"
+	help
+	  report or omit repeated lines
+
+config BR2_PACKAGE_COREUTILS_SELECT_UNLINK
+	bool "unlink"
+	help
+	  call the unlink function to remove the specified file
+
+config BR2_PACKAGE_COREUTILS_SELECT_UPTIME
+	bool "uptime"
+	help
+	  tell how long the system has been running
+
+config BR2_PACKAGE_COREUTILS_SELECT_USERS
+	bool "users"
+	help
+	  print the user names of users currently logged in to the current host
+
+config BR2_PACKAGE_COREUTILS_SELECT_VDIR
+	bool "vdir"
+	help
+	  list directory contents
+
+config BR2_PACKAGE_COREUTILS_SELECT_WC
+	bool "wc"
+	help
+	  print newline, word, and byte counts for each file
+
+config BR2_PACKAGE_COREUTILS_SELECT_WHO
+	bool "who"
+	help
+	  show who is logged on
+
+config BR2_PACKAGE_COREUTILS_SELECT_WHOAMI
+	bool "whoami"
+	help
+	  print effective userid
+
+config BR2_PACKAGE_COREUTILS_SELECT_YES
+	bool "yes"
+	help
+	  output a string repeatedly until killed
+
+endif
+
 comment "coreutils needs a toolchain w/ wchar"
 	depends on BR2_USE_MMU
 	depends on !BR2_USE_WCHAR
diff --git a/package/coreutils/coreutils.mk b/package/coreutils/coreutils.mk
index 0d7b782..d03120a 100644
--- a/package/coreutils/coreutils.mk
+++ b/package/coreutils/coreutils.mk
@@ -103,21 +103,79 @@  ifeq ($(BR2_ROOTFS_MERGED_USR),)
 define COREUTILS_CLEANUP_BIN
 	# some things go in root rather than usr
 	for f in $(COREUTILS_BIN_PROGS); do \
-		mv -f $(TARGET_DIR)/usr/bin/$$f $(TARGET_DIR)/bin/$$f || exit 1; \
+		if [ -e $(TARGET_DIR)/usr/bin/$$f]; then \
+			mv -f $(TARGET_DIR)/usr/bin/$$f $(TARGET_DIR)/bin/$$f || exit 1; \
+		fi; \
 	done
 endef
 COREUTILS_POST_INSTALL_TARGET_HOOKS += COREUTILS_CLEANUP_BIN
 endif
 
+ifeq ($(BR2_PACKAGE_COREUTILS_SELECT),y)
+
+# List of all programs in coreutils
+
+# For install and [, as the Kconfig and autotool names do not match,
+# the different names are separated with ':'
+
+COREUTILS_ALL_PROGS := square_bracket:[ arch base32 base64 basename cat    \
+  chcon chgrp chmod chown chroot cksum comm cp csplit cut date dd df dir   \
+  dircolors dirname du echo env expand expr factor false fmt fold groups   \
+  head hostid hostname id install:ginstall join kill link ln logname ls    \
+  md5sum mkdir mkfifo mknod mktemp mv nice nl nohup nproc numfmt od paste  \
+  pathchk pinky pr printenv printf ptx pwd readlink realpath rm rmdir      \
+  runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf    \
+  sleep sort split stat stdbuf stty sum sync tac tail tee test timeout     \
+  touch tr true truncate tsort tty uname unexpand uniq unlink uptime users \
+  vdir wc who whoami yes
+
+define COREUTILS_REAL_OPTNAME
+$(word 2,$(subst :,$(space),$(1)))
+endef
+
+define COREUTILS_OPTNAME
+$(if $(call COREUTILS_REAL_OPTNAME,$(1)),$(call COREUTILS_REAL_OPTNAME,$(1)),$(1))
+endef
+
+define COREUTILS_BR2NAME
+$(call UPPERCASE,$(word 1,$(subst :,$(space),$(1))))
+endef
+
+define COREUTILS_DO_SELECT_NAME
+$(if $(BR2_PACKAGE_COREUTILS_SELECT_$(1)),$(2),$(3))
+endef
+
+define COREUTILS_IS_SELECTED
+$(call COREUTILS_DO_SELECT_NAME,$(call COREUTILS_BR2NAME,$(1)),$(call COREUTILS_OPTNAME,$(1)),,)
+endef
+
+define COREUTILS_IS_NOT_SELECTED
+$(call COREUTILS_DO_SELECT_NAME,$(call COREUTILS_BR2NAME,$(1)),,$(call COREUTILS_OPTNAME,$(1)),)
+endef
+
+COREUTILS_DO_INSTALL := $(foreach a,$(COREUTILS_ALL_PROGS),$(call COREUTILS_IS_SELECTED,$(a)))
+COREUTILS_DO_INSTALL := --enable-install-program=$(subst $(space),$(comma),$(strip $(COREUTILS_DO_INSTALL)))
+
+COREUTILS_NO_INSTALL := $(foreach a,$(COREUTILS_ALL_PROGS),$(call COREUTILS_IS_NOT_SELECTED,$(a)))
+COREUTILS_NO_INSTALL := --enable-no-install-program=$(subst $(space),$(comma),$(strip $(COREUTILS_NO_INSTALL)))
+
+COREUTILS_CONF_OPTS += $(COREUTILS_DO_INSTALL) $(COREUTILS_NO_INSTALL)
+
+else
 ifeq ($(BR2_STATIC_LIBS),y)
 COREUTILS_CONF_OPTS += --enable-no-install-program=stdbuf
 endif
+endif
 
 define COREUTILS_CLEANUP
 	# link for archaic shells
-	ln -fs test $(TARGET_DIR)/usr/bin/[
+	if ! [ -e "$(TARGET_DIR)/usr/bin/[" ]; then \
+		ln -fs test "$(TARGET_DIR)/usr/bin/["; \
+	fi
 	# gnu thinks chroot is in bin, debian thinks it's in sbin
-	mv -f $(TARGET_DIR)/usr/bin/chroot $(TARGET_DIR)/usr/sbin/chroot
+	if [ -e "$(TARGET_DIR)/usr/bin/chroot" ]; then \
+		mv -f "$(TARGET_DIR)/usr/bin/chroot" "$(TARGET_DIR)/usr/sbin/chroot"; \
+	fi
 endef
 
 COREUTILS_POST_INSTALL_TARGET_HOOKS += COREUTILS_CLEANUP