1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
#=============================================================================
# Copyright 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.
#=============================================================================
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")
else()
return()
endif()
# Invalidate verification results.
unset(FortranCInterface_VERIFIED_C CACHE)
unset(FortranCInterface_VERIFIED_CXX CACHE)
set(_result)
# Build a sample project which reports symbols.
try_compile(FortranCInterface_COMPILED
${FortranCInterface_BINARY_DIR}
${FortranCInterface_SOURCE_DIR}
FortranCInterface
CMAKE_FLAGS
"-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}"
"-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}"
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()
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}")
|