Choosing linker scripts (was Re: [v3] more symbol exports)

Phil Edwards phil@jaj.com
Wed Feb 20 14:13:00 GMT 2002


On Wed, Feb 20, 2002 at 09:05:12AM -0800, Benjamin Kosnik wrote:
> 
> > I'll start playing with this now.  I won't check anything in (anything
> > that makes this the default, at least) until we hear more good news on
> > the BSD front.  I'll change the option from =yes to =gnu while I'm at it.
> 
> Great. I'm not quite sure how to specify shared libsgcc, as suggested by 
> Loren in the last email about BSD support.

Me neither.

Anyhow, this is what's going in.  (Checked on i686-linux, all combinations
of --enable-symver options, with no regressions.)

The user can specify =gnu (or other schemes, I might actually be able to give
Solaris a try soon), and that will unconditionally use the appropriate script
file.  If the user doesn't specify anything (e.g., "--enable-symvers"),
then we check for a GNU ld of the appropriate version and go that route.

The default in configure.in remains 'no'.  Changing it to 'yes' will
have the same effect as a user turning the switch on without specifying
a particular scheme, that is, we'll check for GNU ld and compare versions.

A value of 'no', or any errors, continues to not do versioning, but now we
symlink a dummy file into the objdir instead of the gnu script.  The file
is still unused; it just won't be as confusing.

I did the linker version check in the same macro as the other linker checks.
So the diff is large even though the behavior hasn't changed very much.

