[Cmake-commits] [cmake-commits] king committed CMakeLists.txt NONE 1.1 Input.cmake.in NONE 1.1 Macro.h.in NONE 1.1 Output.cmake.in NONE 1.1 call_mod.f90 NONE 1.1 call_sub.f NONE 1.1 main.F NONE 1.1 my_module.f90 NONE 1.1 my_sub.f NONE 1.1 mymodule.f90 NONE 1.1 mysub.f NONE 1.1 symbol.c.in NONE 1.1

cmake-commits at cmake.org cmake-commits at cmake.org
Wed Aug 5 13:40:31 EDT 2009


Update of /cvsroot/CMake/CMake/Modules/FortranCInterface
In directory public:/mounts/ram/cvs-serv17401/Modules/FortranCInterface

Added Files:
	CMakeLists.txt Input.cmake.in Macro.h.in Output.cmake.in 
	call_mod.f90 call_sub.f main.F my_module.f90 my_sub.f 
	mymodule.f90 mysub.f symbol.c.in 
Log Message:
Rewrite FortranCInterface module

This is a new FortranCInterface.cmake module to replace the previous
prototype.  All module support files lie in a FortranCInterface
directory next to it.

This module uses a new approach to detect Fortran symbol mangling.  We
build a single test project which defines symbols in a Fortran library
(one per object-file) and calls them from a Fortran executable.  The
executable links to a C library which defines symbols encoding all known
manglings (one per object-file).  The C library falls back to the
Fortran library for symbols it cannot provide.  Therefore the executable
will always link, but prefers the C-implemented symbols when they match.
These symbols store string literals of the form INFO:symbol[<name>] so
we can parse them out of the executable.

This module also provides a simpler interface.  It always detects the
mangling as soon as it is included.  A single macro is provided to
generate mangling macros and optionally pre-mangled symbols.


--- NEW FILE: CMakeLists.txt ---
cmake_minimum_required(VERSION 2.6.3)
project(FortranCInterface C Fortran)
include(${FortranCInterface_BINARY_DIR}/Input.cmake OPTIONAL)

# Check if the C compiler supports '$' in identifiers.
include(CheckCSourceCompiles)
check_c_source_compiles("
extern int dollar$(void);
int main() { return 0; }
" C_SUPPORTS_DOLLAR)

# List manglings of global symbol names to try.
set(global_symbols
  my_sub_   # GNU, Intel, HP, SunPro, MIPSpro
  my_sub    # VisualAge
  mysub_    # GNU, Intel, HP, SunPro, MIPSpro
  mysub     # VisualAge
  ${FortranCInterface_GLOBAL_SYMBOLS}
  )
list(REMOVE_DUPLICATES global_symbols)

# List manglings of module symbol names to try.
set(module_symbols
  __my_module_MOD_my_sub  # GNU
  __my_module_NMOD_my_sub # VisualAge
  __mymodule_MOD_mysub    # GNU
  __mymodule_NMOD_mysub   # VisualAge
  my_module$my_sub        # HP
  my_module_mp_my_sub_    # Intel
  mymodule$mysub          # HP
  mymodule_mp_mysub_      # Intel
  ${FortranCInterface_MODULE_SYMBOLS}
  )
list(REMOVE_DUPLICATES module_symbols)

# Note that some compiler manglings cannot be invoked from C:
#   MIPSpro uses "MY_SUB.in.MY_MODULE"
#   SunPro uses "my_module.my_sub_"

# Add module symbols only with Fortran90.
if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
  set(myfort_modules mymodule.f90 my_module.f90)
  set(call_mod call_mod.f90)
  set_property(SOURCE main.F PROPERTY COMPILE_DEFINITIONS CALL_MOD)
else()
  set(module_symbols)
endif()

# Generate C symbol sources.
foreach(symbol IN LISTS global_symbols module_symbols)
  # Skip symbols with '$' if C cannot handle them.
  if(C_SUPPORTS_DOLLAR OR NOT "${symbol}" MATCHES "\\$")
    if("${symbol}" MATCHES "SUB")
      set(upper "-UPPER")
    else()
      set(upper)
    endif()
    string(REPLACE "$" "S" name "${symbol}")
    set(source ${CMAKE_CURRENT_BINARY_DIR}/symbols/${name}${upper}.c)
    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/symbol.c.in ${source} @ONLY)
    list(APPEND symbol_sources ${source})
  endif()
endforeach()

# Provide symbols through Fortran.
add_library(myfort STATIC mysub.f my_sub.f ${myfort_modules})

# Provide symbols through C but fall back to Fortran.
add_library(symbols STATIC ${symbol_sources})
target_link_libraries(symbols myfort)

# Require symbols through Fortran.
add_executable(FortranCInterface main.F call_sub.f ${call_mod})
target_link_libraries(FortranCInterface symbols)

