[Cmake-commits] [cmake-commits] hoffman committed FortranCInterface.cmake NONE 1.1 FortranCInterface.h.in NONE 1.1

cmake-commits at cmake.org cmake-commits at cmake.org
Mon Oct 27 15:23:16 EDT 2008


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

Added Files:
	FortranCInterface.cmake FortranCInterface.h.in 
Log Message:
ENH: add fortran link discovery module


--- NEW FILE: FortranCInterface.cmake ---
# FortranCInterface.cmake
#
# This file defines the function create_fortran_c_interface.
# this function is used to create a configured header file 
# that contains a mapping from C to a Fortran function using
# the correct name mangling scheme as defined by the current 
# fortran compiler.  
#
# The function tages a list of functions and the name of 
# a header file to configure.  
#
# This file also defines some helper functions that are used
# to detect the fortran name mangling scheme used by the 
# current Fortran compiler.
#  test_fortran_mangling - test a single fortran mangling 
#  discover_fortran_mangling - loop over all combos of fortran
#   name mangling and call test_fortran_mangling until one of them
#   works.
#

function(test_fortran_mangling PREFIX ISUPPER POSTFIX RESULT)
  if(ISUPPER)
    set(FUNCTION "${PREFIX}SUB${POSTFIX}")
  else(ISUPPER)
    set(FUNCTION "${PREFIX}sub${POSTFIX}")
  endif(ISUPPER)
  # create a fortran file with sub called sub
  # 
  set(TMP_DIR
    "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckFortranLink")
  file(REMOVE_RECURSE "${TMP_DIR}")
  file(WRITE "${TMP_DIR}/test.f"
    "
      subroutine sub
      end subroutine sub
    "
    )
  message(STATUS "checking Fortran linkage: ${FUNCTION}")
  file(WRITE "${TMP_DIR}/ctof.c"
    "
      extern ${FUNCTION}();
      int main() { ${FUNCTION}(); return 0;}
    "
    )
  file(WRITE "${TMP_DIR}/CMakeLists.txt"
    "
     project(testf C Fortran)
     add_library(flib test.f)
     add_executable(ctof ctof.c)
     target_link_libraries(ctof flib)
    "
    )
  set(FORTRAN_NAME_MANGLE_TEST FALSE)
  try_compile(FORTRAN_NAME_MANGLE_TEST "${TMP_DIR}" "${TMP_DIR}"
    testf
    OUTPUT_VARIABLE output)
  if(FORTRAN_NAME_MANGLE_TEST)
    set(${RESULT} TRUE PARENT_SCOPE)
  else()
    set(${RESULT} FALSE PARENT_SCOPE)
  endif()
endfunction(test_fortran_mangling)

function(discover_fortran_mangling prefix isupper suffix found )
  foreach(pre "_" "" "__")
    foreach(isup TRUE FALSE)
      foreach(post "" "_")
        set(worked FALSE)
        test_fortran_mangling("${pre}" ${isup} "${post}" worked )
        if(worked)
          message(STATUS "found Fotran linkage")
          set(${isupper} "${isup}" PARENT_SCOPE)
          set(${prefix} "${pre}" PARENT_SCOPE)
          set(${suffix} "${post}" PARENT_SCOPE)
          set(${found} TRUE PARENT_SCOPE)
          return()
        endif()
      endforeach()
    endforeach()
  endforeach()
  set(${found} FALSE PARENT_SCOPE)
endfunction(discover_fortran_mangling)

function(create_fortran_c_interface NAMESPACE FUNCTIONS HEADER)
  if(NOT FORTRAN_C_MANGLING_FOUND)
    discover_fortran_mangling(prefix isupper suffix found)
    if(NOT found)
      message(SEND_ERROR "Could not find fortran c name mangling.")
      return()
    endif(NOT found)
    set(FORTRAN_C_PREFIX "${prefix}" CACHE INTERNAL
      "PREFIX for Fortran to c name mangling")
    set(FORTRAN_C_SUFFIX "${suffix}" CACHE INTERNAL
      "SUFFIX for Fortran to c name mangling")
    set(FORTRAN_C_MANGLING_UPPERCASE ${isupper} CACHE INTERNAL 
      "Was fortran to c mangling found" )
    set(FORTRAN_C_MANGLING_FOUND TRUE CACHE INTERNAL 
      "Was fortran to c mangling found" )
  endif(NOT FORTRAN_C_MANGLING_FOUND)
  foreach(f ${${FUNCTIONS}})
    if(${FORTRAN_C_MANGLING_UPPERCASE})
      string(TOUPPER "${f}" ff)
    else()
      string(TOLOWER "${f}" ff)
    endif()
    set(function "${FORTRAN_C_PREFIX}${ff}${FORTRAN_C_SUFFIX}")
    set(HEADER_CONTENT "${HEADER_CONTENT}
#define ${NAMESPACE}${f} ${function}
")
  endforeach(f)
  configure_file(
    "${CMAKE_ROOT}/Modules/FortranCInterface.h.in"
    ${HEADER} @ONLY)
  message(STATUS "created ${HEADER}")
endfunction()

#  TODO
# need to add support for module linking
# module test_interface
#
#    interface dummy
#        module procedure module_function
#    end interface
#
# contains
#
#    subroutine module_function
#    end subroutine
#
# end module test_interface
#
# produces this:
# __test_interface_MOD_module_function
#
# 

--- NEW FILE: FortranCInterface.h.in ---
/* This file is automatically generated by CMake, DO NOT EDIT.
   It contains a mapping from Fortran functions so they can 
   be called from C or C++.   */


@HEADER_CONTENT@






More information about the Cmake-commits mailing list