(If I had waited a few hours, and included the local time in the changelog,
I would've had a unique palindrome timestamp:  "20:02, 20/02, 2002"  That
hasn't happened for a millinium, and will never happen again.)


2002-02-20  Phil Edwards  <pme@gcc.gnu.org>

	* acinclude.m4 (GLIBCPP_CHECK_LINKER_FEATURES):  Also check version.
	(GLIBCPP_ENABLE_SYMVERS):  Redo logic, use linker version.
	* configure.in (GLIBCPP_ENABLE_SYMVERS):  Move later in the script.
	* aclocal.m4:  Regenerate.
	* configure:  Regenerate.
	* config/linker-map.dummy:  New file.  Contains nothing useful.


Index: acinclude.m4
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/acinclude.m4,v
retrieving revision 1.191
diff -u -3 -p -r1.191 acinclude.m4
--- acinclude.m4	2002/02/14 18:24:04	1.191
+++ acinclude.m4	2002/02/20 21:58:48
@@ -49,6 +49,7 @@ AC_SUBST(glibcpp_srcdir)
 dnl This is here just to satisfy automake.
 ifelse(not,equal,[AC_CONFIG_AUX_DIR(..)])
 
+AC_PROG_AWK
 # Will set LN_S to either 'ln -s' or 'ln'.  With autoconf 2.50+, can also
 # be 'cp -p' if linking isn't available.
 #ac_cv_prog_LN_S='cp -p'
@@ -280,6 +281,8 @@ dnl safe (like an empty string).
 dnl
 dnl Define SECTION_LDFLAGS='-Wl,--gc-sections' if possible.
 dnl Define OPT_LDFLAGS='-Wl,-O1' if possible.
+dnl Define LD, with_gnu_ld, and (possibly) glibcpp_gnu_ld_version as
+dnl side-effects of testing.
 dnl
 dnl GLIBCPP_CHECK_LINKER_FEATURES
 AC_DEFUN(GLIBCPP_CHECK_LINKER_FEATURES, [
@@ -290,8 +293,32 @@ AC_DEFUN(GLIBCPP_CHECK_LINKER_FEATURES, 
   test -z "$OPT_LDFLAGS" && OPT_LDFLAGS=''
   AC_REQUIRE([AC_PROG_LD])
 
+  # The name set by libtool depends on the version of libtool.  Shame on us
+  # for depending on an impl detail, but c'est la vie.  Older versions used
+  # ac_cv_prog_gnu_ld, but now it's lt_cv_prog_gnu_ld, and is copied back on
+  # top of with_gnu_ld (which is also set by --with-gnu-ld, so that actually
+  # makes sense).  We'll test with_gnu_ld everywhere else, so if that isn't
+  # set (hence we're using an older libtool), then set it.
+  if test x${with_gnu_ld+set} != xset; then
+    if test x${ac_cv_prog_gnu_ld+set} != xset; then
+      # We got through "ac_require(ac_prog_ld)" and still not set?  Huh?
+      with_gnu_ld=no
+    else
+      with_gnu_ld=$ac_cv_prog_gnu_ld
+    fi
+  fi
+
+  # Start by getting the version number.  I think the libtool test already
+  # does some of this, but throws away the result.
+  changequote(,)
+  ldver=`$LD --version 2>/dev/null | head -1 | \
+         sed -e 's/GNU ld version \([0-9.][0-9.]*\).*/\1/'`
+  changequote([,])
+  glibcpp_gnu_ld_version=`echo $ldver | \
+         $AWK -F. '{ if (NF<3) [$]3=0; print ([$]1*100+[$]2)*100+[$]3 }'`
+
   # Set --gc-sections.
-  if test "$ac_cv_prog_gnu_ld" = "notbroken"; then
+  if test "$with_gnu_ld" = "notbroken"; then
     # GNU ld it is!  Joy and bunny rabbits!
 
     # All these tests are for C++; save the language and the compiler flags.
@@ -329,7 +356,7 @@ AC_DEFUN(GLIBCPP_CHECK_LINKER_FEATURES, 
   fi
 
   # Set linker optimization flags.
-  if test x"$ac_cv_prog_gnu_ld" = x"yes" &&
+  if test x"$with_gnu_ld" = x"yes" &&
      test x"$enable_debug" = x"no"; then
     OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"
   fi
@@ -2009,52 +2036,67 @@ dnl Add version tags to symbols in share
 dnl marking other symbols as private/local (or not).
 dnl
 dnl GLIBCPP_ENABLE_SYMVERS
-dnl --enable-symvers adds a version script to the linker call when creating
-dnl       the shared library.
+dnl --enable-symvers=style adds a version script to the linker call when
+dnl       creating the shared library.  The choice of version script is
+dnl       controlled by 'style'.
 dnl --disable-symvers does not.
 dnl  +  Usage:  GLIBCPP_ENABLE_SYMVERS[(DEFAULT)]
 dnl       Where DEFAULT is either `yes' or `no'.  If ommitted, it
-dnl       defaults to `no'.
+dnl       defaults to `no'.  Passing `yes' tries to choose a default style
+dnl       based on linker characteristics.
 AC_DEFUN(GLIBCPP_ENABLE_SYMVERS, [dnl
-AC_REQUIRE([AC_PROG_LD])
 define([GLIBCPP_ENABLE_SYMVERS_DEFAULT], ifelse($1, yes, yes, no))dnl
 AC_ARG_ENABLE(symvers,
 changequote(<<, >>)dnl
-<<  --enable-symvers        enables symbol versioning of the shared library [default=>>GLIBCPP_ENABLE_SYMVERS_DEFAULT],
+<<  --enable-symvers=style  enables symbol versioning of the shared library [default=>>GLIBCPP_ENABLE_SYMVERS_DEFAULT],
 changequote([, ])dnl
 [case "$enableval" in
- yes) enable_symvers=yes ;;
+ yes) enable_symvers=default ;;
  no)  enable_symvers=no ;;
+ # other names here, just as sanity checks
+ #gnu|sun|etcetera) enable_symvers=$enableval ;;
+ gnu) enable_symvers=$enableval ;;
  *)   AC_MSG_ERROR([Unknown argument to enable/disable symvers]) ;;
  esac],
 enable_symvers=GLIBCPP_ENABLE_SYMVERS_DEFAULT)dnl
-dnl Option parsed, now set things appropriately
+
+# If we never went through the GLIBCPP_CHECK_LINKER_FEATURES macro, then we
+# don't know enough about $LD... I think.
 AC_MSG_CHECKING([whether to version shared lib symbols])
-if test $enable_shared = no; then
+if test $enable_shared = no || test x$LD = x ; then
   enable_symvers=irrelevant
 fi
-# placeholder -- maybe have a fallback later
-LINKER_MAP=config/linker-map.gnu
-# symvers variable may evolve into holding the type of linker map someday
-if test $enable_symvers = yes; then
-  # flat-out assume a whole bunch of things right now
-  #
-  # The name of this variable changed between autoconf versions (our problem
-  # for depending on an impl detail, tsk tsk).  It used to be
-  # ac_cv_prog_gnu_ld but is now lt_cv_prog_gnu_ld, and is copied back into
-  # with_gnu_ld which can also be user-settable.  Let's use that one.
-  if test $with_gnu_ld = yes; then
-    # we also assume that the gnu ld in question has phil's patches... can't
-    # think today of an easy way to programatically test for that; revisit
-    LINKER_MAP=config/linker-map.gnu
-  else
-    # placeholder -- maybe have a fallback later
-    LINKER_MAP=config/linker-map.gnu
-    enable_symvers=no
-  fi
-fi
+
+# For GNU ld, we need at least this version.  It's 2.12 in the same format
+# as the tested-for version.  See GLIBCPP_CHECK_LINKER_FEATURES for more.
+glibcpp_min_gnu_ld_version=21200
+
+dnl Everything parsed; figure out the actions.
+LINKER_MAP=config/linker-map.dummy
+case $enable_symvers in
+  no | irrelevant)
+      ;;
+  gnu)
+      LINKER_MAP=config/linker-map.gnu
+      ;;
+dnl  sun)
+dnl      LINKER_MAP=config/linker-map....?
+dnl      ;;
+  default)   # not specified by user, try to figure it out
+      if test $with_gnu_ld = yes &&
+         test $glibcpp_gnu_ld_version -ge $glibcpp_min_gnu_ld_version ;
+      then
+        LINKER_MAP=config/linker-map.gnu
+      else
+	# just fail for now
+        enable_symvers=no
+      fi
+      ;;
+esac
+
 AC_LINK_FILES($LINKER_MAP, src/linker.map)
