File: CheckFortranFeatures.cmake

package info (click to toggle)
ecflow 5.15.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 51,868 kB
  • sloc: cpp: 269,341; python: 22,756; sh: 3,609; perl: 770; xml: 333; f90: 204; ansic: 141; makefile: 70
file content (168 lines) | stat: -rw-r--r-- 6,782 bytes parent folder | download | duplicates (8)
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
###############################################################################
# checks
set(Fortran_FEATURE_CHECK_DIR ${CMAKE_CURRENT_LIST_DIR} CACHE INTERNAL "fortran file directory")

MACRO(fortran_check_single_feature FEATURE_NAME FEATURE_NUMBER RESULT_VAR)
  IF (NOT DEFINED ${RESULT_VAR})
    SET(_bindir "${CMAKE_BINARY_DIR}/fortran_feature_tests/fortran_${FEATURE_NAME}")

    IF (${FEATURE_NUMBER})
      SET(_SRCFILE_BASE ${Fortran_FEATURE_CHECK_DIR}/${FEATURE_NAME}-N${FEATURE_NUMBER})
      SET(_LOG_NAME "\"${FEATURE_NAME}\" (N${FEATURE_NUMBER})")
    ELSE (${FEATURE_NUMBER})
      SET(_SRCFILE_BASE ${Fortran_FEATURE_CHECK_DIR}/${FEATURE_NAME})
      SET(_LOG_NAME "\"${FEATURE_NAME}\"")
    ENDIF (${FEATURE_NUMBER})
    ecbuild_info("Checking Fortran support for ${_LOG_NAME}")

    SET(_SRCFILE "${_SRCFILE_BASE}.F90")
    SET(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.F90")
    SET(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.F90")

    IF (CROSS_COMPILING)
      try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}")
      IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
        try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}")
      ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
    ELSE (CROSS_COMPILING)
      ecbuild_try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
          "${_bindir}" "${_SRCFILE}")
      IF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
        SET(${RESULT_VAR} TRUE)
      ELSE (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
        SET(${RESULT_VAR} FALSE)
      ENDIF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
      IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
        ecbuild_try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
            "${_bindir}_fail" "${_SRCFILE_FAIL}")
        IF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
          SET(${RESULT_VAR} TRUE)
        ELSE (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
          SET(${RESULT_VAR} FALSE)
        ENDIF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
      ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
    ENDIF (CROSS_COMPILING)
    IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
      try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}")
      IF (_TMP_RESULT)
        SET(${RESULT_VAR} FALSE)
      ELSE (_TMP_RESULT)
        SET(${RESULT_VAR} TRUE)
      ENDIF (_TMP_RESULT)
    ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})

    IF (${RESULT_VAR})
      ecbuild_info("Checking Fortran support for ${_LOG_NAME} -- works")
    ELSE (${RESULT_VAR})
      ecbuild_info("Checking Fortran support for ${_LOG_NAME} -- not supported")
    ENDIF (${RESULT_VAR})
    SET(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "Fortran support for ${_LOG_NAME}")
  ENDIF (NOT DEFINED ${RESULT_VAR})
ENDMACRO(fortran_check_single_feature)

# Find list of all features
function(fortran_find_all_features outvar)
  FILE(GLOB ALL_Fortran_FEATURE_FILES "${Fortran_FEATURE_CHECK_DIR}/*.F90")
  set(OUTPUT_VARIABLES)
  foreach(filename ${ALL_Fortran_FEATURE_FILES})
    get_filename_component(filename ${filename} NAME_WE)
    string(REGEX REPLACE "_fail_compile" "" filename "${filename}")
    string(REGEX REPLACE "_fail" "" filename "${filename}")
    string(REGEX REPLACE "-N[0-9]*" "" filename "${filename}")
    set(OUTPUT_VARIABLES ${OUTPUT_VARIABLES} ${filename})
  endforeach()
  list(REMOVE_DUPLICATES OUTPUT_VARIABLES)
  set(${outvar} ${OUTPUT_VARIABLES} PARENT_SCOPE)
endfunction()

