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


# determine the compiler to use for Objective-C programs
# NOTE, a generator may set CMAKE_OBJC_COMPILER before
# loading this file to force a compiler.
# use environment variable OBJC first if defined by user, next use
# the cmake variable CMAKE_GENERATOR_OBJC which can be defined by a generator
# as a default compiler
#
# Sets the following variables:
#   CMAKE_OBJC_COMPILER
#   CMAKE_AR
#   CMAKE_RANLIB
#   CMAKE_COMPILER_IS_GNUOBJC
#   CMAKE_COMPILER_IS_CLANGOBJC
#
# If not already set before, it also sets
#   _CMAKE_TOOLCHAIN_PREFIX

include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)

# Load system-specific compiler preferences for this language.
include(Platform/${CMAKE_SYSTEM_NAME}-Determine-OBJC OPTIONAL)
include(Platform/${CMAKE_SYSTEM_NAME}-OBJC OPTIONAL)
if(NOT CMAKE_OBJC_COMPILER_NAMES)
  set(CMAKE_OBJC_COMPILER_NAMES clang)
endif()

if("${CMAKE_GENERATOR}" MATCHES "Xcode")
  set(CMAKE_OBJC_COMPILER_XCODE_TYPE sourcecode.c.objc)
else()
  if(NOT CMAKE_OBJC_COMPILER)
    set(CMAKE_OBJC_COMPILER_INIT NOTFOUND)

    # prefer the environment variable OBJC or CC
    foreach(var OBJC CC)
      if($ENV{${var}} MATCHES ".+")
        get_filename_component(CMAKE_OBJC_COMPILER_INIT $ENV{${var}} PROGRAM PROGRAM_ARGS CMAKE_OBJC_FLAGS_ENV_INIT)
        if(CMAKE_OBJC_FLAGS_ENV_INIT)
          set(CMAKE_OBJC_COMPILER_ARG1 "${CMAKE_OBJC_FLAGS_ENV_INIT}" CACHE STRING "First argument to Objective-C compiler")
        endif()
        if(NOT EXISTS ${CMAKE_OBJC_COMPILER_INIT})
          message(FATAL_ERROR "Could not find compiler set in environment variable ${var}:\n  $ENV{${var}}")
        endif()
        break()
      endif()
    endforeach()

    # next try prefer the compiler specified by the generator
    if(CMAKE_GENERATOR_OBJC)
      if(NOT CMAKE_OBJC_COMPILER_INIT)
        set(CMAKE_OBJC_COMPILER_INIT ${CMAKE_GENERATOR_OBJC})
      endif()
    endif()

    # finally list compilers to try
    if(NOT CMAKE_OBJC_COMPILER_INIT)
      set(CMAKE_OBJC_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}cc ${_CMAKE_TOOLCHAIN_PREFIX}gcc clang)
    endif()

    _cmake_find_compiler(OBJC)

  else()
    # we only get here if CMAKE_OBJC_COMPILER was specified using -D or a pre-made CMakeCache.txt
    # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
    # if CMAKE_OBJC_COMPILER is a list of length 2, use the first item as
    # CMAKE_OBJC_COMPILER and the 2nd one as CMAKE_OBJC_COMPILER_ARG1

    list(LENGTH CMAKE_OBJC_COMPILER _CMAKE_OBJC_COMPILER_LIST_LENGTH)
    if("${_CMAKE_OBJC_COMPILER_LIST_LENGTH}" EQUAL 2)
      list(GET CMAKE_OBJC_COMPILER 1 CMAKE_OBJC_COMPILER_ARG1)
      list(GET CMAKE_OBJC_COMPILER 0 CMAKE_OBJC_COMPILER)
    endif()

    # if a compiler was specified by the user but without path,
    # now try to find it with the full path
    # if it is found, force it into the cache,
    # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
    # if the C compiler already had a path, reuse it for searching the CXX compiler
    get_filename_component(_CMAKE_USER_OBJC_COMPILER_PATH "${CMAKE_OBJC_COMPILER}" PATH)
    if(NOT _CMAKE_USER_OBJC_COMPILER_PATH)
      find_program(CMAKE_OBJC_COMPILER_WITH_PATH NAMES ${CMAKE_OBJC_COMPILER})
      if(CMAKE_OBJC_COMPILER_WITH_PATH)
        set(CMAKE_OBJC_COMPILER ${CMAKE_OBJC_COMPILER_WITH_PATH} CACHE STRING "Objective-C compiler" FORCE)
      endif()
      unset(CMAKE_OBJC_COMPILER_WITH_PATH CACHE)
    endif()
  endif()
  mark_as_advanced(CMAKE_OBJC_COMPILER)

  # Each entry in this list is a set of extra flags to try
  # adding to the compile line to see if it helps produce
  # a valid identification file.
  set(CMAKE_OBJC_COMPILER_ID_TEST_FLAGS_FIRST)
  set(CMAKE_OBJC_COMPILER_ID_TEST_FLAGS
    # Try compiling to an object file only.
    "-c"

    )
