Developers using both Fortran and C on OSX platforms often
experience linking problems, referring to undefined symbols
restFP
and saveFP
. There are
numerous incomplete explanations of this problem on the web,
along with various rather voodoo solutions. This page
summarises a short discussion on
fortran-dev@lists.apple.com
, explaining the
problem, and indicating and explaining the reasonably robust
solutions which exist.
Comments and updates are appreciated
Persistent URL: http://purl.org/nxg/note/restfp
People using Fortran on OSX have a problem, since although
Apple provides a variant of the GNU compiler collection, GCC, as
the system compiler, they do not supply the Fortran front-end to
this, g77
. That can be obtained from either the
DarwinPorts or
Fink projects.
However the problems do not end there.
The DarwinPorts and Fink g77
builds use the Free
Software Foundation (FSF) GCC, while the Apple compilers use a
GCC variant with OSX-specific modifications which have not, or
not yet, been integrated with the FSF mainline. That means that
the GCC back-ends -- that is, the parts which generate the
object code which is linked to make libraries and executables --
produce object code which is slightly different, sometimes to
the point of being incompatible. This incompatibility is a
problem if and only if you are using both back-ends,
that is, if you are mixing Fortran (from FSF g77
)
with code produced by Apple GCC.
In particular, the Apple GCC produces object code which
includes references to the restFP
and
saveFP
symbols, which refer to assembler routines
which manipulate the floating-point state of the processor. The
FSF GCC (that is, g77
) does not produce these
references, and as a result, when you link together your Fortran
and C code using the Fortran compiler (as you must, in order to
pick up the Fortran runtime support), the Fortran linker cannot
find definitions of these symbols, and the link fails, with an
error which looks like this:
----------------------------------------------------------------------- /tmp/gcc/bin/gcc -g -O2 -o prog prog.o <blah blah blah> /usr/bin/ld: Undefined symbols: restFP saveFP -----------------------------------------------------------------------
So what can you do about this? The answer depends on what OS X version you have.
The restFP
and saveFP
functions are
defined in Apple's libgcc
, and so the
fix is simply to include this library in your link line. The
best way of doing this is to include the option
-lcc_dynamic
at the end of your link line (it has to come at the
end, so that it comes after the modules which create the
references to the restFP
and saveFP
symbols). You might be able
to include that at the time you are configuring your software,
with a command like:
% env LDFLAGS=-lcc_dynamic ./configure
or there may be some other way of configuring extra link flags in the build -- see the distribution's documentation for details.
This works because the only
cc_dynamic
library on the system (namely
/usr/lib/libcc_dynamic.a
) is a symlink to the
libgcc.a
static library appropriate to the Apple
GCC. See Martin Costabel's message below
for further discussion of this.
You must avoid including this library if your link line already
includes -lgcc
: that will pull in the dynamic
libgcc
with inconsistent results.
In a thread on the unix-porting
list, Martin Costabel remarks that gfortran
should just work, as it knows where to find the missing
libraries, and that the Fink g95
has been similarly
clued-in (though a built-from-source g95
might
not).
Later in the same thread, Bill Northcott notes that g77
has to be
matched with gcc 3.3
, and gfortran
with gcc4
(the compiler version is adjustable with
the command gcc_select
).
The following is an autoconf macro which addresses this
problem. If it detects it is running on OSX/Darwin, it checks
that a fix is required, and adds the string
-lcc_dynamic
to the two substitution variables
C_FC_FCLINK_MAGIC
and
C_FC_PPFC_FCLINK_MAGIC
. This is useful behaviour
in the context in which I developed it -- hack to your heart's
content. Comments on the robustness and autoconf style of
this are welcome.
This macro has been tested on 10.3; who knows what would happen on 10.4
The OS X 10.3 information on this page is a summary of
explanations provided by Stan Shebs
and Martin Costabel, after a query by me on
fortran-dev@lists.apple.com
. The original
mail messages are below, archived locally and at
lists.apple.com
:
Initial query | local | apple.com |
Martin Costabel | local | apple.com |
Stan Shebs | local | apple.com |
Note that the last message in that thread (from me:
local,
apple.com), in seeming to recommend
-L/usr/lib -lgcc
as the best solution, is rather a
misunderstanding of Martin Costabel's message (blush). Also
the autoconf test included in there has some flaws, fixed in
the version above.
All the details are in the ld
man page, though
rather painfully compressed.
For fuller documentation on the OSX linker and its model,
which is more discursive than the ld
man page,
see Apple's Introduction to Mach-O Runtime Architecture.
Thanks to Russell Edwards at CSIRO for comments.
$Log: index.xml,v $ Revision 1.12 2007/03/10 12:37:36 norman Explain why the -lcc_dynamic has to come at the end (more use than simply stating it...) Revision 1.11 2007/03/10 12:30:48 norman Note that the -lcc_dynamic option must come at the end of the link line Revision 1.10 2006/11/29 21:15:06 norman Break the autoconf macro into a separate file Revision 1.9 2006/11/29 20:57:50 norman Mild updates for 10.4 Revision 1.8 2006/05/26 14:00:21 norman Remove DOCTYPE... references. Not useful, and requires that xhtml1 DTDs be present, which is a useless fuss. Revision 1.7 2006/04/03 15:14:50 norman Add RDF info Revision 1.6 2005/04/02 15:10:02 norman Add pointers to fuller documentation on the OS X linker and linking model. Revision 1.5 2004/12/09 11:17:22 norman There's always one last typo, isn't there. Revision 1.4 2004/12/09 10:53:49 norman Rewordings Add the (corrected) autoconf test De-emphasised my last message in the thread -- it's a poor summary of Martin's and Stan's comments