# Parses input and separates into arguments before REQUIRED and after REQUIRED.
# Arguments before REQUIRED are OPTIONALS.
# Arguments after REQUIRED are REQUIRED.
# If no arguments, then sets output OPTIONALS to ALLFEATURES.
function(parse_input_features ALLFEATURES OPTIONALS REQUIRED ERRORS)

  if("${ARGN}" STREQUAL "")
    set(${OPTIONALS} ${ALLFEATURES} PARENT_SCOPE)
    set(${REQUIRED} "" PARENT_SCOPE)
  else()
    set(REQUIRED_FEATURES)
    set(OPTIONAL_FEATURES)
    set(UNKNOWN_FEATURES)
    set(result_type OPTIONAL_FEATURES)
    foreach(feature ${ARGN})
      if(${feature} STREQUAL "REQUIRED")
        set(result_type REQUIRED_FEATURES)
      else()
        list(FIND ALLFEATURES ${feature} feature_was_found)

        if(feature_was_found EQUAL -1)
          list(APPEND UNKNOWN_FEATURES ${feature})
        else()
          list(APPEND ${result_type} ${feature})
        endif()

      endif(${feature} STREQUAL "REQUIRED")
    endforeach()

    set(${OPTIONALS} ${OPTIONAL_FEATURES} PARENT_SCOPE)
    set(${REQUIRED} ${REQUIRED_FEATURES} PARENT_SCOPE)
    set(${ERRORS} ${UNKNOWN_FEATURES} PARENT_SCOPE)
  endif("${ARGN}" STREQUAL "")
endfunction(parse_input_features)

# Figures out name and number of feature
# then calls macro that does the work
macro(_figure_out_fortran_feature current_feature)
  # Find set of files that match current_feature, excepting _fail and _fail_compile.
  file(GLOB ALL_FEATURE_FILES "${Fortran_FEATURE_CHECK_DIR}/${current_feature}*.F90")
  foreach(filename ${ALL_FEATURE_FILES})
    if(filename MATCHES "(_fail|_fail_compile).F90$")
      list(REMOVE_ITEM ALL_FEATURE_FILES ${filename})
    endif()
  endforeach()

  list(LENGTH ALL_FEATURE_FILES NFILES)
  if(NOT ${NFILES} EQUAL 1)
    ecbuild_critical("[Fortran] Expected to find only one feature. Found ${NFILES} -- ${ALL_FEATURE_FILES}.")
  endif(NOT ${NFILES} EQUAL 1)

  # Now we know which file corresponds to option.
  get_filename_component(basename ${ALL_FEATURE_FILES} NAME_WE)
  # If has feature number, extract it
  set(number "")
  if(basename MATCHES "-N[0-9]*$")
    string(REGEX REPLACE "${current_feature}-N" "" number "${basename}")
  endif()
  # Then call macro
  string(TOUPPER ${current_feature} UPPER_OPTIONAL)
  set(VARNAME HAS_Fortran_${UPPER_OPTIONAL})
  fortran_check_single_feature(${current_feature} "${number}" ${VARNAME})
endmacro(_figure_out_fortran_feature)

function(fortran_feature_check)

  # find all features
  fortran_find_all_features(ALL_Fortran_FEATURES)

  # Parses input to this function.
  parse_input_features("${ALL_Fortran_FEATURES}" OPTIONALS REQUIRED ERRORS ${ARGN})
  if(NOT ${ERRORS} STREQUAL "")
    ecbuild_info("[Fortran] The following features are unknown: ${ERRORS}.")
  endif()

  # Check optional features
  foreach(current_feature ${OPTIONALS})
    _figure_out_fortran_feature(${current_feature})
  endforeach(current_feature ${ARGN})

  # Check required features
  foreach(current_feature ${REQUIRED})
    _figure_out_fortran_feature(${current_feature})
    string(TOUPPER ${current_feature} UPPER_REQUIRED)
    set(VARNAME HAS_Fortran_${UPPER_REQUIRED})
    if(NOT ${VARNAME})
      ecbuild_critical("[Fortran] Required feature ${current_feature} is not available.")
    endif(NOT ${VARNAME})
  endforeach(current_feature ${REQUIRED})

endfunction(fortran_feature_check)