endif()

# Build a small source file to identify the compiler.
if(NOT CMAKE_OBJC_COMPILER_ID_RUN)
  set(CMAKE_OBJC_COMPILER_ID_RUN 1)

  # Try to identify the compiler.
  set(CMAKE_OBJC_COMPILER_ID)
  file(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in
    CMAKE_OBJC_COMPILER_ID_PLATFORM_CONTENT)

  # Match the link line from xcodebuild output of the form
  #  Ld ...
  #      ...
  #      /path/to/cc ...CompilerIdOBJC/...
  # to extract the compiler front-end for the language.
  set(CMAKE_OBJC_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdOBJC/(\\./)?(CompilerIdOBJC.(framework|xctest)/)?CompilerIdOBJC[ \t\n\\\"]")
  set(CMAKE_OBJC_COMPILER_ID_TOOL_MATCH_INDEX 2)

  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
  CMAKE_DETERMINE_COMPILER_ID(OBJC OBJCCFLAGS CMakeOBJCCompilerId.m)

  # Set old compiler and platform id variables.
  if(CMAKE_OBJC_COMPILER_ID STREQUAL "GNU")
    set(CMAKE_COMPILER_IS_GNUOBJC 1)
  endif()
  if(CMAKE_OBJC_COMPILER_ID STREQUAL "Clang")
    set(CMAKE_COMPILER_IS_CLANGOBJC 1)
  endif()
endif()

if (NOT _CMAKE_TOOLCHAIN_LOCATION)
  get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_OBJC_COMPILER}" PATH)
endif ()

# If we have a gcc cross compiler, they have usually some prefix, like
# e.g. powerpc-linux-gcc, arm-elf-gcc or i586-mingw32msvc-gcc, optionally
# with a 3-component version number at the end (e.g. arm-eabi-gcc-4.5.2).
# The other tools of the toolchain usually have the same prefix
# NAME_WE cannot be used since then this test will fail for names like
# "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
if (CMAKE_CROSSCOMPILING  AND NOT _CMAKE_TOOLCHAIN_PREFIX)

  if(CMAKE_OBJC_COMPILER_ID MATCHES "GNU|Clang|QCC")
    get_filename_component(COMPILER_BASENAME "${CMAKE_OBJC_COMPILER}" NAME)
    if (COMPILER_BASENAME MATCHES "^(.+-)(clang|g?cc)(-[0-9]+(\\.[0-9]+)*)?(-[^.]+)?(\\.exe)?$")
      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
      set(_CMAKE_COMPILER_SUFFIX ${CMAKE_MATCH_5})
    elseif(CMAKE_OBJC_COMPILER_ID MATCHES "Clang")
      if(CMAKE_OBJC_COMPILER_TARGET)
        set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_OBJC_COMPILER_TARGET}-)
      endif()
    elseif(COMPILER_BASENAME MATCHES "qcc(\\.exe)?$")
      if(CMAKE_OBJC_COMPILER_TARGET MATCHES "gcc_nto([a-z0-9]+_[0-9]+|[^_le]+)(le)?")
        set(_CMAKE_TOOLCHAIN_PREFIX nto${CMAKE_MATCH_1}-)
      endif()
    endif ()

    # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
    # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
    if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
    endif ()
  endif()

endif ()

set(_CMAKE_PROCESSING_LANGUAGE "OBJC")
include(CMakeFindBinUtils)
include(Compiler/${CMAKE_OBJC_COMPILER_ID}-FindBinUtils OPTIONAL)
unset(_CMAKE_PROCESSING_LANGUAGE)

if(CMAKE_OBJC_COMPILER_ARCHITECTURE_ID)
  set(_SET_CMAKE_OBJC_COMPILER_ARCHITECTURE_ID
    "set(CMAKE_OBJC_COMPILER_ARCHITECTURE_ID ${CMAKE_OBJC_COMPILER_ARCHITECTURE_ID})")
else()
  set(_SET_CMAKE_OBJC_COMPILER_ARCHITECTURE_ID "")
endif()

if(CMAKE_OBJC_XCODE_ARCHS)
  set(SET_CMAKE_XCODE_ARCHS
    "set(CMAKE_XCODE_ARCHS \"${CMAKE_OBJC_XCODE_ARCHS}\")")
endif()

# configure variables set in this file for fast reload later on
configure_file(${CMAKE_ROOT}/Modules/CMakeOBJCCompiler.cmake.in
  ${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCCompiler.cmake
  @ONLY
  )
set(CMAKE_OBJC_COMPILER_ENV_VAR "OBJC")
