Subject: bug#20437: ls links too many dynamic libraries

From: Paul Eggert <[email-masked]>
Date: Sun, 26 Apr 2015 22:30:16 -0700

Currently GNU 'ls' dynamically links a whole bunch of libraries, libraries like 
libpcre and liblzma.  Can we figure out some way to remove the runtime 
dependencies on these libraries?  It's better if a core utility like 'ls' avoids 
libthis and libthat unless the libraries are vital to its function, which these 
shouldn't be.

I installed the attached patches to get rid of one unnecessary library, libacl, 
on GNU/Linux.  Can we do better and get rid of more dependencies?  Perhaps using 
techniques similar to what was used to get rid of libacl?
>From 5874d5a7070e0f19ffa8bc48e15e094bbe91d75c Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Sun, 26 Apr 2015 15:46:18 -0700
Subject: [PATCH 1/2] build: update gnulib submodule to latest

* bootstrap.conf (gnulib_modules): Add file-has-acl.
(buildreq): Bump autopoint and gettext to 0.19.4.
* configure.ac (AM_GNU_GETTEXT_VERSION):
Bump to 0.19.4.
* gl/lib/tempname.c.diff, gl/lib/tempname.h.diff:
Merge recent gnulib changes.
---
 bootstrap.conf         |  5 +++--
 configure.ac           |  2 +-
 gl/lib/tempname.c.diff | 22 +++++++++++-----------
 gl/lib/tempname.h.diff | 18 ++++++++++--------
 gnulib                 |  2 +-
 5 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/bootstrap.conf b/bootstrap.conf
index 4283140..75df5de 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -81,6 +81,7 @@ gnulib_modules="
   fdl
   fdopen
   fdutimensat
+  file-has-acl
   file-type
   fileblocks
   filemode
@@ -318,9 +319,9 @@ gnulib_tool_option_extras="--tests-base=gnulib-tests --with-tests --symlink\
 buildreq="\
 autoconf   2.64
 automake   1.11.2
-autopoint  -
+autopoint  0.19.4
 bison      -
-gettext    0.18.1
+gettext    0.19.4
 git        1.4.4
 gperf      -
 gzip       -
diff --git a/configure.ac b/configure.ac
index 3918f43..7959bf4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -590,7 +590,7 @@ AM_CONDITIONAL([CROSS_COMPILING], [test "$cross_compiling" = yes])
 # As long as "grep 'PRI[diouxX]' po/*.pot" reports matches in
 # translatable strings, we must use need-formatstring-macros here.
 AM_GNU_GETTEXT([external], [need-formatstring-macros])
-AM_GNU_GETTEXT_VERSION([0.18.1])
+AM_GNU_GETTEXT_VERSION([0.19.4])
 
 # For a test of uniq: it uses the $LOCALE_FR envvar.
 gt_LOCALE_FR
diff --git a/gl/lib/tempname.c.diff b/gl/lib/tempname.c.diff
index 459a1e5..43858e9 100644
--- a/gl/lib/tempname.c.diff
+++ b/gl/lib/tempname.c.diff
@@ -1,5 +1,5 @@
 diff --git a/lib/tempname.c b/lib/tempname.c
-index 49c7df1..84a45d4 100644
+index 69c572f..1920274 100644
 --- a/lib/tempname.c
 +++ b/lib/tempname.c
 @@ -20,6 +20,7 @@
@@ -34,9 +34,9 @@ index 49c7df1..84a45d4 100644
 
  int
 -__try_tempname (char *tmpl, int suffixlen, void *args,
--                int (*try) (char *, void *))
+-                int (*tryfunc) (char *, void *))
 +try_tempname_len (char *tmpl, int suffixlen, void *args,
-+                  int (*try) (char *, void *), size_t x_suffix_len)
++                  int (*tryfunc) (char *, void *), size_t x_suffix_len)
  {
 -  int len;
 +  size_t len;
@@ -113,7 +113,7 @@ index 49c7df1..84a45d4 100644
 +      for (i = 0; i < x_suffix_len; i++)
 +        XXXXXX[i] = letters[randint_genmax (rand_src, sizeof letters - 2)];
 
-       fd = try (tmpl, args);
+       fd = tryfunc (tmpl, args);
        if (fd >= 0)
          {
            __set_errno (save_errno);
@@ -144,7 +144,7 @@ index 49c7df1..84a45d4 100644
  }
 
  static int
-@@ -285,9 +291,10 @@ try_nocreate (char *tmpl, void *flags)
+@@ -285,9 +291,10 @@ try_nocreate (char *tmpl, void *flags _GL_UNUSED)
  }
 
  /* Generate a temporary file name based on TMPL.  TMPL must match the
@@ -157,7 +157,7 @@ index 49c7df1..84a45d4 100644
 
     KIND may be one of:
     __GT_NOCREATE:       simply verify that the name does not exist
-@@ -298,7 +305,8 @@ try_nocreate (char *tmpl, void *flags)
+@@ -298,7 +305,8 @@ try_nocreate (char *tmpl, void *flags _GL_UNUSED)
 
     We use a clever algorithm to get hard-to-predict names. */
  int
