diff options
Diffstat (limited to 'Modules/FortranCInterface.cmake')
-rw-r--r-- | Modules/FortranCInterface.cmake | 301 |
1 files changed, 198 insertions, 103 deletions
diff --git a/Modules/FortranCInterface.cmake b/Modules/FortranCInterface.cmake index c59e1f839..893a96fb5 100644 --- a/Modules/FortranCInterface.cmake +++ b/Modules/FortranCInterface.cmake @@ -1,98 +1,193 @@ -# - 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 "FCMangle.h" header that defines the same FC_*() -# mangling macros as the previous example plus preprocessor symbols -# FC_mysub and FC_mymod_my_sub. -# -# Another function is provided to verify that the Fortran and C/C++ -# compilers work together: -# FortranCInterface_VERIFY([CXX] [QUIET]) -# It tests whether a simple test executable using Fortran and C (and -# C++ when the CXX option is given) compiles and links successfully. -# The result is stored in the cache entry FortranCInterface_VERIFIED_C -# (or FortranCInterface_VERIFIED_CXX if CXX is given) as a boolean. -# If the check fails and QUIET is not given the function terminates -# with a FATAL_ERROR message describing the problem. The purpose of -# this check is to stop a build early for incompatible compiler -# combinations. The test is built in the Release configuration. -# -# 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.) - -#============================================================================= -# Copyright 2008-2009 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FortranCInterface +----------------- + +Fortran/C Interface Detection + +This module automatically detects the API by which C and Fortran +languages interact. + +Module Variables +^^^^^^^^^^^^^^^^ + +Variables that indicate if the mangling is found: + +``FortranCInterface_GLOBAL_FOUND`` + Global subroutines and functions. + +``FortranCInterface_MODULE_FOUND`` + Module subroutines and functions (declared by "MODULE PROCEDURE"). + +This module also provides the following variables to specify +the detected mangling, though a typical use case does not need +to reference them and can use the `Module Functions`_ below. + +``FortranCInterface_GLOBAL_PREFIX`` + Prefix for a global symbol without an underscore. + +``FortranCInterface_GLOBAL_SUFFIX`` + Suffix for a global symbol without an underscore. + +``FortranCInterface_GLOBAL_CASE`` + The case for a global symbol without an underscore, + either ``UPPER`` or ``LOWER``. + +``FortranCInterface_GLOBAL__PREFIX`` + Prefix for a global symbol with an underscore. + +``FortranCInterface_GLOBAL__SUFFIX`` + Suffix for a global symbol with an underscore. + +``FortranCInterface_GLOBAL__CASE`` + The case for a global symbol with an underscore, + either ``UPPER`` or ``LOWER``. + +``FortranCInterface_MODULE_PREFIX`` + Prefix for a module symbol without an underscore. + +``FortranCInterface_MODULE_MIDDLE`` + Middle of a module symbol without an underscore that appears + between the name of the module and the name of the symbol. + +``FortranCInterface_MODULE_SUFFIX`` + Suffix for a module symbol without an underscore. + +``FortranCInterface_MODULE_CASE`` + The case for a module symbol without an underscore, + either ``UPPER`` or ``LOWER``. + +``FortranCInterface_MODULE__PREFIX`` + Prefix for a module symbol with an underscore. + +``FortranCInterface_MODULE__MIDDLE`` + Middle of a module symbol with an underscore that appears + between the name of the module and the name of the symbol. + +``FortranCInterface_MODULE__SUFFIX`` + Suffix for a module symbol with an underscore. + +``FortranCInterface_MODULE__CASE`` + The case for a module symbol with an underscore, + either ``UPPER`` or ``LOWER``. + +Module Functions +^^^^^^^^^^^^^^^^ + +.. command:: FortranCInterface_HEADER + + The ``FortranCInterface_HEADER`` 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 options are: + + ``MACRO_NAMESPACE`` + Replace the default ``FortranCInterface_`` prefix with a given + namespace ``<macro-ns>``. + + ``SYMBOLS`` + List 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. + + ``SYMBOL_NAMESPACE`` + Prefix all preprocessor definitions generated by the ``SYMBOLS`` + option with a given namespace ``<ns>``. + +.. command:: FortranCInterface_VERIFY + + The ``FortranCInterface_VERIFY`` function is provided to verify + that the Fortran and C/C++ compilers work together:: + + FortranCInterface_VERIFY([CXX] [QUIET]) + + It tests whether a simple test executable using Fortran and C (and C++ + when the CXX option is given) compiles and links successfully. The + result is stored in the cache entry ``FortranCInterface_VERIFIED_C`` + (or ``FortranCInterface_VERIFIED_CXX`` if ``CXX`` is given) as a boolean. + If the check fails and ``QUIET`` is not given the function terminates with a + fatal error message describing the problem. The purpose of this check + is to stop a build early for incompatible compiler combinations. The + test is built in the ``Release`` configuration. + +Example Usage +^^^^^^^^^^^^^ + +.. code-block:: cmake + + 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_()``. + +.. code-block:: cmake + + include(FortranCInterface) + FortranCInterface_HEADER(FCMangle.h + MACRO_NAMESPACE "FC_" + SYMBOL_NAMESPACE "FC_" + SYMBOLS mysub mymod:my_sub) + +This creates a "FCMangle.h" header that defines the same ``FC_*()`` +mangling macros as the previous example plus preprocessor symbols +``FC_mysub`` and ``FC_mymod_my_sub``. + +Additional Manglings +^^^^^^^^^^^^^^^^^^^^ + +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: + +.. code-block:: cmake + + 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. @@ -100,9 +195,8 @@ if(FortranCInterface_SOURCE_DIR) return() endif() -# Use CMake 2.8.0 behavior for this module regardless of including context. cmake_policy(PUSH) -cmake_policy(VERSION 2.8.0) +cmake_policy(SET CMP0007 NEW) #----------------------------------------------------------------------------- # Verify that C and Fortran are available. @@ -166,7 +260,7 @@ function(FortranCInterface_HEADER file) 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} + string(APPEND HEADER_CONTENT " ${_desc_${macro}} #define ${MACRO_NAMESPACE}${macro}${FortranCInterface_${macro}_MACRO} ") @@ -175,7 +269,7 @@ ${_desc_${macro}} # Generate symbol mangling definitions. if(SYMBOLS) - set(HEADER_CONTENT "${HEADER_CONTENT} + string(APPEND HEADER_CONTENT " /*--------------------------------------------------------------------------*/ /* Mangle some symbols automatically. */ ") @@ -196,7 +290,7 @@ ${_desc_${macro}} 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") + string(APPEND 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() @@ -210,7 +304,7 @@ ${_desc_${macro}} 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") + string(APPEND 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() @@ -254,7 +348,8 @@ function(FortranCInterface_VERIFY) try_compile(FortranCInterface_VERIFY_${lang}_COMPILED ${FortranCInterface_BINARY_DIR}/Verify${lang} ${FortranCInterface_SOURCE_DIR}/Verify - VerifyFortranC + VerifyFortranC # project name + VerifyFortranC # target name CMAKE_FLAGS -DVERIFY_CXX=${verify_cxx} -DCMAKE_VERBOSE_MAKEFILE=ON "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}" @@ -284,7 +379,7 @@ function(FortranCInterface_VERIFY) # Error if compilers are incompatible. if(NOT FortranCInterface_VERIFIED_${lang} AND NOT quiet) file(READ "${FortranCInterface_BINARY_DIR}/Verify${lang}/output.txt" _output) - string(REGEX REPLACE "\n" "\n " _output "${_output}") + string(REPLACE "\n" "\n " _output "${_output}") message(FATAL_ERROR "The Fortran compiler:\n ${CMAKE_Fortran_COMPILER}\n" "and the ${lang} compiler:\n ${CMAKE_${lang}_COMPILER}\n" |