diff mbox

[v3] Fix cross compilation to Solaris

Message ID yddtw42qyly.fsf@CeBiTec.Uni-Bielefeld.DE
State New
Headers show

Commit Message

Rainer Orth May 30, 2017, 1:10 p.m. UTC
I recently tried a cross-build from sparc-sun-solaris2.12 to
i386-pc-solaris2.12 (with cross-binutils and gas, but the native ld
which has been a cross-linker for quite some time).  The build failed in
libstdc++-v3 like this:

/vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc:62:46: error: ‘void* aligned_alloc(std::size_t, std::size_t)’ conflicts with a previous declaration
 aligned_alloc (std::size_t al, std::size_t sz)
                                              ^
In file included from /var/gcc/sysroot/i386/usr/include/stdlib.h:13:0,
                 from /var/gcc/cross/i386-pc-solaris2.12/obj/gcc-8.0.0-20170516/12-gcc-gas/i386-pc-solaris2.12/libstdc++-v3/include/cstdlib:75,
                 from /var/gcc/cross/i386-pc-solaris2.12/obj/gcc-8.0.0-20170516/12-gcc-gas/i386-pc-solaris2.12/libstdc++-v3/include/stdlib.h:36,
                 from /vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc:27:
/var/gcc/sysroot/i386/usr/include/iso/stdlib_c99.h:79:14: note: previous declaration ‘void* std::aligned_alloc(std::size_t, std::size_t)’
 extern void *aligned_alloc(size_t, size_t);
              ^~~~~~~~~~~~~
/vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc: In function ‘void* operator new(std::size_t, std::align_val_t)’:
/vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc:103:57: error: call of overloaded ‘aligned_alloc(std::size_t&, std::size_t&)’ is ambiguous
   while (__builtin_expect ((p = aligned_alloc (align, sz)) == 0, false))
                                                         ^
In file included from /var/gcc/sysroot/i386/usr/include/stdlib.h:13:0,
                 from /var/gcc/cross/i386-pc-solaris2.12/obj/gcc-8.0.0-20170516/12-gcc-gas/i386-pc-solaris2.12/libstdc++-v3/include/cstdlib:75,
                 from /var/gcc/cross/i386-pc-solaris2.12/obj/gcc-8.0.0-20170516/12-gcc-gas/i386-pc-solaris2.12/libstdc++-v3/include/stdlib.h:36,
                 from /vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc:27:
/var/gcc/sysroot/i386/usr/include/iso/stdlib_c99.h:79:14: note: candidate: ‘void* std::aligned_alloc(std::size_t, std::size_t)’
 extern void *aligned_alloc(size_t, size_t);
              ^~~~~~~~~~~~~
/vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc:62:1: note: candidate: ‘void* aligned_alloc(std::size_t, std::size_t)’
 aligned_alloc (std::size_t al, std::size_t sz)
 ^~~~~~~~~~~~~
make[4]: *** [Makefile:936: new_opa.lo] Error 1

It turns out that currently crossconfig.m4 has a static list of
AC_DEFINEs for *-solaris*, which is obviously incomplete compared to the
target's features.  Instead of manually fixing this, it seems the way to
go is follow the lead of the Linux etc. targets and just perform the
link tests which are skipped in configure.ac for the !GLIBCXX_IS_NATIVE
case since they *do* work reliably in this case.  This is just what this
patch does: treat Solaris like the Linux targets and remove the
hardcoded feature list from crossconfig.m4.

This way, config.h is identical between a native build and the cross
above, with the exception of HAVE_SETENV which is equally guarded with
GLIBCXX_IS_NATIVE in acinclude.m4 (GLIBCXX_CONFIGURE_TESTSUITE).  Maybe
it's time to somehow refine the GLIBCXX_IS_NATIVE check to allow cross
configurations that *can* perform link tests to run them?

With the patch, the cross-build succeeded without issues.

Ok for mainline?

	Rainer

Comments

