From: Norman Gray <norman@astro.gla.ac.uk>
To: fortran-dev@lists.apple.com
Cc: Martin Costabel <costabel@wanadoo.fr>, Stan Shebs <shebs@apple.com>
Subject: Re: Link problems: restFP/saveFP and -lcc_dynamic -- why?
Date: Thu, 29 Jul 2004 23:53:47 +0100
Message-Id: <268C9EB6-E1B2-11D8-B2D6-000D93C1FC1C@astro.gla.ac.uk>
In-Reply-To: <4106A739.1070808@apple.com>
References: <Pine.LNX.4.58.0407271319070.26008@ptolemy>
  <4106A739.1070808@apple.com>

Martin and Stan,

> Norman Gray wrote:
>
>> Can anyone explain to me what the story is with the restFP/saveFP 
>> symbols

Thanks for your illumination here.

I think I now understand that this is not really a problem of mixing 
Fortran and C, but of mixing GCC versions (meaning GCC the compiler 
collection, rather than gcc the C compiler), and that it bites a 
variety of people from time to time because they are of necessity 
mixing the GCC that comes with OpenDarwin or Fink (`OD-or-F') with the 
system GCC.

In particular, the link errors come about when you produce an object 
file using a GCC which does generate the safeFP/restFP pairs (that is, 
using the current system gcc), and link it using a GCC which doesn't 
(that is, using the current OD-or-F g77).  Stan noted that this has 
been one of the differences between Apple and GNU GCC.  Is this all 
correct?

The problem still remains of how I or others can test for the problem.  
I've got an autoconf test which largely addresses this, and which I've 
included below.  It works by creating an object file which includes the 
symbol restFP (it's harder than it might seem to avoid looking for 
_restFP, of course...): if neither the C compiler nor the Fortran one 
can link this, or if both of them can, then there's nothing to do; if 
gcc can but g77 can't, then we know we have to add the system libgcc 
somehow; if g77 can but gcc can't, then we're bamboozled.

As Martin pointed out, linking with -lcc_dynamic does produce 
inconsistent results -- it can work on a simple case, but not in a more 
complicated case (though I'm afraid I still don't really understand 
why).

So, the solution does seem to be that "-L/usr/lib -lgcc" works in 
general, and the problem can be reliably tested for.  Any comments on 
the truth of this, on my understanding of the general principles, or on 
the robustness of the test below would be most gratefully received.





More generally, it would seem that there are two ways to completely 
avoid this problem (neither of them easy, unfortunately).  First would 
be if OpenDarwin or Fink g77 were distributed based on a GCC version 
matched with the system one for a particular OSX version; but even that 
might not work since (is this correct?) the system GCC is an Apple 
variant of GNU GCC.  Second would be if Apple included g77 in the 
system GCC (I can appreciate that there wouldn't be much call for this, 
but it still seems to me, surely naively, that it must be more effort 
to take g77 out than to keep it in!).  But back to the real world...

Phew.  Thanks again for insights -- I hope this message summarises 
things usefully.

All the best,

Norman







AC_CANONICAL_BUILD
AC_PROG_CC
AC_PROG_FC

# _STAR_RESTFP_FIX
# ----------------
# Determines if we need to make any library fixes to get things to link
# properly.  In fact, there's only a problem on OSX/Darwin, since the
# GCC installation which provides g77 and the (system) GCC which 
provides
# gcc can generate slightly incompatible object code.  The following 
test
# is therefore pretty specific to OSX/Darwin.
#
# If there are any libraries that need to be added to the path, this 
adds
# them to FCLIBS, in the same way that AC_FC_LIBRARY_LDFLAGS does.
#
# See the thread: 
http://lists.apple.com/mhonarc/fortran-dev/msg00768.html
AC_DEFUN([_STAR_RESTFP_FIX],
    [AC_CACHE_CHECK([whether we need any library fixups],
        [star_cv_restfp_fixup],
        [if expr $build_os : 'darwin7' >/dev/null; then
dnl Only affects OSX/Darwin
             if test "$GCC" = yes; then
dnl The problem only affects g77/gcc, so we know we're dealing with gcc 
below
                 AC_LANG_PUSH(C)
                 rm -f conftest*
                 star_cv_restfp_fixup=unknown
                 AC_LANG_CONFTEST(AC_LANG_PROGRAM([], restFP()))
                 { AC_TRY_COMMAND($CC -o conftest.x -S conftest.c)
                   test $ac_status = 0
                 } &&
                 sed 's/_restFP/restFP/g' conftest.x>conftest.s &&
                 { AC_TRY_COMMAND($CC -c -o conftest.$objext conftest.s)
                   test $ac_status = 0
                 } ||
                 star_cv_restfp_fixup=broken
                 AC_LANG_POP(C)
                 if test $star_cv_restfp_fixup = broken; then
                     AC_MSG_WARN([unable to assemble restFP test])
                 else
                     # Link this with the C compiler
                     AC_TRY_COMMAND($CC -o conftest conftest.$ac_object)
                     _s_cstatus=$ac_status
                     # Link this with the Fortran compiler
                     AC_TRY_COMMAND($FC -o conftest conftest.$ac_objext)
                     if test $_s_cstatus = 0 -a $ac_status = 0; then
                         # both compilers can compile it
                         star_cv_restfp_fixup=no
                     elif test $_s_cstatus != 0 -a $ac_status != 0; then
                         # neither compiler can compile it
                         star_cv_restfp_fixup=no
                     elif test $_s_cstatus = 0; then
                         # The C compiler can, but the Fortran cannot
                         star_cv_restfp_fixup=yes
                     else
                         # The C compiler can't compile, but the Fortran 
can.
                         # Haven't heard of this case!  Don't know what 
to do.
                         star_cv_restfp_fixup=broken
                     fi
                 fi
                 # Don't even try linking with -lcc_dynamic.  It may 
work, but
                 # will be unpredictable:
                 # 
http://lists.apple.com/mhonarc/fortran-dev/msg00769.html
                 if test $star_cv_restfp_fixup = yes; then
                     AC_TRY_COMMAND($FC -o conftest conftest.$objext 
-L/usr/lib -lgcc)
                     if test $ac_status = 0; then
                         star_cv_restfp_fixup=lgcc
                     fi
                 fi
                 if test $star_cv_restfp_fixup = yes; then
                     # ooops
                     AC_MSG_WARN([unable to solve restFP problem])
                     star_cv_restfp_fixup=broken
                 fi
                 rm -f conftest*
             else # !gcc
                 star_cv_restfp_fixup=no
             fi
         else # !Darwin
             star_cv_restfp_fixup=no
         fi
         ])
    # Define FCLIBS, just as AC_FC_LIBRARY_LDFLAGS does
    if test $star_cv_restfp_fixup = lgcc; then
        FCLIBS="$FCLIBS -L/usr/lib -lgcc"
    fi
    AC_SUBST(FCLIBS)
])

-- 
----------------------------------------------------------------------
Norman Gray  :  Physics & Astronomy, Glasgow University, UK
http://www.astro.gla.ac.uk/users/norman/  :  www.starlink.ac.uk
_______________________________________________
fortran-dev mailing list | fortran-dev@lists.apple.com
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/fortran-dev
Do not post admin requests to the list. They will be ignored.


