[Cmake-commits] [cmake-commits] king committed FortranCInterface.cmake 1.14 1.15 FortranCInterface.h.in 1.1 NONE

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


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

Modified Files:
	FortranCInterface.cmake 
Removed Files:
	FortranCInterface.h.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.


Index: FortranCInterface.cmake
===================================================================
RCS file: /cvsroot/CMake/CMake/Modules/FortranCInterface.cmake,v
retrieving revision 1.14
retrieving revision 1.15
diff -C 2 -d -r1.14 -r1.15
*** FortranCInterface.cmake	31 Oct 2008 11:50:28 -0000	1.14
--- FortranCInterface.cmake	5 Aug 2009 17:40:28 -0000	1.15
***************
*** 1,231 ****
! # 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.
! #  discover_fortran_module_mangling - try different types of 
! #  fortran modle name mangling to find one that works
  #
  #
  #
! # this function tests a single fortran mangling.  
! # CODE - test code to try should define a subroutine called "sub"
! # PREFIX - string to put in front of sub
! # POSTFIX - string to put after sub
! # ISUPPER - if TRUE then sub will be called as SUB
! # DOC - string used in status checking Fortran ${DOC} linkage
! # SUB - the name of the SUB to call
! # RESULT place to store result TRUE if this linkage works, FALSE
! #        if not.
  #