Jonathan Wakely June 1, 2017, 1:35 p.m. UTC | #1
On 30/05/17 15:10 +0200, Rainer Orth wrote:
>I recently tried a cross-build from sparc-sun-solaris2.12 to
>i386-pc-solaris2.12 (with cross-binutils and gas, but the native ld
>which has been a cross-linker for quite some time).  The build failed in
>libstdc++-v3 like this:
>
>/vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc:62:46: error: ‘void* aligned_alloc(std::size_t, std::size_t)’ conflicts with a previous declaration
> aligned_alloc (std::size_t al, std::size_t sz)
>                                              ^
>In file included from /var/gcc/sysroot/i386/usr/include/stdlib.h:13:0,
>                 from /var/gcc/cross/i386-pc-solaris2.12/obj/gcc-8.0.0-20170516/12-gcc-gas/i386-pc-solaris2.12/libstdc++-v3/include/cstdlib:75,
>                 from /var/gcc/cross/i386-pc-solaris2.12/obj/gcc-8.0.0-20170516/12-gcc-gas/i386-pc-solaris2.12/libstdc++-v3/include/stdlib.h:36,
>                 from /vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc:27:
>/var/gcc/sysroot/i386/usr/include/iso/stdlib_c99.h:79:14: note: previous declaration ‘void* std::aligned_alloc(std::size_t, std::size_t)’
> extern void *aligned_alloc(size_t, size_t);
>              ^~~~~~~~~~~~~
>/vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc: In function ‘void* operator new(std::size_t, std::align_val_t)’:
>/vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc:103:57: error: call of overloaded ‘aligned_alloc(std::size_t&, std::size_t&)’ is ambiguous
>   while (__builtin_expect ((p = aligned_alloc (align, sz)) == 0, false))
>                                                         ^
>In file included from /var/gcc/sysroot/i386/usr/include/stdlib.h:13:0,
>                 from /var/gcc/cross/i386-pc-solaris2.12/obj/gcc-8.0.0-20170516/12-gcc-gas/i386-pc-solaris2.12/libstdc++-v3/include/cstdlib:75,
>                 from /var/gcc/cross/i386-pc-solaris2.12/obj/gcc-8.0.0-20170516/12-gcc-gas/i386-pc-solaris2.12/libstdc++-v3/include/stdlib.h:36,
>                 from /vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc:27:
>/var/gcc/sysroot/i386/usr/include/iso/stdlib_c99.h:79:14: note: candidate: ‘void* std::aligned_alloc(std::size_t, std::size_t)’
> extern void *aligned_alloc(size_t, size_t);
>              ^~~~~~~~~~~~~
>/vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc:62:1: note: candidate: ‘void* aligned_alloc(std::size_t, std::size_t)’
> aligned_alloc (std::size_t al, std::size_t sz)
> ^~~~~~~~~~~~~
>make[4]: *** [Makefile:936: new_opa.lo] Error 1
>
>It turns out that currently crossconfig.m4 has a static list of
>AC_DEFINEs for *-solaris*, which is obviously incomplete compared to the
>target's features.  Instead of manually fixing this, it seems the way to
>go is follow the lead of the Linux etc. targets and just perform the
>link tests which are skipped in configure.ac for the !GLIBCXX_IS_NATIVE
>case since they *do* work reliably in this case.  This is just what this
>patch does: treat Solaris like the Linux targets and remove the
>hardcoded feature list from crossconfig.m4.
>
>This way, config.h is identical between a native build and the cross
>above, with the exception of HAVE_SETENV which is equally guarded with
>GLIBCXX_IS_NATIVE in acinclude.m4 (GLIBCXX_CONFIGURE_TESTSUITE).  Maybe
>it's time to somehow refine the GLIBCXX_IS_NATIVE check to allow cross
>configurations that *can* perform link tests to run them?

Sounds like a good idea, although I don't know how to do that.


>With the patch, the cross-build succeeded without issues.
>
>Ok for mainline?

OK, thanks.
Rainer Orth June 1, 2017, 2:20 p.m. UTC | #2
Hi Jonathan,

>>This way, config.h is identical between a native build and the cross
>>above, with the exception of HAVE_SETENV which is equally guarded with
>>GLIBCXX_IS_NATIVE in acinclude.m4 (GLIBCXX_CONFIGURE_TESTSUITE).  Maybe
>>it's time to somehow refine the GLIBCXX_IS_NATIVE check to allow cross
>>configurations that *can* perform link tests to run them?
>
> Sounds like a good idea, although I don't know how to do that.

I'm not sure either, since I couldn't easily find the origin of that
variable.  The earliest ChangeLog entry mentioning it is

2003-08-17  Phil Edwards  <pme@gcc.gnu.org>

[...]
        * configure.ac (GLIBCXX_IS_NATIVE):  Determine earlier and re-order.
        Comment out the conditionals for CANADIAN and GLIBCXX_BUILD_LIBMATH
        (currently unused).  Strip the fake-VPATH shell fragment from
        automake-generated rules, if present.

and it's already present in r70194 for configure.ac, the earliest after
the rename from configure.in.  No idea what happened to earlier history
before that rename: svn should be able to cope with that, I thought.

