Thread: make use of ld --as-needed

make use of ld --as-needed

From
Neil Conway
Date:
The issue has been raised in the past that our build system links each
executable against the maximal set of libraries it might need. So for
example, if one executable requires `libreadline', all executables are
linked against it.

The easiest fix is to make use of GNU ld's --as-needed flag, which
ignores linker arguments that are not actually needed by the specified
object files. The attached patch modifies configure to check for this
flag (when using GNU ld), and if ld supports it, adds the flag to
LDFLAGS (we need to do the check since only relatively recent versions
of GNU ld support this capability). The patch only checks for GNU ld:
does anyone know if any other linkers support this capability, and if
so, what flags need to be specified to enable it?

I haven't had a chance to test this on a non-GNU-ld system, but I will
do so before applying. Barring any objections, I'll apply this tomorrow.

-Neil
Index: configure
===================================================================
RCS file: /var/lib/cvs/pgsql/configure,v
retrieving revision 1.434
diff -c -r1.434 configure
*** configure    25 Mar 2005 00:34:19 -0000    1.434
--- configure    5 May 2005 03:46:43 -0000
***************
*** 3622,3632 ****
  CPPFLAGS="$CPPFLAGS $INCLUDES"
  LDFLAGS="$LDFLAGS $LIBDIRS"

- { echo "$as_me:$LINENO: using CPPFLAGS=$CPPFLAGS" >&5
- echo "$as_me: using CPPFLAGS=$CPPFLAGS" >&6;}
- { echo "$as_me:$LINENO: using LDFLAGS=$LDFLAGS" >&5
- echo "$as_me: using LDFLAGS=$LDFLAGS" >&6;}
-


  for ac_prog in gawk mawk nawk awk
--- 3622,3627 ----
***************
*** 4167,4172 ****
--- 4162,4233 ----



+ # To simplify the build system, we specify the maximal set of
+ # libraries to link against when building any executable. The linker
+ # on same platforms optionally allows unused link arguments to be
+ # elided from the resulting executable, so enable that capability if
+ # it exists.
+ # XXX: currently we only support GNU ld; do any other linkers support
+ # an equivalent feature?
+ if test "$with_gnu_ld"; then
+   echo "$as_me:$LINENO: checking whether ld --as-needed works" >&5
+ echo $ECHO_N "checking whether ld --as-needed works... $ECHO_C" >&6
+ if test "${pgac_cv_prog_ld_as_needed+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+
+     pgac_save_LDFLAGS=$LDFLAGS; LDFLAGS="$LDFLAGS -Wl,--as-needed"
+     cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+
+ #ifdef F77_DUMMY_MAIN
+ #  ifdef __cplusplus
+      extern "C"
+ #  endif
+    int F77_DUMMY_MAIN() { return 1; }
+ #endif
+ int
+ main ()
+ {
+
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+   (eval $ac_link) 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+          { ac_try='test -s conftest$ac_exeext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }; }; then
+   pgac_cv_prog_ld_as_needed=yes
+ else
+   echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ pgac_cv_prog_ld_as_needed=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+    if test x"$pgac_cv_prog_ld_as_needed" = x"no"; then
+      LDFLAGS=$pgac_save_LDFLAGS
+    fi
+
+ fi
+ echo "$as_me:$LINENO: result: $pgac_cv_prog_ld_as_needed" >&5
+ echo "${ECHO_T}$pgac_cv_prog_ld_as_needed" >&6
+ fi
+
+ { echo "$as_me:$LINENO: using CPPFLAGS=$CPPFLAGS" >&5
+ echo "$as_me: using CPPFLAGS=$CPPFLAGS" >&6;}
+ { echo "$as_me:$LINENO: using LDFLAGS=$LDFLAGS" >&5
+ echo "$as_me: using LDFLAGS=$LDFLAGS" >&6;}
+
  for ac_prog in 'bison -y'
  do
    # Extract the first word of "$ac_prog", so it can be a program name with args.
Index: configure.in
===================================================================
RCS file: /var/lib/cvs/pgsql/configure.in,v
retrieving revision 1.407
diff -c -r1.407 configure.in
*** configure.in    25 Mar 2005 00:34:19 -0000    1.407
--- configure.in    5 May 2005 03:46:21 -0000
***************
*** 539,547 ****
  CPPFLAGS="$CPPFLAGS $INCLUDES"
  LDFLAGS="$LDFLAGS $LIBDIRS"

- AC_MSG_NOTICE([using CPPFLAGS=$CPPFLAGS])
- AC_MSG_NOTICE([using LDFLAGS=$LDFLAGS])
-
  AC_ARG_VAR(LDFLAGS_SL)

  AC_PROG_AWK
--- 539,544 ----
***************
*** 565,570 ****
--- 562,590 ----
  AC_PATH_PROG(TAR, tar)
  PGAC_CHECK_STRIP

+ # To simplify the build system, we specify the maximal set of
+ # libraries to link against when building any executable. The linker
+ # on same platforms optionally allows unused link arguments to be
+ # elided from the resulting executable, so enable that capability if
+ # it exists.
+ # XXX: currently we only support GNU ld; do any other linkers support
+ # an equivalent feature?
+ if test "$with_gnu_ld"; then
+   AC_CACHE_CHECK([whether ld --as-needed works], [pgac_cv_prog_ld_as_needed],
+   [
+     pgac_save_LDFLAGS=$LDFLAGS; LDFLAGS="$LDFLAGS -Wl,--as-needed"
+     AC_TRY_LINK([], [],
+                 [pgac_cv_prog_ld_as_needed=yes],
+                 [pgac_cv_prog_ld_as_needed=no])
+    if test x"$pgac_cv_prog_ld_as_needed" = x"no"; then
+      LDFLAGS=$pgac_save_LDFLAGS
+    fi
+   ])
+ fi
+
+ AC_MSG_NOTICE([using CPPFLAGS=$CPPFLAGS])
+ AC_MSG_NOTICE([using LDFLAGS=$LDFLAGS])
+
  AC_CHECK_PROGS(YACC, ['bison -y'])

  if test "$YACC"; then

Re: make use of ld --as-needed

From
Tom Lane
Date:
Neil Conway <neilc@samurai.com> writes:
> The easiest fix is to make use of GNU ld's --as-needed flag, which
> ignores linker arguments that are not actually needed by the specified
> object files. The attached patch modifies configure to check for this
> flag (when using GNU ld),

Minor gripe --- what's the motivation for moving this down as you did?
Seems like if there's something wrong there, it would justify rather
more rearrangements in the order of tests than just this.

Also, please s/same platforms/some platforms/

            regards, tom lane

Re: make use of ld --as-needed

From
Neil Conway
Date:
Tom Lane wrote:
> Minor gripe --- what's the motivation for moving this down as you did?

What do you mean by "this"? I moved the AC_MSG_NOTICEs for CPPFLAGS and
LDFLAGS down below the --as-needed check, since the --as-needed check
may modify LDFLAGS.

> Also, please s/same platforms/some platforms/

Thanks for catching that.

-Neil

Re: make use of ld --as-needed

From
Tom Lane
Date:
Neil Conway <neilc@samurai.com> writes:
> Tom Lane wrote:
>> Minor gripe --- what's the motivation for moving this down as you did?

> What do you mean by "this"? I moved the AC_MSG_NOTICEs for CPPFLAGS and
> LDFLAGS down below the --as-needed check, since the --as-needed check
> may modify LDFLAGS.

Well, I guess the question is why you put the --as-needed check where
you did, rather than above the existing AC_MSG_NOTICE displays.  If it
has an interaction with the intervening tests, what is that exactly?
Surely finding "tar" for instance is not related.

            regards, tom lane

Re: make use of ld --as-needed

From
Neil Conway
Date:
Tom Lane wrote:
> Well, I guess the question is why you put the --as-needed check where
> you did, rather than above the existing AC_MSG_NOTICE displays.  If it
> has an interaction with the intervening tests, what is that exactly?

PGAC_PROG_LD needs to be invoked to figure out if we're using gnu ld.
That's the only dependency AFAIK, so I'll move the --as-needed check to
before AC_PROG_RANLIB -- that is more logical.

-Neil