[CMake] Fortan and C++

Michael Wild themiwi at gmail.com
Sat Aug 22 10:33:16 EDT 2009


On 22. Aug, 2009, at 15:29, Dominik Szczerba wrote:
[...]
>> If you try to use FortranCInterface.cmake, be aware that it is  
>> quite  buggy, as it doesn't pass the CMAKE_*_FLAGS to the  
>> try_compile calls.  Further it doesn't ensure that the C language  
>> is enabled, altough it  is calling try_compile on C code! I'll file  
>> a bug report with an  attached patch for that.
>
> This is new to me. Sounds like automatic handling of calling  
> decorations. Would be great! Are there any examples how to use it?  
> Do I still need it when I know the mangling scheme myself? Can I set  
> the pre/suffixes myself in some elegant manner? Currently I am just  
> hacking on my own, so indications how to position myself for the  
> future are very welcome.
>
> Thanks,
> Dominik
[...]

Exactly. It first tries to figure out the name-mangling scheme used by  
your Fortran compiler. I think it tries to prepend/append _ up to two  
times and also tries lower/upper case variations. For names containing  
a _, it also detects whether the compiler appends an additional _  
charachter. Then it creates a header file containing preprocessor  
defines, mapping the "names as written" to the mangled names.

This would be all great and nice, if it wasn't buggy... *sigh*

With reference to the future: the Intel compiler supports the  
iso_c_binding intrinsic module defined for Fortran 2003, allowing one  
to do something like this:

-- >8 --

! Fortran native function
real function super_duper(a)
   implicit none
   real, intent(in) :: a
   super_duper = a**2
end function super_duper

! C-wrapper function
real(c_float) function c_super_duper(a) bind(c)
   use, intrinsic :: iso_c_binding
   implicit none
   real (c_float), intent(in), value :: a
   real, external :: super_duper
   c_super_duper = super_duper(a)
end function c_super_duper

-- <8 --

And then in your C++ file you write:

-- >8 --

#include <iostream>

extern "C" {
   float c_super_duper(float);
}

int main() {
   std::cout << "super_duper(10) = " << c_super_duper(10.0) << "\n";
   return 0;
}

-- <8 --

It is very verbose and also a bit confusing, but it takes care of all  
the name-mangling issues and also does the type-handling correctly. As  
you can see, the argument is passed by value by adding the VALUE  
attribute in the wrapper function.

Michael


More information about the CMake mailing list