# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=[

NOTE: This function is used internally by CMake. Projects should not include
      this file directly.

The cmake_check_compiler_flag() function can be used to compile and link a
source file to check whether a specific compiler or linker flag is supported.
The function does not use the try_compile() command so as to avoid infinite
recursion.  It may not work for all platforms or toolchains, the caller is
responsible for ensuring it is only called in valid situations.

  cmake_check_compiler_flag(<lang> <flag> <result>
                            [SRC_EXT <ext>] [COMMAND_PATTERN <pattern>]
                            [FAIL_REGEX <regex> ...]
                            [OUTPUT_VARIABLE <output>])

Parameters:
  <lang>   - Language to check.
  <flag>   - The flag to add to the compile/link command line.
  <result> - Boolean output variable.  It will be stored in the cache as an
             internal variable and if true, will cause future tests that assign
             to that variable to be bypassed.

Optional parameters:
  SRC_EXT         - Overrides the extension of the source file used for the
                    check.  Defaults are 'c' (C), 'cxx' (CXX), 'F' (Fortran).
  COMMAND_PATTERN - Pattern to be used for the command line. The default is
                    '<FLAG> -o <OUTPUT> <SOURCE>'
  FAIL_REGEX      - List of additional regular expressions that, if matched by
                    the output, give a failed result for the check.  A common
                    set of regular expressions will be included in addition to
                    those given by FAIL_REGEX.
  OUTPUT_VARIABLE - Set <output> variable with details about any error.
#]=]

include_guard(GLOBAL)
include(CMakeCheckCompilerFlagCommonPatterns)

function(CMAKE_CHECK_COMPILER_FLAG lang flag result)
  # Cache results between runs similar to check_<lang>_source_compiles()
  if(DEFINED ${result})
    return()
  endif()

  set(comment "Is the '${flag}' option(s) supported")
  string(REPLACE ";" " " comment "${comment}")

  if (NOT lang MATCHES "^(C|CXX|Fortran|ASM)$")
    # other possible languages are not supported
    # log message to keep trace of this problem...
    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
      "Function 'CMAKE_CHECK_COMPILER_FLAG' called with unsupported language: ${lang}\n")
    set(${result} FALSE CACHE INTERNAL ${comment})
    return()
  endif()
  if (lang STREQUAL "ASM")
    # assume ASM compiler is a multi-language compiler, so supports C language as well
    set(check_lang C)
  else()
    set(check_lang ${lang})
  endif()

  cmake_parse_arguments(CCCF "" "SRC_EXT;COMMAND_PATTERN;OUTPUT_VARIABLE" "FAIL_REGEX" ${ARGN})

  if (NOT CCCF_COMMAND_PATTERN)
    set (CCCF_COMMAND_PATTERN "<FLAG> -o <OUTPUT> <SOURCE>")
  endif()

  list (APPEND CCCF_FAIL_REGEX "argument unused during compilation") # clang
  if (check_lang STREQUAL "C")
    list(APPEND CCCF_FAIL_REGEX
      "command line option .* is valid for .* but not for C") # GNU
  elseif(check_lang STREQUAL "CXX")
    list(APPEND CCCF_FAIL_REGEX
      "command line option .* is valid for .* but not for C\\+\\+") # GNU
  elseif(check_lang STREQUAL "Fortran")
    list(APPEND CCCF_FAIL_REGEX
      "command line option .* is valid for .* but not for Fortran") # GNU
  endif()

  # Add patterns for common errors
  check_compiler_flag_common_patterns(COMPILER_FLAG_COMMON_PATTERNS)
  foreach(arg IN LISTS COMPILER_FLAG_COMMON_PATTERNS)
    if(arg MATCHES "^FAIL_REGEX$")
      continue()
    endif()
    list(APPEND CCCF_FAIL_REGEX "${arg}")
  endforeach()

  if(NOT CCCF_SRC_EXT)
    if (check_lang STREQUAL "C")
      set(CCCF_SRC_EXT c)
    elseif(check_lang STREQUAL "CXX")
      set(CCCF_SRC_EXT cxx)
    elseif(check_lang STREQUAL "Fortran")
      set(CCCF_SRC_EXT F)
    endif()
  endif()

  if (CCCF_OUTPUT_VARIABLE)
    unset(${CCCF_OUTPUT_VARIABLE} PARENT_SCOPE)
  endif()

  # Compute the directory in which to run the test.
  set(COMPILER_FLAG_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp")
  # Compute source and output files.
  set(COMPILER_FLAG_SRC
    "${COMPILER_FLAG_DIR}/CompilerFlag${lang}.${CCCF_SRC_EXT}")
  if(check_lang STREQUAL "Fortran")
    file(WRITE "${COMPILER_FLAG_SRC}"
      "      program simple\n      end program simple\n")
  else()
    file(WRITE "${COMPILER_FLAG_SRC}" "int main (void)\n{ return 0; }\n")
  endif()
  get_filename_component(COMPILER_FLAG_EXE "${COMPILER_FLAG_SRC}" NAME_WE)
  string(APPEND COMPILER_FLAG_EXE "${CMAKE_EXECUTABLE_SUFFIX}")

  # Build command line
  separate_arguments(CCCF_COMMAND_PATTERN UNIX_COMMAND
    "${CCCF_COMMAND_PATTERN}")
  list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "<SOURCE>" "${COMPILER_FLAG_SRC}")
  list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "<OUTPUT>" "${COMPILER_FLAG_EXE}")
  list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "<FLAG>" "${flag}")

  execute_process(
    COMMAND "${CMAKE_COMMAND}" -E env LC_ALL=C LC_MESSAGES=C LANG=C
            "${CMAKE_${lang}_COMPILER}" ${CCCF_COMMAND_PATTERN}
    WORKING_DIRECTORY "${COMPILER_FLAG_DIR}"
    OUTPUT_VARIABLE COMPILER_FLAG_OUTPUT
    ERROR_VARIABLE COMPILER_FLAG_OUTPUT
    RESULT_VARIABLE COMPILER_FLAG_RESULT)

  # Record result in the cache so we can avoid re-testing every CMake run
  if (COMPILER_FLAG_RESULT)
    set(${result} FALSE CACHE INTERNAL ${comment})
  else()
    foreach(regex IN LISTS CCCF_FAIL_REGEX)
      if(COMPILER_FLAG_OUTPUT MATCHES "${regex}")
        set(${result} FALSE CACHE INTERNAL ${comment})
      endif()
    endforeach()
  endif()
  if (DEFINED ${result})
    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
        "Determining if the ${flag} option "
        "is supported for ${lang} language failed with the following output:\n"
        "${COMPILER_FLAG_OUTPUT}\n")
    if (CCCF_OUTPUT_VARIABLE)
      set(${CCCF_OUTPUT_VARIABLE} "${COMPILER_FLAG_OUTPUT}" PARENT_SCOPE)
    endif()
    return()
  endif()

  set(${result} TRUE CACHE INTERNAL ${comment})
endfunction()
