summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2009-08-24 12:49:07 (GMT)
committerBrad King <brad.king@kitware.com>2009-08-24 12:49:07 (GMT)
commit14f7a043e3686a6a2b821e759e391c54f3239479 (patch)
tree218135681a13af0502a383413fbce8fb94951ca9 /Modules
parent40ddd535435ee5a68b54d373030bc16d7f918f4b (diff)
downloadCMake-14f7a043e3686a6a2b821e759e391c54f3239479.zip
CMake-14f7a043e3686a6a2b821e759e391c54f3239479.tar.gz
CMake-14f7a043e3686a6a2b821e759e391c54f3239479.tar.bz2
Teach FortranCInterface to load outside results
We split the main detection logic into a Detect.cmake support module and load it only when detection results are not already available. This allows results computed by the main project to be used in try-compile projects without recomputing them. The call to try_compile() need only to pass FortranCInterface_BINARY_DIR through the CMAKE_FLAGS option.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/FortranCInterface.cmake166
-rw-r--r--Modules/FortranCInterface/Detect.cmake165
2 files changed, 169 insertions, 162 deletions
diff --git a/Modules/FortranCInterface.cmake b/Modules/FortranCInterface.cmake
index eba97c6..126b117 100644
--- a/Modules/FortranCInterface.cmake
+++ b/Modules/FortranCInterface.cmake
@@ -85,170 +85,12 @@ foreach(lang C Fortran)
endforeach()
#-----------------------------------------------------------------------------
-# 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}")
+# Create the interface detection project if it does not exist.
+if(NOT FortranCInterface_BINARY_DIR)
+ set(FortranCInterface_BINARY_DIR ${CMAKE_BINARY_DIR}/CMakeFiles/FortranCInterface)
+ include(${FortranCInterface_SOURCE_DIR}/Detect.cmake)
endif()
# Load the detection results.
diff --git a/Modules/FortranCInterface/Detect.cmake b/Modules/FortranCInterface/Detect.cmake
new file mode 100644
index 0000000..b848d33
--- /dev/null
+++ b/Modules/FortranCInterface/Detect.cmake
@@ -0,0 +1,165 @@
+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()
+
+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}")