#
# helper CMakeLists.txt file that can be used to generate input files
# for the Tests/RunCMake/ParseImplicitIncludeInfo test.
#
# usage:
#  [create a temporary build directory and chdir to it]
#  cmake [-D options] $CMAKE_SRC/Tests/RunCMake/ParseImplicitIncludeInfo/data
#
# where useful -D options include:
#   -DLANGUAGES="C;CXX"    -- list of languages to generate inputs for
#   -DUNAME="Darwin"       -- operating system name (def: CMAKE_SYSTEM_NAME)
#

cmake_minimum_required(VERSION 3.3)
if(POLICY CMP0089)
  cmake_policy(SET CMP0089 NEW)
endif()

set(lngs C CXX)
set(LANGUAGES "${lngs}" CACHE STRING "List of languages to generate inputs for")

project(gen_implicit_include_data ${LANGUAGES})

set(UNAME "${CMAKE_SYSTEM_NAME}" CACHE STRING "System uname")
string(TOLOWER "${UNAME}" UNAME)
message("Generate input for system type: ${UNAME}")

# CMAKE_<LANG>_COMPILER_* variables we save in the resultfile
set(compvars ABI AR ARCHITECTURE_ID EXTERNAL_TOOLCHAIN ID LAUNCHER LOADED
  RANLIB TARGET VERSION VERSION_INTERAL)

foreach(lang IN ITEMS ${LANGUAGES})

  if("${lang}" STREQUAL "C")
    set(file ${CMAKE_ROOT}/Modules/CMakeCCompilerABI.c)
  elseif("${lang}" STREQUAL "CXX")
    set(file ${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp)
  elseif("${lang}" STREQUAL "CUDA")
    set(file ${CMAKE_ROOT}/Modules/CMakeCUDACompilerABI.cu)
  elseif("${lang}" STREQUAL "Fortran")
    set(file ${CMAKE_ROOT}/Modules/CMakeFortranCompilerABI.F)
  else()
    message(FATAL_ERROR "unknown language ${lang}")
  endif()

  set(resultfile "${CMAKE_BINARY_DIR}/")
  string(APPEND resultfile ${UNAME}-${lang}-${CMAKE_${lang}_COMPILER_ID})
  string(APPEND resultfile -${CMAKE_${lang}_COMPILER_VERSION})
  string(APPEND resultfile .input)
  message("Generate input for language ${lang}")
  message("Input file: ${file}")
  message("Result file: ${resultfile}")

  # replicate logic from CMakeDetermineCompilerABI
  set(outfile "${CMAKE_PLATFORM_INFO_DIR}/test${lang}.out")
  set(CMAKE_FLAGS )
  set(COMPILE_DEFINITIONS )
  if(DEFINED CMAKE_${lang}_VERBOSE_FLAG)
    set(CMAKE_FLAGS "-DEXE_LINKER_FLAGS=${CMAKE_${lang}_VERBOSE_FLAG}")
    set(COMPILE_DEFINITIONS "${CMAKE_${lang}_VERBOSE_FLAG}")
  endif()
  if(DEFINED CMAKE_${lang}_VERBOSE_COMPILE_FLAG)
    set(COMPILE_DEFINITIONS "${CMAKE_${lang}_VERBOSE_COMPILE_FLAG}")
  endif()
  if(NOT "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC")
    # Avoid adding our own platform standard libraries for compilers
    # from which we might detect implicit link libraries.
    list(APPEND CMAKE_FLAGS "-DCMAKE_${lang}_STANDARD_LIBRARIES=")
  endif()

  try_compile(rv ${CMAKE_BINARY_DIR} ${file}
    CMAKE_FLAGS ${CMAKE_FLAGS}
    COMPILE_DEFINITIONS ${COMPILE_DEFINITIONS}
    CMAKE_FLAGS ${CMAKE_FLAGS}
    OUTPUT_VARIABLE output
    COPY_FILE "${outfile}"
    COPY_FILE_ERROR copy_error)

  if(NOT rv)
    message(FATAL_ERROR "${lang} compile failed!!")
  endif()

  set(result "CMAKE_LANG=${lang}\n")
  foreach(var IN ITEMS ${compvars})
    list(APPEND result
      "CMAKE_${lang}_COMPILER_${var}=${CMAKE_${lang}_COMPILER_${var}}\n")
  endforeach()

  file(WRITE ${resultfile} ${result} ${output})
endforeach()
