[CMake] Fortran-C mixed code

Radu Serban radu at llnl.gov
Thu Jan 18 13:24:00 EST 2007


Alan W. Irwin wrote:
> On 2007-01-12 12:42-0800 Radu Serban wrote:
> 
>> I'm attempting to use cmake to configure a package containing both 
>> Fortran (F77) and C source code (as an alternative to the current 
>> build system which uses autoconf+libtool) but I couldn't figure out 
>> how to properly do that.
> 
> Have you considered splitting your library into a fortran-only library 
> and a
> C-only library?  Autotools tries to support mixing fortran- and C-compiled
> objects in the same library (using the AC_F77_LIBRARY_LDFLAGS macro and the
> resulting FLIBS), but we could never get that to work reliably on all
> platforms for PLplot.  Thus, we ended up splitting our libraries into
> fortran-only and C-only when we were still building with autotools, and we
> have continued that approach now we have migrated to cmake.  We didn't have
> to do anything special to get this approach to work. Just use the
> appropriate ADD_LIBRARY command for each library, and use
> TARGET_LINK_LIBRARIES to establish the dependencies between them, and the
> result seems to build fine on all platforms.
> 
> Alan

Hi Alan,

Splitting the library into two is unfortunately not applicable to my case (see 
below why).

In my initial post I had raised 3 issues (determining the F77 intrinsic and 
run-time libraries, using a C compiler to link an executable from an object 
created from a Fortran source and a C library, and determining the Fortran 
compiler's name mangling scheme).

The first two issues are relevant only if the C library is actually built using 
a C++ compiler. However, I realized that cmake will stop with an error if I set 
the environment variable CC to, say, g++ before invoking cmake on my project 
(#error "The CMAKE_C_COMPILER is set to a C++ compiler"). As such, I can always 
be sure that a C++ compiler will not be used to create the library from the C 
sources and using the Fortran compiler to link will work just fine (and the F77 
intrinsic and run-time libraries will not be needed).

But knowing the Fortran name mangling scheme is still crucial (if interested, 
see below why). For now I rely on the user to provide the case (lower or upper) 
and number of appended underscores (none, one, or two) which determine it. The 
defaults I provide (lower case with one underscore) is probably the most common 
one, but I'd be much happier if I could automatically determine it at 
configuration time... Any suggestions?

Finally, I'm now wondering why cmake will not allow using a C++ compiler on C 
sources. Sure, one must be careful in conditionally including the appropriate 
wrappers in the header files to allow C++ usage, but I don't see why cmake would 
absolutely forbid this. Issuing a warning may be appropriate, why an error? Am I 
missing anything?

--Radu

P.S. Here's why knowing the Fortran name mangling scheme is important for us.

We distribute a library (CVODE) for solving ordinary differential equations 
(ODE). CVODE is part of an entire suite of solvers, but that is irrelevant for 
this discussion. A user who wants to use CVODE to solve a given ODE problem must 
then provide both the main function and an additional function which defines the 
ODE right-hand side (the RHS function), i.e. the function f in y'=f(t,y). The 
user then links these two functions together with the CVODE library into their 
executable. Therefore, the following is a typical calling chain:
   user's C main  ->
   CVODE C library function cv_solve ->
   user's C RHS function f (of type CVRhsFn)

The solver is written all in C, so building the library with cmake is no 
problem. However, for Fortran users, i.e. users who want to provide the main and 
f functions as Fortran sources (the RHS function in this case must have the 
fixed name FCVFUN), we also provide an Fortran-C interface library. This second 
library, FCVODE, is also all written in C. The above calling chain now becomes:
   user's Fortran PROGRAM ->
   FCVODE C library function FCVSOLVE ->
   CVODE function cv_solve ->
   FCVODE C library function fcv_RhsWrapper (of type CVRhsFn; wrapper around 
FCVFUN) ->
   user's Fortran FCVFUN

For our library sources to work unmodified regardless of the Fortran compiler, 
the FCVODE library includes a configuration header files which defines function 
names based on the Fortran name mangling scheme. For example, if the scheme is 
lower case with one appended underscore, we have
#define FCV_SOLVE fcvsolve_
#define FCV_FUN fcvfun_
and I can use FCV_SOLVE to declare and define the user-callable FCVODE solver 
function while the implementation of the FCVODE library function fcv_RhsWrapper 
always calls FCV_FUN(...), etc.


More information about the CMake mailing list