@@ -165,14 +165,14 @@ index 49c7df1..84a45d4 100644
 +gen_tempname_len (char *tmpl, int suffixlen, int flags, int kind,
 +                  size_t x_suffix_len)
  {
-   int (*try) (char *, void *);
+   int (*tryfunc) (char *, void *);
 
 @@ -320,5 +328,18 @@ __gen_tempname (char *tmpl, int suffixlen, int flags, int kind)
        assert (! "invalid KIND in __gen_tempname");
        abort ();
      }
--  return __try_tempname (tmpl, suffixlen, &flags, try);
-+  return try_tempname_len (tmpl, suffixlen, &flags, try, x_suffix_len);
+-  return __try_tempname (tmpl, suffixlen, &flags, tryfunc);
++  return try_tempname_len (tmpl, suffixlen, &flags, tryfunc, x_suffix_len);
 +}
 +
 +int
@@ -183,7 +183,7 @@ index 49c7df1..84a45d4 100644
 +
 +int
 +__try_tempname (char *tmpl, int suffixlen, void *args,
-+                int (*try) (char *, void *))
++                int (*tryfunc) (char *, void *))
 +{
-+  return try_tempname_len (tmpl, suffixlen, args, try, 6);
++  return try_tempname_len (tmpl, suffixlen, args, tryfunc, 6);
  }
diff --git a/gl/lib/tempname.h.diff b/gl/lib/tempname.h.diff
index 843692e..210e70b 100644
--- a/gl/lib/tempname.h.diff
+++ b/gl/lib/tempname.h.diff
@@ -1,21 +1,23 @@
 diff --git a/lib/tempname.h b/lib/tempname.h
-index f7c98d0..793207f 100644
+index e609360..6029b9f 100644
 --- a/lib/tempname.h
 +++ b/lib/tempname.h
-@@ -46,6 +46,8 @@
+@@ -50,6 +50,8 @@ extern "C" {
 
     We use a clever algorithm to get hard-to-predict names. */
  extern int gen_tempname (char *tmpl, int suffixlen, int flags, int kind);
 +extern int gen_tempname_len (char *tmpl, int suffixlen, int flags, int kind,
 +                             size_t x_suffix_len);
 
- /* Similar to gen_tempname, but TRY is called for each temporary
-    name to try.  If TRY returns a non-negative number, TRY_GEN_TEMPNAME
-@@ -53,5 +55,7 @@ extern int gen_tempname (char *tmpl, int suffixlen, int flags, int kind);
+ /* Similar to gen_tempname, but TRYFUNC is called for each temporary
+    name to try.  If TRYFUNC returns a non-negative number, TRY_GEN_TEMPNAME
+@@ -57,6 +59,9 @@ extern int gen_tempname (char *tmpl, int suffixlen, int flags, int kind);
     name is tried, or else TRY_GEN_TEMPNAME returns -1. */
  extern int try_tempname (char *tmpl, int suffixlen, void *args,
-                          int (*try) (char *, void *));
+                          int (*tryfunc) (char *, void *));
 +extern int try_tempname_len (char *tmpl, int suffixlen, void *args,
-+                             int (*try) (char *, void *), size_t x_suffix_len);
++                             int (*tryfunc) (char *, void *),
++                             size_t x_suffix_len);
 
- #endif /* GL_TEMPNAME_H */
+ #ifdef __cplusplus
+ }
diff --git a/gnulib b/gnulib
index 6e0e31c..ff714c0 160000
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit 6e0e31c383c86e297bfbb8dae89515b0587a1b15
+Subproject commit ff714c0a2094bdefd9ed41603493e66aaf285f12
-- 
2.1.0

>From 5279e31bbdb1e570d7b86a947c6c76d7f8f68b11 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Sun, 26 Apr 2015 22:09:30 -0700
Subject: [PATCH 2/2] ls: on GNU/Linux, remove dependency on libacl

* src/local.mk (src_ls_LDADD): Change from LIB_ACL to LIB_HAS_ACL.
---
 src/local.mk | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/local.mk b/src/local.mk
index 19152f0..5a3b1b3 100644
--- a/src/local.mk
+++ b/src/local.mk
@@ -278,7 +278,7 @@ src_uptime_LDADD += $(GETLOADAVG_LIBS)
 
 # for various ACL functions
 copy_ldadd += $(LIB_ACL)
-src_ls_LDADD += $(LIB_ACL)
+src_ls_LDADD += $(LIB_HAS_ACL)
 
 # for various xattr functions
 copy_ldadd += $(LIB_XATTR)
-- 
2.1.0