The !$GLIBCXX_IS_NATIVE branch in configure.ac explains

  # This lets us hard-code the functionality we know we'll have in the cross
  # target environment.  "Let" is a sugar-coated word placed on an especially
  # dull and tedious hack, actually.
  #
  # Here's why GLIBCXX_CHECK_MATH_SUPPORT, and other autoconf macros
  # that involve linking, can't be used:
  #    "cannot open sim-crt0.o"
  #    "cannot open crt0.o"
  # etc.  All this is because there currently exists no unified, consistent
  # way for top level CC information to be passed down to target directories:
  # newlib includes, newlib linking info, libgloss versus newlib crt0.o, etc.
  # When all of that is done, all of this hokey, excessive AC_DEFINE junk for
  # crosses can be removed.

which suggests this is primarily an issue for builds done in a unified
tree, with gcc, binutils, newlib etc. all thrown in at once, i.e. for
embedded targets.

ISTM that one should just be able to actually *do* a link test of an
empty main, see if it works and decide from there if link tests are
possible or not.

Me only very rarely doing crosses at all, and then mostly only building
cc1/cc1plus, am certainly not a good person to try this, though ;-)

	Rainer
diff mbox

Patch

# HG changeset patch
# Parent  282c9bac296f5446b92afe815eb60d2134d2de34
Support cross compilation to Solaris 12

diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -53748,7 +53748,7 @@  fi
 	;;
     esac
     ;;
-  *-linux* | *-uclinux* | *-gnu* | *-kfreebsd*-gnu | *-cygwin*)
+  *-linux* | *-uclinux* | *-gnu* | *-kfreebsd*-gnu | *-cygwin* | *-solaris*)
 
   # All these tests are for C++; save the language and the compiler flags.
   # The CXXFLAGS thing is suspicious, but based on similar bits previously
@@ -72389,170 +72389,6 @@  done
   CXXFLAGS="$ac_save_CXXFLAGS"
 
     ;;