--- NEW FILE: mysub.f ---
      subroutine mysub
      end

--- NEW FILE: mymodule.f90 ---
module mymodule
  interface myinterface
     module procedure mysub
  end interface
contains
  subroutine mysub
  end subroutine mysub
end module mymodule

--- NEW FILE: Input.cmake.in ---
set(CMAKE_Fortran_COMPILER_ID "@CMAKE_Fortran_COMPILER_ID@")
set(FortranCInterface_GLOBAL_SYMBOLS "@FortranCInterface_GLOBAL_SYMBOLS@")
set(FortranCInterface_MODULE_SYMBOLS "@FortranCInterface_MODULE_SYMBOLS@")

--- NEW FILE: my_sub.f ---
      subroutine my_sub
      end

--- NEW FILE: call_mod.f90 ---
subroutine call_mod
  use mymodule
  use my_module
  call mysub()
  call my_sub()
end subroutine call_mod

--- NEW FILE: Macro.h.in ---
#ifndef @MACRO_NAMESPACE at HEADER_INCLUDED
#define @MACRO_NAMESPACE at HEADER_INCLUDED
@HEADER_CONTENT@
#endif

--- NEW FILE: symbol.c.in ---
const char* @symbol@(void)
{
  return "INFO:symbol[@symbol@]";
}

--- NEW FILE: Output.cmake.in ---
# Global symbol without underscore.
set(FortranCInterface_GLOBAL_SYMBOL  "@FortranCInterface_GLOBAL_SYMBOL@")
set(FortranCInterface_GLOBAL_PREFIX  "@FortranCInterface_GLOBAL_PREFIX@")
set(FortranCInterface_GLOBAL_SUFFIX  "@FortranCInterface_GLOBAL_SUFFIX@")
set(FortranCInterface_GLOBAL_CASE    "@FortranCInterface_GLOBAL_CASE@")
set(FortranCInterface_GLOBAL_MACRO   "@FortranCInterface_GLOBAL_MACRO@")

# Global symbol with underscore.
set(FortranCInterface_GLOBAL__SYMBOL "@FortranCInterface_GLOBAL__SYMBOL@")
set(FortranCInterface_GLOBAL__PREFIX "@FortranCInterface_GLOBAL__PREFIX@")
set(FortranCInterface_GLOBAL__SUFFIX "@FortranCInterface_GLOBAL__SUFFIX@")
set(FortranCInterface_GLOBAL__CASE   "@FortranCInterface_GLOBAL__CASE@")
set(FortranCInterface_GLOBAL__MACRO  "@FortranCInterface_GLOBAL__MACRO@")

# Module symbol without underscore.
set(FortranCInterface_MODULE_SYMBOL  "@FortranCInterface_MODULE_SYMBOL@")
set(FortranCInterface_MODULE_PREFIX  "@FortranCInterface_MODULE_PREFIX@")
set(FortranCInterface_MODULE_MIDDLE  "@FortranCInterface_MODULE_MIDDLE@")
set(FortranCInterface_MODULE_SUFFIX  "@FortranCInterface_MODULE_SUFFIX@")
set(FortranCInterface_MODULE_CASE    "@FortranCInterface_MODULE_CASE@")
set(FortranCInterface_MODULE_MACRO   "@FortranCInterface_MODULE_MACRO@")

# Module symbol with underscore.
set(FortranCInterface_MODULE__SYMBOL "@FortranCInterface_MODULE__SYMBOL@")
set(FortranCInterface_MODULE__PREFIX "@FortranCInterface_MODULE__PREFIX@")
set(FortranCInterface_MODULE__MIDDLE "@FortranCInterface_MODULE__MIDDLE@")
set(FortranCInterface_MODULE__SUFFIX "@FortranCInterface_MODULE__SUFFIX@")
set(FortranCInterface_MODULE__CASE   "@FortranCInterface_MODULE__CASE@")
set(FortranCInterface_MODULE__MACRO  "@FortranCInterface_MODULE__MACRO@")

# Summarize what was found.
set(FortranCInterface_GLOBAL_FOUND @FortranCInterface_GLOBAL_FOUND@)
set(FortranCInterface_MODULE_FOUND @FortranCInterface_MODULE_FOUND@)

--- NEW FILE: main.F ---
        program main
          call call_sub()
#ifdef CALL_MOD
          call call_mod()
#endif
        end

--- NEW FILE: my_module.f90 ---
module my_module
  interface my_interface
     module procedure my_sub
  end interface
contains
  subroutine my_sub
  end subroutine my_sub
end module my_module

--- NEW FILE: call_sub.f ---
        subroutine call_sub
          call mysub()
          call my_sub()
        end



More information about the Cmake-commits mailing list