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

#[=======================================================================[.rst:
CMakeFindPackageMode
--------------------



This file is executed by cmake when invoked with --find-package.  It
expects that the following variables are set using -D:

``NAME``
  name of the package
``COMPILER_ID``
  the CMake compiler ID for which the result is,
  i.e. GNU/Intel/Clang/MSVC, etc.
``LANGUAGE``
  language for which the result will be used,
  i.e. C/CXX/Fortran/ASM
``MODE``
  ``EXIST``
    only check for existence of the given package
  ``COMPILE``
    print the flags needed for compiling an object file which uses
    the given package
  ``LINK``
    print the flags needed for linking when using the given package
``QUIET``
  if TRUE, don't print anything
#]=======================================================================]

if(NOT NAME)
  message(FATAL_ERROR "Name of the package to be searched not specified. Set the CMake variable NAME, e.g. -DNAME=JPEG .")
endif()

if(NOT COMPILER_ID)
  message(FATAL_ERROR "COMPILER_ID argument not specified. In doubt, use GNU.")
endif()

if(NOT LANGUAGE)
  message(FATAL_ERROR "LANGUAGE argument not specified. Use C, CXX or Fortran.")
endif()

if(NOT MODE)
  message(FATAL_ERROR "MODE argument not specified. Use either EXIST, COMPILE or LINK.")
endif()

# require the current version. If we don't do this, Platforms/CYGWIN.cmake complains because
# it doesn't know whether it should set WIN32 or not:
cmake_minimum_required(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} )

macro(ENABLE_LANGUAGE)
  # disable the enable_language() command, otherwise --find-package breaks on Windows.
  # On Windows, enable_language(RC) is called in the platform files unconditionally.
  # But in --find-package mode, we don't want (and can't) enable any language.
endmacro()

set(CMAKE_PLATFORM_INFO_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY})

include(CMakeDetermineSystem)

# short-cut some tests on Darwin, see Darwin-GNU.cmake:
if("${CMAKE_SYSTEM_NAME}" MATCHES Darwin  AND  "${COMPILER_ID}" MATCHES GNU)
  set(CMAKE_${LANGUAGE}_SYSROOT_FLAG "")
  set(CMAKE_${LANGUAGE}_OSX_DEPLOYMENT_TARGET_FLAG "")
endif()

include(CMakeSystemSpecificInitialize)

# Also load the system specific file, which sets up e.g. the search paths.
# This makes the FIND_XXX() calls work much better
include(CMakeSystemSpecificInformation)

