1
#=============================================================================
2
# Copyright 2009 Kitware, Inc.
4
# Distributed under the OSI-approved BSD License (the "License");
5
# see accompanying file Copyright.txt for details.
7
# This software is distributed WITHOUT ANY WARRANTY; without even the
8
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9
# See the License for more information.
10
#=============================================================================
12
configure_file(${FortranCInterface_SOURCE_DIR}/Input.cmake.in
13
${FortranCInterface_BINARY_DIR}/Input.cmake @ONLY)
15
# Detect the Fortran/C interface on the first run or when the
16
# configuration changes.
17
if(${FortranCInterface_BINARY_DIR}/Input.cmake
18
IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
19
OR ${FortranCInterface_SOURCE_DIR}/Output.cmake.in
20
IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
21
OR ${FortranCInterface_SOURCE_DIR}/CMakeLists.txt
22
IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
23
OR ${CMAKE_CURRENT_LIST_FILE}
24
IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
26
message(STATUS "Detecting Fortran/C Interface")
31
# Invalidate verification results.
32
unset(FortranCInterface_VERIFIED_C CACHE)
33
unset(FortranCInterface_VERIFIED_CXX CACHE)
37
# Build a sample project which reports symbols.
38
try_compile(FortranCInterface_COMPILED
39
${FortranCInterface_BINARY_DIR}
40
${FortranCInterface_SOURCE_DIR}
42
OUTPUT_VARIABLE FortranCInterface_OUTPUT)
43
set(FortranCInterface_COMPILED ${FortranCInterface_COMPILED})
44
unset(FortranCInterface_COMPILED CACHE)
46
# Locate the sample project executable.
47
if(FortranCInterface_COMPILED)
48
find_program(FortranCInterface_EXE
49
NAMES FortranCInterface
50
PATHS ${FortranCInterface_BINARY_DIR} ${FortranCInterface_BINARY_DIR}/Debug
53
set(FortranCInterface_EXE ${FortranCInterface_EXE})
54
unset(FortranCInterface_EXE CACHE)
56
set(_result "Failed to compile")
57
set(FortranCInterface_EXE)
58
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
59
"Fortran/C interface test project failed with the following output:\n"
60
"${FortranCInterface_OUTPUT}\n")
63
# Load symbols from INFO:symbol[] strings in the executable.
64
set(FortranCInterface_SYMBOLS)
65
if(FortranCInterface_EXE)
66
file(STRINGS "${FortranCInterface_EXE}" _info_strings
67
LIMIT_COUNT 8 REGEX "INFO:[^[]*\\[")
68
foreach(info ${_info_strings})
69
if("${info}" MATCHES ".*INFO:symbol\\[([^]]*)\\].*")
70
string(REGEX REPLACE ".*INFO:symbol\\[([^]]*)\\].*" "\\1" symbol "${info}")
71
list(APPEND FortranCInterface_SYMBOLS ${symbol})
75
set(_result "Failed to load sample executable")
78
set(_case_mysub "LOWER")
79
set(_case_my_sub "LOWER")
80
set(_case_MYSUB "UPPER")
81
set(_case_MY_SUB "UPPER")
82
set(_global_regex "^(_*)(mysub|MYSUB)([_$]*)$")
83
set(_global__regex "^(_*)(my_sub|MY_SUB)([_$]*)$")
84
set(_module_regex "^(_*)(mymodule|MYMODULE)([A-Za-z_$]*)(mysub|MYSUB)([_$]*)$")
85
set(_module__regex "^(_*)(my_module|MY_MODULE)([A-Za-z_$]*)(my_sub|MY_SUB)([_$]*)$")
87
# Parse the symbol names.
88
foreach(symbol ${FortranCInterface_SYMBOLS})
90
# Look for global symbols.
91
string(REGEX REPLACE "${_global_${form}regex}"
92
"\\1;\\2;\\3" pieces "${symbol}")
93
list(LENGTH pieces len)
95
set(FortranCInterface_GLOBAL_${form}SYMBOL "${symbol}")
96
list(GET pieces 0 FortranCInterface_GLOBAL_${form}PREFIX)
97
list(GET pieces 1 name)
98
list(GET pieces 2 FortranCInterface_GLOBAL_${form}SUFFIX)
99
set(FortranCInterface_GLOBAL_${form}CASE "${_case_${name}}")
102
# Look for module symbols.
103
string(REGEX REPLACE "${_module_${form}regex}"
104
"\\1;\\2;\\3;\\4;\\5" pieces "${symbol}")
105
list(LENGTH pieces len)
107
set(FortranCInterface_MODULE_${form}SYMBOL "${symbol}")
108
list(GET pieces 0 FortranCInterface_MODULE_${form}PREFIX)
109
list(GET pieces 1 module)
110
list(GET pieces 2 FortranCInterface_MODULE_${form}MIDDLE)
111
list(GET pieces 3 name)
112
list(GET pieces 4 FortranCInterface_MODULE_${form}SUFFIX)
113
set(FortranCInterface_MODULE_${form}CASE "${_case_${name}}")
118
# Construct mangling macro definitions.
119
set(_name_LOWER "name")
120
set(_name_UPPER "NAME")
122
if(FortranCInterface_GLOBAL_${form}SYMBOL)
123
if(FortranCInterface_GLOBAL_${form}PREFIX)
124
set(_prefix "${FortranCInterface_GLOBAL_${form}PREFIX}##")
128
if(FortranCInterface_GLOBAL_${form}SUFFIX)
129
set(_suffix "##${FortranCInterface_GLOBAL_${form}SUFFIX}")
133
set(_name "${_name_${FortranCInterface_GLOBAL_${form}CASE}}")
134
set(FortranCInterface_GLOBAL${form}_MACRO
135
"(name,NAME) ${_prefix}${_name}${_suffix}")
137
if(FortranCInterface_MODULE_${form}SYMBOL)
138
if(FortranCInterface_MODULE_${form}PREFIX)
139
set(_prefix "${FortranCInterface_MODULE_${form}PREFIX}##")
143
if(FortranCInterface_MODULE_${form}SUFFIX)
144
set(_suffix "##${FortranCInterface_MODULE_${form}SUFFIX}")
148
set(_name "${_name_${FortranCInterface_MODULE_${form}CASE}}")
149
set(_middle "##${FortranCInterface_MODULE_${form}MIDDLE}##")
150
set(FortranCInterface_MODULE${form}_MACRO
151
"(mod_name,name, mod_NAME,NAME) ${_prefix}mod_${_name}${_middle}${_name}${_suffix}")
155
# Summarize what is available.
156
foreach(scope GLOBAL MODULE)
157
if(FortranCInterface_${scope}_SYMBOL AND
158
FortranCInterface_${scope}__SYMBOL)
159
set(FortranCInterface_${scope}_FOUND 1)
161
set(FortranCInterface_${scope}_FOUND 0)
165
# Record the detection results.
166
configure_file(${FortranCInterface_SOURCE_DIR}/Output.cmake.in
167
${FortranCInterface_BINARY_DIR}/Output.cmake @ONLY)
168
file(APPEND ${FortranCInterface_BINARY_DIR}/Output.cmake "\n")
170
# Report the results.
171
if(FortranCInterface_GLOBAL_FOUND)
172
if(FortranCInterface_MODULE_FOUND)
173
set(_result "Found GLOBAL and MODULE mangling")
174
else(FortranCInterface_MODULE_FOUND)
175
set(_result "Found GLOBAL but not MODULE mangling")
178
set(_result "Failed to recognize symbols")
180
message(STATUS "Detecting Fortran/C Interface - ${_result}")