-  *-solaris*)
-
-  # If we're not using GNU ld, then there's no point in even trying these
-  # tests.  Check for that first.  We should have already tested for gld
-  # by now (in libtool), but require it now just to be safe...
-  test -z "$SECTION_LDFLAGS" && SECTION_LDFLAGS=''
-  test -z "$OPT_LDFLAGS" && OPT_LDFLAGS=''
-
-
-
-  # 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.
-  glibcxx_ld_is_gold=no
-  if test x"$with_gnu_ld" = x"yes"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld version" >&5
-$as_echo_n "checking for ld version... " >&6; }
-
-    if $LD --version 2>/dev/null | grep 'GNU gold' >/dev/null 2>&1; then
-      glibcxx_ld_is_gold=yes
-    fi
-    ldver=`$LD --version 2>/dev/null |
-	   sed -e 's/GNU gold /GNU ld /;s/GNU ld version /GNU ld /;s/GNU ld ([^)]*) /GNU ld /;s/GNU ld \([0-9.][0-9.]*\).*/\1/; q'`
-
-    glibcxx_gnu_ld_version=`echo $ldver | \
-	   $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_gnu_ld_version" >&5
-$as_echo "$glibcxx_gnu_ld_version" >&6; }
-  fi
-
-  # Set --gc-sections.
-  glibcxx_have_gc_sections=no
-  if test "$glibcxx_ld_is_gold" = "yes"; then
-    if $LD --help 2>/dev/null | grep gc-sections >/dev/null 2>&1; then
-      glibcxx_have_gc_sections=yes
-    fi
-  else
-    glibcxx_gcsections_min_ld=21602
-    if test x"$with_gnu_ld" = x"yes" &&
-	test $glibcxx_gnu_ld_version -gt $glibcxx_gcsections_min_ld ; then
-      glibcxx_have_gc_sections=yes
-    fi
-  fi
-  if test "$glibcxx_have_gc_sections" = "yes"; then
-    # Sufficiently young GNU ld it is!  Joy and bunny rabbits!
-    # NB: This flag only works reliably after 2.16.1. Configure tests
-    # for this are difficult, so hard wire a value that should work.
-
-    ac_test_CFLAGS="${CFLAGS+set}"
-    ac_save_CFLAGS="$CFLAGS"
-    CFLAGS='-Wl,--gc-sections'
-
-    # Check for -Wl,--gc-sections
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,--gc-sections" >&5
-$as_echo_n "checking for ld that supports -Wl,--gc-sections... " >&6; }
-    if test x$gcc_no_link = xyes; then
-  as_fn_error "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
-fi
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
- int one(void) { return 1; }
-     int two(void) { return 2; }
-
-int
-main ()
-{
- two();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_gcsections=yes
-else
-  ac_gcsections=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-    if test "$ac_gcsections" = "yes"; then
-      rm -f conftest.c
-      touch conftest.c
-      if $CC -c conftest.c; then
-	if $LD --gc-sections -o conftest conftest.o 2>&1 | \
-	   grep "Warning: gc-sections option ignored" > /dev/null; then
-	  ac_gcsections=no
-	fi
-      fi
-      rm -f conftest.c conftest.o conftest
-    fi
-    if test "$ac_gcsections" = "yes"; then
-      SECTION_LDFLAGS="-Wl,--gc-sections $SECTION_LDFLAGS"
-    fi
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_gcsections" >&5
-$as_echo "$ac_gcsections" >&6; }
-
-    if test "$ac_test_CFLAGS" = set; then
-      CFLAGS="$ac_save_CFLAGS"
-    else
-      # this is the suspicious part
-      CFLAGS=''
-    fi
-  fi
-
-  # Set -z,relro.
-  # Note this is only for shared objects.
-  ac_ld_relro=no
-  if test x"$with_gnu_ld" = x"yes"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,-z,relro" >&5
-$as_echo_n "checking for ld that supports -Wl,-z,relro... " >&6; }
-    cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
-    if test -n "$cxx_z_relo"; then
-      OPT_LDFLAGS="-Wl,-z,relro"
-      ac_ld_relro=yes
-    fi
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ld_relro" >&5
-$as_echo "$ac_ld_relro" >&6; }
-  fi
-
-  # Set linker optimization flags.
-  if test x"$with_gnu_ld" = x"yes"; then
-    OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"
-  fi
-
-
-
-
-    $as_echo "#define HAVE_MBSTATE_T 1" >>confdefs.h
-
-    $as_echo "#define HAVE_FINITE 1" >>confdefs.h
-
-    $as_echo "#define HAVE_FPCLASS 1" >>confdefs.h
-
-    # All of the dependencies for wide character support are here, so
-    # turn it on.
-    $as_echo "#define _GLIBCXX_USE_WCHAR_T 1" >>confdefs.h
-
-    # These two C99 functions are present only in Solaris >= 10
-    $as_echo "#define HAVE_STRTOF 1" >>confdefs.h
-
-    $as_echo "#define HAVE_STRTOLD 1" >>confdefs.h
-
-    $as_echo "#define HAVE_ISNAN 1" >>confdefs.h
-
-    $as_echo "#define HAVE_ISNANF 1" >>confdefs.h
-
-    $as_echo "#define HAVE_MODFF 1" >>confdefs.h
-
-    $as_echo "#define HAVE_HYPOT 1" >>confdefs.h
-
-    ;;
   *-tpf)
     SECTION_FLAGS='-ffunction-sections -fdata-sections'
     SECTION_LDFLAGS='-Wl,--gc-sections $SECTION_LDFLAGS'
diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4
--- a/libstdc++-v3/crossconfig.m4
+++ b/libstdc++-v3/crossconfig.m4
@@ -182,7 +182,7 @@  case "${host}" in
 	;;
     esac
     ;;
-  *-linux* | *-uclinux* | *-gnu* | *-kfreebsd*-gnu | *-cygwin*)
+  *-linux* | *-uclinux* | *-gnu* | *-kfreebsd*-gnu | *-cygwin* | *-solaris*)
     GLIBCXX_CHECK_COMPILER_FEATURES
     GLIBCXX_CHECK_LINKER_FEATURES
     GLIBCXX_CHECK_MATH_SUPPORT
@@ -239,22 +239,6 @@  case "${host}" in
     GLIBCXX_CHECK_MATH_SUPPORT
     GLIBCXX_CHECK_STDLIB_SUPPORT
     ;;
-  *-solaris*)
-    GLIBCXX_CHECK_LINKER_FEATURES
-    AC_DEFINE(HAVE_MBSTATE_T)
-    AC_DEFINE(HAVE_FINITE)
-    AC_DEFINE(HAVE_FPCLASS)
-    # All of the dependencies for wide character support are here, so
-    # turn it on. 
-    AC_DEFINE(_GLIBCXX_USE_WCHAR_T) 
-    # These two C99 functions are present only in Solaris >= 10
-    AC_DEFINE(HAVE_STRTOF)
-    AC_DEFINE(HAVE_STRTOLD)
-    AC_DEFINE(HAVE_ISNAN)
-    AC_DEFINE(HAVE_ISNANF)
-    AC_DEFINE(HAVE_MODFF)
-    AC_DEFINE(HAVE_HYPOT)
-    ;;
   *-tpf)
     SECTION_FLAGS='-ffunction-sections -fdata-sections'
     SECTION_LDFLAGS='-Wl,--gc-sections $SECTION_LDFLAGS'