! function(test_fortran_mangling CODE PREFIX ISUPPER POSTFIX DOC SUB RESULT)
!   if(ISUPPER)
!     string(TOUPPER "${SUB}" sub)
!   else(ISUPPER) 
!     string(TOLOWER "${SUB}" sub)
!   endif(ISUPPER)
!   set(FUNCTION "${PREFIX}${sub}${POSTFIX}")
!   # 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" "${CODE}"    )
!   message(STATUS "checking Fortran ${DOC} 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)
  
! # this function discovers the name mangling scheme used
! # for functions in a fortran module.  
! function(discover_fortran_module_mangling prefix suffix found)
!   set(CODE 
!     "
!       module test_interface
!       interface dummy
!          module procedure sub
!       end interface
!       contains
!         subroutine sub
!         end subroutine
!       end module test_interface
!     ")
!   set(worked FALSE)
!   foreach(interface 
!       "test_interface$" 
!       "TEST_INTERFACE_mp_" 
!       "_test_interface__" 
!       "__test_interface__" 
!       "__test_interface_NMOD_" 
!       "__test_interface_MOD_")
!     test_fortran_mangling("${CODE}" "${interface}"
!       ${FORTRAN_C_MANGLING_UPPERCASE} "" "module" "sub" worked)
!     if(worked)
!       # if this is the upper case module match then
!       # lower case it for the extraction of pre and post strings
!       if("${interface}" MATCHES "TEST_INTERFACE")
!         string(TOLOWER "${interface}" interface)
        endif()
!       string(REGEX REPLACE "(.*)test_interface(.*)" "\\1" pre "${interface}")
!       string(REGEX REPLACE "(.*)test_interface(.*)" "\\2" post "${interface}")
!       set(${prefix} "${pre}" PARENT_SCOPE)
!       set(${suffix} "${post}" PARENT_SCOPE)
!       set(${found} TRUE PARENT_SCOPE)
!       return()
!     endif(worked)
!   endforeach(interface)
!   if(NOT worked)
!     message(STATUS "Failed to find C binding to Fortran module functions.")
!     set(${prefix} "BROKEN_C_FORTRAN_MODULE_BINDING" PARENT_SCOPE)
!     set(${suffix} "BROKEN_C_FORTRAN_MODULE_BINDING" PARENT_SCOPE)
!     set(${found} FALSE PARENT_SCOPE)
!   endif(NOT worked)
! endfunction(discover_fortran_module_mangling)
  
  
! function(discover_fortran_mangling prefix isupper suffix extra_under_score
!     found )
!   set(CODE 
!     "
!       subroutine sub
!       end subroutine sub
!     ")
!   foreach(post "_" "")
!     foreach(isup FALSE TRUE)
!       foreach(pre "" "_" "__")
!         set(worked FALSE)
!         test_fortran_mangling("${CODE}" "${pre}" ${isup}
!           "${post}" "function" sub worked )
!         if(worked)
!           message(STATUS "found Fortran function linkage")
!           set(${isupper} "${isup}" PARENT_SCOPE)
!           set(${prefix} "${pre}" PARENT_SCOPE)
!           set(${suffix} "${post}" PARENT_SCOPE)
!           set(${found} TRUE PARENT_SCOPE)
!           set(CODE 
!             "
!       subroutine my_sub
!       end subroutine my_sub
!     ")
!           set(worked FALSE)
!           test_fortran_mangling("${CODE}" "${pre}" ${isup}
!             "${post}" "function with _ " my_sub worked )
!           if(worked)
!             set(${extra_under_score} FALSE PARENT_SCOPE)
!           else(worked)
!             test_fortran_mangling("${CODE}" "${pre}" ${isup}
!               "${post}_" "function with _ " my_sub worked )
!             if(worked)
!               set(${extra_under_score} TRUE PARENT_SCOPE)
!             endif(worked)
!           endif(worked)
!         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)
!     # find regular fortran function mangling
!     discover_fortran_mangling(prefix isupper suffix extra_under found)
!     if(NOT found)
!       message(SEND_ERROR "Could not find fortran c name mangling.")
!       return()
!     endif(NOT found)
!     # find fortran module function mangling
!     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_EXTRA_UNDERSCORE ${extra_under} CACHE INTERNAL 
!       "If a function has a _ in the name does the compiler append an extra _" )
!     set(FORTRAN_C_MANGLING_FOUND TRUE CACHE INTERNAL 
!       "Was fortran to c mangling found" )
!     set(prefix )
!     set(suffix )
!     set(found FALSE)
!     # only try this if the compiler is F90 compatible
!     if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
!       discover_fortran_module_mangling(prefix suffix found)
!     endif(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
!     if(found)
!       message(STATUS "found Fortran module linkage")
!     else(found)
!       message(STATUS "Failed to find Fortran module linkage")
!     endif(found)
!     set(FORTRAN_C_MODULE_PREFIX "${prefix}" CACHE INTERNAL
!       "PREFIX for Fortran to c name mangling")
!     set(FORTRAN_C_MODULE_SUFFIX "${suffix}" CACHE INTERNAL
!       "SUFFIX for Fortran to c name mangling")
!     set(FORTRAN_C_MODULE_MANGLING_FOUND ${found} CACHE INTERNAL
!       "Was for Fortran to c name mangling found for modules")
!   endif(NOT FORTRAN_C_MANGLING_FOUND)
!   foreach(f ${${FUNCTIONS}})
!     if(FORTRAN_C_MANGLING_UPPERCASE)
!       string(TOUPPER "${f}" fcase)
      else()
!       string(TOLOWER "${f}" fcase)
      endif()
!     if("${f}" MATCHES ":")
!       string(REGEX REPLACE "(.*):(.*)" "\\1" module "${f}")
!       string(REGEX REPLACE "(.*):(.*)" "\\2" function "${f}")
!       string(REGEX REPLACE "(.*):(.*)" "\\1" module_case "${fcase}")
!       string(REGEX REPLACE "(.*):(.*)" "\\2" function_case "${fcase}")
        set(HEADER_CONTENT "${HEADER_CONTENT}
! #define ${NAMESPACE}${module}_${function} ${FORTRAN_C_MODULE_PREFIX}${module_case}${FORTRAN_C_MODULE_SUFFIX}${function_case}
  ")
!     else("${f}" MATCHES ":")
!       set(function "${FORTRAN_C_PREFIX}${fcase}${FORTRAN_C_SUFFIX}")
!       if("${f}" MATCHES "_" AND FORTRAN_C_MANGLING_EXTRA_UNDERSCORE)
!         set(function "${function}_")
!       endif("${f}" MATCHES "_" AND FORTRAN_C_MANGLING_EXTRA_UNDERSCORE)
!       set(HEADER_CONTENT "${HEADER_CONTENT}
! #define ${NAMESPACE}${f} ${function}
  ")
!     endif("${f}" MATCHES ":")
    endforeach(f)
-   configure_file(
-     "${CMAKE_ROOT}/Modules/FortranCInterface.h.in"
-     ${HEADER} @ONLY)
-   message(STATUS "created ${HEADER}")
- endfunction()
  
--- 1,334 ----
! # - Fortran/C Interface Detection
! # This module automatically detects the API by which C and Fortran
! # languages interact.  Variables indicate if the mangling is found:
! #   FortranCInterface_GLOBAL_FOUND = Global subroutines and functions
! #   FortranCInterface_MODULE_FOUND = Module subroutines and functions
! #                                    (declared by "MODULE PROCEDURE")
! # A function is provided to generate a C header file containing macros
! # to mangle symbol names:
! #   FortranCInterface_HEADER(<file>
! #                            [MACRO_NAMESPACE <macro-ns>]
! #                            [SYMBOL_NAMESPACE <ns>]
! #                            [SYMBOLS [<module>:]<function> ...])
! # It generates in <file> definitions of the following macros:
! #   #define FortranCInterface_GLOBAL (name,NAME) ...
! #   #define FortranCInterface_GLOBAL_(name,NAME) ...
! #   #define FortranCInterface_MODULE (mod,name, MOD,NAME) ...
! #   #define FortranCInterface_MODULE_(mod,name, MOD,NAME) ...
! # These macros mangle four categories of Fortran symbols,
! # respectively:
! #   - Global symbols without '_': call mysub()
! #   - Global symbols with '_'   : call my_sub()
! #   - Module symbols without '_': use mymod; call mysub()
! #   - Module symbols with '_'   : use mymod; call my_sub()
! # If mangling for a category is not known, its macro is left undefined.
! # All macros require raw names in both lower case and upper case.
! # The MACRO_NAMESPACE option replaces the default "FortranCInterface_"
! # prefix with a given namespace "<macro-ns>".
  #
+ # The SYMBOLS option lists symbols to mangle automatically with C
+ # preprocessor definitions:
+ #   <function>          ==> #define <ns><function> ...
+ #   <module>:<function> ==> #define <ns><module>_<function> ...
+ # If the mangling for some symbol is not known then no preprocessor
+ # definition is created, and a warning is displayed.
+ # The SYMBOL_NAMESPACE option prefixes all preprocessor definitions
+ # generated by the SYMBOLS option with a given namespace "<ns>".
  #
+ # Example usage:
+ #   include(FortranCInterface)
+ #   FortranCInterface_HEADER(FC.h MACRO_NAMESPACE "FC_")
+ # This creates a "FC.h" header that defines mangling macros
+ # FC_GLOBAL(), FC_GLOBAL_(), FC_MODULE(), and FC_MODULE_().
  #
! # Example usage:
! #   include(FortranCInterface)
! #   FortranCInterface_HEADER(FCMangle.h
! #                            MACRO_NAMESPACE "FC_"
! #                            SYMBOL_NAMESPACE "FC_"
! #                            SYMBOLS mysub mymod:my_sub)
! # This creates a "FC.h" header that defines the same FC_*() mangling
! # macros as the previous example plus preprocessor symbols FC_mysub
! # and FC_mymod_my_sub.
  #
! # FortranCInterface is aware of possible GLOBAL and MODULE manglings
! # for many Fortran compilers, but it also provides an interface to
! # specify new possible manglings.  Set the variables
! #   FortranCInterface_GLOBAL_SYMBOLS
! #   FortranCInterface_MODULE_SYMBOLS
! # before including FortranCInterface to specify manglings of the
! # symbols "MySub", "My_Sub", "MyModule:MySub", and "My_Module:My_Sub".
! # For example, the code:
! #   set(FortranCInterface_GLOBAL_SYMBOLS mysub_ my_sub__ MYSUB_)
! #     #                                  ^^^^^  ^^^^^^   ^^^^^
! #   set(FortranCInterface_MODULE_SYMBOLS
! #       __mymodule_MOD_mysub __my_module_MOD_my_sub)
! #     #   ^^^^^^^^     ^^^^^   ^^^^^^^^^     ^^^^^^
! #   include(FortranCInterface)
! # tells FortranCInterface to try given GLOBAL and MODULE manglings.
! # (The carets point at raw symbol names for clarity in this example
! # but are not needed.)
! 
! #-----------------------------------------------------------------------------
! # Execute at most once in a project.
! if(FortranCInterface_SOURCE_DIR)
!   return()
! endif()
! 
! #-----------------------------------------------------------------------------
! # Set up an interface detection project.
! set(FortranCInterface_SOURCE_DIR ${CMAKE_ROOT}/Modules/FortranCInterface)
! set(FortranCInterface_BINARY_DIR ${CMAKE_BINARY_DIR}/CMakeFiles/FortranCInterface)
! configure_file(${FortranCInterface_SOURCE_DIR}/Input.cmake.in
!                ${FortranCInterface_BINARY_DIR}/Input.cmake @ONLY)
! 
! # Detect the Fortran/C interface on the first run or when the
! # configuration changes.
! if(${FortranCInterface_BINARY_DIR}/Input.cmake
!     IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
!     OR ${FortranCInterface_SOURCE_DIR}/Output.cmake.in
!     IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
!     OR ${FortranCInterface_SOURCE_DIR}/CMakeLists.txt
!     IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
!     OR ${CMAKE_CURRENT_LIST_FILE}
!     IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
      )
!   message(STATUS "Detecting Fortran/C Interface")
!   set(_result)
! 
!   # Build a sample project which reports symbols.
!   try_compile(FortranCInterface_COMPILED
!     ${FortranCInterface_BINARY_DIR}
!     ${FortranCInterface_SOURCE_DIR}
!     FortranCInterface
!     OUTPUT_VARIABLE FortranCInterface_OUTPUT)
!   set(FortranCInterface_COMPILED ${FortranCInterface_COMPILED})
!   unset(FortranCInterface_COMPILED CACHE)
! 
!   # Locate the sample project executable.
!   if(FortranCInterface_COMPILED)
!     find_program(FortranCInterface_EXE
!       NAMES FortranCInterface
!       PATHS ${FortranCInterface_BINARY_DIR} ${FortranCInterface_BINARY_DIR}/Debug
!       NO_DEFAULT_PATH
!       )
!     set(FortranCInterface_EXE ${FortranCInterface_EXE})
!     unset(FortranCInterface_EXE CACHE)
    else()
!     set(_result "Failed to compile")
!     set(FortranCInterface_EXE)
!     file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
!       "Fortran/C interface test project failed with the following output:\n"
!       "${FortranCInterface_OUTPUT}\n")
    endif()
  
!   # Load symbols from INFO:symbol[] strings in the executable.
!   set(FortranCInterface_SYMBOLS)
!   if(FortranCInterface_EXE)
!     file(STRINGS "${FortranCInterface_EXE}" _info_strings
!       LIMIT_COUNT 8 REGEX "INFO:[^[]*\\[")
!     foreach(info ${_info_strings})
!       if("${info}" MATCHES ".*INFO:symbol\\[([^]]*)\\].*")
!         string(REGEX REPLACE ".*INFO:symbol\\[([^]]*)\\].*" "\\1" symbol "${info}")
!         list(APPEND FortranCInterface_SYMBOLS ${symbol})
        endif()
!     endforeach()
!   elseif(NOT _result)
!     set(_result "Failed to load sample executable")
!   endif()
  
+   set(_case_mysub "LOWER")
+   set(_case_my_sub "LOWER")
+   set(_case_MYSUB "UPPER")
+   set(_case_MY_SUB "UPPER")
+   set(_global_regex  "^(_*)(mysub|MYSUB)([_$]*)$")
+   set(_global__regex "^(_*)(my_sub|MY_SUB)([_$]*)$")
+   set(_module_regex  "^(_*)(mymodule|MYMODULE)([A-Za-z_$]*)(mysub|MYSUB)([_$]*)$")
+   set(_module__regex "^(_*)(my_module|MY_MODULE)([A-Za-z_$]*)(my_sub|MY_SUB)([_$]*)$")
  
!   # Parse the symbol names.
!   foreach(symbol ${FortranCInterface_SYMBOLS})
!     foreach(form "" "_")
!       # Look for global symbols.
!       string(REGEX REPLACE "${_global_${form}regex}"
!                            "\\1;\\2;\\3" pieces "${symbol}")
!       list(LENGTH pieces len)
!       if(len EQUAL 3)
!         set(FortranCInterface_GLOBAL_${form}SYMBOL "${symbol}")
!         list(GET pieces 0 FortranCInterface_GLOBAL_${form}PREFIX)
!         list(GET pieces 1 name)
!         list(GET pieces 2 FortranCInterface_GLOBAL_${form}SUFFIX)
!         set(FortranCInterface_GLOBAL_${form}CASE "${_case_${name}}")
!       endif()
! 
!       # Look for module symbols.
!       string(REGEX REPLACE "${_module_${form}regex}"
!                            "\\1;\\2;\\3;\\4;\\5" pieces "${symbol}")
!       list(LENGTH pieces len)
!       if(len EQUAL 5)
!         set(FortranCInterface_MODULE_${form}SYMBOL "${symbol}")
!         list(GET pieces 0 FortranCInterface_MODULE_${form}PREFIX)
!         list(GET pieces 1 module)
!         list(GET pieces 2 FortranCInterface_MODULE_${form}MIDDLE)
!         list(GET pieces 3 name)
!         list(GET pieces 4 FortranCInterface_MODULE_${form}SUFFIX)
!         set(FortranCInterface_MODULE_${form}CASE "${_case_${name}}")
!       endif()
      endforeach()
    endforeach()
  
!   # Construct mangling macro definitions.
!   set(_name_LOWER "name")
!   set(_name_UPPER "NAME")
!   foreach(form "" "_")
!     if(FortranCInterface_GLOBAL_${form}SYMBOL)
!       if(FortranCInterface_GLOBAL_${form}PREFIX)
!         set(_prefix "${FortranCInterface_GLOBAL_${form}PREFIX}##")
!       else()
!         set(_prefix "")
!       endif()
!       if(FortranCInterface_GLOBAL_${form}SUFFIX)
!         set(_suffix "##${FortranCInterface_GLOBAL_${form}SUFFIX}")
!       else()
!         set(_suffix "")
!       endif()
!       set(_name "${_name_${FortranCInterface_GLOBAL_${form}CASE}}")
!       set(FortranCInterface_GLOBAL${form}_MACRO
!         "(name,NAME) ${_prefix}${_name}${_suffix}")
!     endif()
!     if(FortranCInterface_MODULE_${form}SYMBOL)
!       if(FortranCInterface_MODULE_${form}PREFIX)
!         set(_prefix "${FortranCInterface_MODULE_${form}PREFIX}##")
!       else()
!         set(_prefix "")
!       endif()
!       if(FortranCInterface_MODULE_${form}SUFFIX)
!         set(_suffix "##${FortranCInterface_MODULE_${form}SUFFIX}")
!       else()
!         set(_suffix "")
!       endif()
!       set(_name "${_name_${FortranCInterface_MODULE_${form}CASE}}")
!       set(_middle "##${FortranCInterface_MODULE_${form}MIDDLE}##")
!       set(FortranCInterface_MODULE${form}_MACRO
!         "(mod_name,name, mod_NAME,NAME) ${_prefix}mod_${_name}${_middle}${_name}${_suffix}")
!     endif()
!   endforeach()
! 
!   # Summarize what is available.
!   foreach(scope GLOBAL MODULE)
!     if(FortranCInterface_${scope}_SYMBOL AND
!         FortranCInterface_${scope}__SYMBOL)
!       set(FortranCInterface_${scope}_FOUND 1)
      else()
!       set(FortranCInterface_${scope}_FOUND 0)
      endif()
!   endforeach()
! 
!   # Record the detection results.
!   configure_file(${FortranCInterface_SOURCE_DIR}/Output.cmake.in
!                  ${FortranCInterface_BINARY_DIR}/Output.cmake @ONLY)
!   file(APPEND ${FortranCInterface_BINARY_DIR}/Output.cmake "\n")
! 
!   # Report the results.
!   if(FortranCInterface_GLOBAL_FOUND)
!     if(FortranCInterface_MODULE_FOUND)
!       set(_result "Found GLOBAL and MODULE mangling")
!     else(FortranCInterface_MODULE_FOUND)
!       set(_result "Found GLOBAL but not MODULE mangling")
!     endif()
!   elseif(NOT _result)
!     set(_result "Failed to recognize symbols")
!   endif()
!   message(STATUS "Detecting Fortran/C Interface - ${_result}")
! endif()
! 
! # Load the detection results.
! include(${FortranCInterface_BINARY_DIR}/Output.cmake)
! 
! #-----------------------------------------------------------------------------
! function(FortranCInterface_HEADER file)
!   # Parse arguments.
!   if(IS_ABSOLUTE "${file}")
!     set(FILE "${file}")
!   else()
!     set(FILE "${CMAKE_CURRENT_BINARY_DIR}/${file}")
!   endif()
!   set(MACRO_NAMESPACE "FortranCInterface_")
!   set(SYMBOL_NAMESPACE)
!   set(SYMBOLS)
!   set(doing)
!   foreach(arg ${ARGN})
!     if("x${arg}" MATCHES "^x(SYMBOLS|SYMBOL_NAMESPACE|MACRO_NAMESPACE)$")
!       set(doing "${arg}")
!     elseif("x${doing}" MATCHES "^x(SYMBOLS)$")
!       list(APPEND "${doing}" "${arg}")
!     elseif("x${doing}" MATCHES "^x(SYMBOL_NAMESPACE|MACRO_NAMESPACE)$")
!       set("${doing}" "${arg}")
!       set(doing)
!     else()
!       message(AUTHOR_WARNING "Unknown argument: \"${arg}\"")
!     endif()
!   endforeach()
! 
!   # Generate macro definitions.
!   set(HEADER_CONTENT)
!   set(_desc_GLOBAL  "/* Mangling for Fortran global symbols without underscores. */")
!   set(_desc_GLOBAL_ "/* Mangling for Fortran global symbols with underscores. */")
!   set(_desc_MODULE  "/* Mangling for Fortran module symbols without underscores. */")
!   set(_desc_MODULE_ "/* Mangling for Fortran module symbols with underscores. */")
!   foreach(macro GLOBAL GLOBAL_ MODULE MODULE_)
!     if(FortranCInterface_${macro}_MACRO)
        set(HEADER_CONTENT "${HEADER_CONTENT}
! ${_desc_${macro}}
! #define ${MACRO_NAMESPACE}${macro}${FortranCInterface_${macro}_MACRO}
  ")
!     endif()
!   endforeach()
! 
!   # Generate symbol mangling definitions.
!   if(SYMBOLS)
!     set(HEADER_CONTENT "${HEADER_CONTENT}
! /*--------------------------------------------------------------------------*/
! /* Mangle some symbols automatically.                                       */
  ")
!   endif()
!   foreach(f ${SYMBOLS})
!     if("${f}" MATCHES ":")
!       # Module symbol name.  Parse "<module>:<function>" syntax.
!       string(REPLACE ":" ";" pieces "${f}")
!       list(GET pieces 0 module)
!       list(GET pieces 1 function)
!       string(TOUPPER "${module}" m_upper)
!       string(TOLOWER "${module}" m_lower)
!       string(TOUPPER "${function}" f_upper)
!       string(TOLOWER "${function}" f_lower)
!       if("${function}" MATCHES "_")
!         set(form "_")
!       else()
!         set(form "")
!       endif()
!       if(FortranCInterface_MODULE${form}_MACRO)
!         set(HEADER_CONTENT "${HEADER_CONTENT}#define ${SYMBOL_NAMESPACE}${module}_${function} ${MACRO_NAMESPACE}MODULE${form}(${m_lower},${f_lower}, ${m_upper},${f_upper})\n")
!       else()
!         message(AUTHOR_WARNING "No FortranCInterface mangling known for ${f}")
!       endif()
!     else()
!       # Global symbol name.
!       if("${f}" MATCHES "_")
!         set(form "_")
!       else()
!         set(form "")
!       endif()
!       string(TOUPPER "${f}" f_upper)
!       string(TOLOWER "${f}" f_lower)
!       if(FortranCInterface_GLOBAL${form}_MACRO)
!         set(HEADER_CONTENT "${HEADER_CONTENT}#define ${SYMBOL_NAMESPACE}${f} ${MACRO_NAMESPACE}GLOBAL${form}(${f_lower}, ${f_upper})\n")
!       else()
!         message(AUTHOR_WARNING "No FortranCInterface mangling known for ${f}")
!       endif()
!     endif()
    endforeach(f)
  
+   # Store the content.
+   configure_file(${FortranCInterface_SOURCE_DIR}/Macro.h.in ${FILE} @ONLY)
+ endfunction()

--- FortranCInterface.h.in DELETED ---



More information about the Cmake-commits mailing list