-AM_CONDITIONAL(GLIBCPP_BUILD_VERSIONED_SHLIB, test "$enable_symvers" = yes)
+AM_CONDITIONAL(GLIBCPP_BUILD_VERSIONED_SHLIB,
+    test $enable_symvers != no && test $enable_symvers != irrelevant)
 AC_MSG_RESULT($enable_symvers)
 ])
 
Index: configure.in
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/configure.in,v
retrieving revision 1.81
diff -u -3 -p -r1.81 configure.in
--- configure.in	2002/02/14 18:24:10	1.81
+++ configure.in	2002/02/20 21:58:48
@@ -49,7 +49,6 @@ GLIBCPP_ENABLE_THREADS
 GLIBCPP_ENABLE_CXX_FLAGS([none])
 GLIBCPP_ENABLE_SJLJ_EXCEPTIONS
 GLIBCPP_ENABLE_CONCEPT_CHECKS
-GLIBCPP_ENABLE_SYMVERS([no])
 
 
 if test -n "$with_cross_host" || test x"$build" != x"$host"; then
@@ -250,6 +249,8 @@ else
   GLIBCPP_CONFIGURE_TESTSUITE
 fi
 
+# This depends on the possibly-skipped linker test above.
+GLIBCPP_ENABLE_SYMVERS([no])
 
 # Propagate the target-specific source directories through the build chain.
 OS_INC_SRCDIR=$os_include_dir/bits
Index: config/linker-map.dummy
===================================================================
RCS file: linker-map.dummy
diff -N linker-map.dummy
--- /dev/null	Tue May  5 13:32:27 1998
+++ linker-map.dummy	Wed Feb 20 13:58:49 2002
@@ -0,0 +1,7 @@
+# 
+# This is a placeholder file.  It does nothing and is not used.
+# 
+# If you are seeing this file as your linker script (named linker.map), then
+# either 1) the configuration process determined that symbol versioning should
+# not be done, or 2) you specifically turned it off.
+# 



More information about the Libstdc++ mailing list