summaryrefslogtreecommitdiff
path: root/Modules/FortranCInterface.cmake
diff options
context:
space:
mode:
authorBill Hoffman <bill.hoffman@kitware.com>2008-10-27 15:23:14 -0400
committerBill Hoffman <bill.hoffman@kitware.com>2008-10-27 15:23:14 -0400
commit3a97e4699c577a940989af45266e21d57e0d5b4e (patch)
treece9af6312951af8c5d02364a98ce23a5e950c4d7 /Modules/FortranCInterface.cmake
parent1ed93e0a0ed5625f8edd68d57dbec0ab193b0d31 (diff)
downloadcmake-3a97e4699c577a940989af45266e21d57e0d5b4e.tar.gz
ENH: add fortran link discovery module
Diffstat (limited to 'Modules/FortranCInterface.cmake')
-rw-r--r--Modules/FortranCInterface.cmake135
1 files changed, 135 insertions, 0 deletions
diff --git a/Modules/FortranCInterface.cmake b/Modules/FortranCInterface.cmake
new file mode 100644
index 0000000000..9f86acb75d
--- /dev/null
+++ b/Modules/FortranCInterface.cmake
@@ -0,0 +1,135 @@
+# 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
+#
+#