if(UNIX)

  # try to guess whether we have a 64bit system, if it has not been set
  # from the outside
  if(NOT CMAKE_SIZEOF_VOID_P)
    set(CMAKE_SIZEOF_VOID_P 4)
    if(EXISTS /usr/lib64)
      set(CMAKE_SIZEOF_VOID_P 8)
    else()
      # use the file utility to check whether itself is 64 bit:
      find_program(FILE_EXECUTABLE file)
      if(FILE_EXECUTABLE)
        get_filename_component(FILE_ABSPATH "${FILE_EXECUTABLE}" ABSOLUTE)
        execute_process(COMMAND "${FILE_ABSPATH}" "${FILE_ABSPATH}" OUTPUT_VARIABLE fileOutput ERROR_QUIET)
        if("${fileOutput}" MATCHES "64-bit")
          set(CMAKE_SIZEOF_VOID_P 8)
        endif()
      endif()
    endif()
  endif()

  # guess Debian multiarch if it has not been set:
  if(EXISTS /etc/debian_version)
    if(NOT CMAKE_${LANGUAGE}_LIBRARY_ARCHITECTURE )
      file(GLOB filesInLib RELATIVE /lib /lib/*-linux-gnu* )
      foreach(file ${filesInLib})
        if("${file}" MATCHES "${CMAKE_LIBRARY_ARCHITECTURE_REGEX}")
          set(CMAKE_${LANGUAGE}_LIBRARY_ARCHITECTURE ${file})
          break()
        endif()
      endforeach()
    endif()
    if(NOT CMAKE_LIBRARY_ARCHITECTURE)
      set(CMAKE_LIBRARY_ARCHITECTURE ${CMAKE_${LANGUAGE}_LIBRARY_ARCHITECTURE})
    endif()
  endif()

endif()

set(CMAKE_${LANGUAGE}_COMPILER "dummy")
set(CMAKE_${LANGUAGE}_COMPILER_ID "${COMPILER_ID}")
include(CMake${LANGUAGE}Information)


function(set_compile_flags_var _packageName)
  string(TOUPPER "${_packageName}" PACKAGE_NAME)
  # Check the following variables:
  # FOO_INCLUDE_DIRS
  # Foo_INCLUDE_DIRS
  # FOO_INCLUDES
  # Foo_INCLUDES
  # FOO_INCLUDE_DIR
  # Foo_INCLUDE_DIR
  set(includes)
  if(DEFINED ${_packageName}_INCLUDE_DIRS)
    set(includes ${_packageName}_INCLUDE_DIRS)
  elseif(DEFINED ${PACKAGE_NAME}_INCLUDE_DIRS)
    set(includes ${PACKAGE_NAME}_INCLUDE_DIRS)
  elseif(DEFINED ${_packageName}_INCLUDES)
    set(includes ${_packageName}_INCLUDES)
  elseif(DEFINED ${PACKAGE_NAME}_INCLUDES)
    set(includes ${PACKAGE_NAME}_INCLUDES)
  elseif(DEFINED ${_packageName}_INCLUDE_DIR)
    set(includes ${_packageName}_INCLUDE_DIR)
  elseif(DEFINED ${PACKAGE_NAME}_INCLUDE_DIR)
    set(includes ${PACKAGE_NAME}_INCLUDE_DIR)
  endif()

  set(PACKAGE_INCLUDE_DIRS "${${includes}}" PARENT_SCOPE)

  # Check the following variables:
  # FOO_DEFINITIONS
  # Foo_DEFINITIONS
  set(definitions)
  if(DEFINED ${_packageName}_DEFINITIONS)
    set(definitions ${_packageName}_DEFINITIONS)
  elseif(DEFINED ${PACKAGE_NAME}_DEFINITIONS)
    set(definitions ${PACKAGE_NAME}_DEFINITIONS)
  endif()

  set(PACKAGE_DEFINITIONS  "${${definitions}}" )

endfunction()


function(set_link_flags_var _packageName)
  string(TOUPPER "${_packageName}" PACKAGE_NAME)
  # Check the following variables:
  # FOO_LIBRARIES
  # Foo_LIBRARIES
  # FOO_LIBS
  # Foo_LIBS
  set(libs)
  if(DEFINED ${_packageName}_LIBRARIES)
    set(libs ${_packageName}_LIBRARIES)
  elseif(DEFINED ${PACKAGE_NAME}_LIBRARIES)
    set(libs ${PACKAGE_NAME}_LIBRARIES)
  elseif(DEFINED ${_packageName}_LIBS)
    set(libs ${_packageName}_LIBS)
  elseif(DEFINED ${PACKAGE_NAME}_LIBS)
    set(libs ${PACKAGE_NAME}_LIBS)
  endif()

  set(PACKAGE_LIBRARIES "${${libs}}" PARENT_SCOPE )

endfunction()


find_package("${NAME}" QUIET)

set(PACKAGE_FOUND FALSE)

string(TOUPPER "${NAME}" UPPERCASE_NAME)

if(${NAME}_FOUND  OR  ${UPPERCASE_NAME}_FOUND)
  set(PACKAGE_FOUND TRUE)

  if("${MODE}" STREQUAL "EXIST")
    # do nothing
  elseif("${MODE}" STREQUAL "COMPILE")
    set_compile_flags_var(${NAME})
  elseif("${MODE}" STREQUAL "LINK")
    set_link_flags_var(${NAME})
  else()
    message(FATAL_ERROR "Invalid mode argument ${MODE} given.")
  endif()

endif()

set(PACKAGE_QUIET ${SILENT} )
