This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Choosing linker scripts (was Re: [v3] more symbol exports)
- From: Phil Edwards <phil at jaj dot com>
- To: Benjamin Kosnik <bkoz at redhat dot com>
- Cc: Loren James Rittle <rittle at latour dot rsch dot comm dot mot dot com>, gcc-patches at gcc dot gnu dot org, libstdc++ at gcc dot gnu dot org
- Date: Wed, 20 Feb 2002 17:13:08 -0500
- Subject: Choosing linker scripts (was Re: [v3] more symbol exports)
- References: <20020220114407.A4303@disaster.basement.lan> <Pine.SOL.3.91.1020220090228.29288A-100000@taarna.cygnus.com>
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.
+#