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

#[=======================================================================[.rst:
GenerateExportHeader
--------------------

This module provides the ``generate_export_header()`` function to generate
export macros for libraries.

.. versionadded:: 3.12
  Added support for C projects.  Previous versions supported C++ project only.

.. command:: generate_export_header

  The ``generate_export_header()`` function can be used to generate a file
  suitable for preprocessor inclusion which contains EXPORT macros to be
  used in library classes:

  .. code-block:: cmake

    generate_export_header(LIBRARY_TARGET
             [BASE_NAME <base_name>]
             [EXPORT_MACRO_NAME <export_macro_name>]
             [EXPORT_FILE_NAME <export_file_name>]
             [DEPRECATED_MACRO_NAME <deprecated_macro_name>]
             [NO_EXPORT_MACRO_NAME <no_export_macro_name>]
             [INCLUDE_GUARD_NAME <include_guard_name>]
             [STATIC_DEFINE <static_define>]
             [NO_DEPRECATED_MACRO_NAME <no_deprecated_macro_name>]
             [DEFINE_NO_DEPRECATED]
             [PREFIX_NAME <prefix_name>]
             [CUSTOM_CONTENT_FROM_VARIABLE <variable>]
    )

The target properties :prop_tgt:`CXX_VISIBILITY_PRESET <<LANG>_VISIBILITY_PRESET>`
and :prop_tgt:`VISIBILITY_INLINES_HIDDEN` can be used to add the appropriate
compile flags for targets.  See the documentation of those target properties,
and the convenience variables
:variable:`CMAKE_CXX_VISIBILITY_PRESET <CMAKE_<LANG>_VISIBILITY_PRESET>` and
:variable:`CMAKE_VISIBILITY_INLINES_HIDDEN`.

By default ``generate_export_header()`` generates macro names in a file
name determined by the name of the library.  This means that in the
simplest case, users of ``GenerateExportHeader`` will be equivalent to:

.. code-block:: cmake

   set(CMAKE_CXX_VISIBILITY_PRESET hidden)
   set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
   add_library(somelib someclass.cpp)
   generate_export_header(somelib)
   install(TARGETS somelib DESTINATION ${LIBRARY_INSTALL_DIR})
   install(FILES
    someclass.h
    ${PROJECT_BINARY_DIR}/somelib_export.h DESTINATION ${INCLUDE_INSTALL_DIR}
   )


And in the ABI header files:

.. code-block:: c++

   #include "somelib_export.h"
   class SOMELIB_EXPORT SomeClass {
     ...
   };


The CMake fragment will generate a file in the
``${CMAKE_CURRENT_BINARY_DIR}`` called ``somelib_export.h`` containing the
macros ``SOMELIB_EXPORT``, ``SOMELIB_NO_EXPORT``, ``SOMELIB_DEPRECATED``,
``SOMELIB_DEPRECATED_EXPORT`` and ``SOMELIB_DEPRECATED_NO_EXPORT``.
They will be followed by content taken from the variable specified by
the ``CUSTOM_CONTENT_FROM_VARIABLE`` option, if any.
The resulting file should be installed with other headers in the library.

The ``BASE_NAME`` argument can be used to override the file name and the
names used for the macros:

.. code-block:: cmake

   add_library(somelib someclass.cpp)
   generate_export_header(somelib
     BASE_NAME other_name
   )


Generates a file called ``other_name_export.h`` containing the macros
``OTHER_NAME_EXPORT``, ``OTHER_NAME_NO_EXPORT`` and ``OTHER_NAME_DEPRECATED``
etc.

The ``BASE_NAME`` may be overridden by specifying other options in the
function.  For example:

.. code-block:: cmake

   add_library(somelib someclass.cpp)
   generate_export_header(somelib
     EXPORT_MACRO_NAME OTHER_NAME_EXPORT
   )


creates the macro ``OTHER_NAME_EXPORT`` instead of ``SOMELIB_EXPORT``, but
other macros and the generated file name is as default:

.. code-block:: cmake

   add_library(somelib someclass.cpp)
   generate_export_header(somelib
     DEPRECATED_MACRO_NAME KDE_DEPRECATED
   )


creates the macro ``KDE_DEPRECATED`` instead of ``SOMELIB_DEPRECATED``.

If ``LIBRARY_TARGET`` is a static library, macros are defined without
values.

If the same sources are used to create both a shared and a static
library, the uppercased symbol ``${BASE_NAME}_STATIC_DEFINE`` should be
used when building the static library:

.. code-block:: cmake

   add_library(shared_variant SHARED ${lib_SRCS})
   add_library(static_variant ${lib_SRCS})
   generate_export_header(shared_variant BASE_NAME libshared_and_static)
   set_target_properties(static_variant PROPERTIES
     COMPILE_FLAGS -DLIBSHARED_AND_STATIC_STATIC_DEFINE)

This will cause the export macros to expand to nothing when building
the static library.

If ``DEFINE_NO_DEPRECATED`` is specified, then a macro
``${BASE_NAME}_NO_DEPRECATED`` will be defined This macro can be used to
remove deprecated code from preprocessor output:

.. code-block:: cmake

   option(EXCLUDE_DEPRECATED "Exclude deprecated parts of the library" FALSE)
   if (EXCLUDE_DEPRECATED)
     set(NO_BUILD_DEPRECATED DEFINE_NO_DEPRECATED)
   endif()
   generate_export_header(somelib ${NO_BUILD_DEPRECATED})


And then in somelib:

.. code-block:: c++

   class SOMELIB_EXPORT SomeClass
   {
   public:
   #ifndef SOMELIB_NO_DEPRECATED
     SOMELIB_DEPRECATED void oldMethod();
   #endif
   };

.. code-block:: c++

   #ifndef SOMELIB_NO_DEPRECATED
   void SomeClass::oldMethod() {  }
   #endif


If ``PREFIX_NAME`` is specified, the argument will be used as a prefix to
all generated macros.

For example:

.. code-block:: cmake

   generate_export_header(somelib PREFIX_NAME VTK_)

Generates the macros ``VTK_SOMELIB_EXPORT`` etc.

.. versionadded:: 3.1
  Library target can be an ``OBJECT`` library.

.. versionadded:: 3.7
  Added the ``CUSTOM_CONTENT_FROM_VARIABLE`` option.

.. versionadded:: 3.11
  Added the ``INCLUDE_GUARD_NAME`` option.

.. command:: add_compiler_export_flags

  .. code-block:: cmake

    add_compiler_export_flags([<output_variable>])

  .. deprecated:: 3.0

    Set the target properties
    :prop_tgt:`CXX_VISIBILITY_PRESET <<LANG>_VISIBILITY_PRESET>` and
    :prop_tgt:`VISIBILITY_INLINES_HIDDEN` instead.

The ``add_compiler_export_flags()`` function adds ``-fvisibility=hidden`` to
:variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` if supported, and is a no-op
on Windows which does not need extra compiler flags for exporting support.
You may optionally pass a single argument to ``add_compiler_export_flags()``
that will be populated with the ``CXX_FLAGS`` required to enable visibility
support for the compiler/architecture in use.
#]=======================================================================]

include(CheckCompilerFlag)
include(CheckSourceCompiles)

# TODO: Install this macro separately?
macro(_check_cxx_compiler_attribute _ATTRIBUTE _RESULT)
  check_source_compiles(CXX "${_ATTRIBUTE} int somefunc() { return 0; }
    int main() { return somefunc();}" ${_RESULT}
  )
endmacro()

# TODO: Install this macro separately?
macro(_check_c_compiler_attribute _ATTRIBUTE _RESULT)
  check_source_compiles(C "${_ATTRIBUTE} int somefunc(void) { return 0; }
    int main(void) { return somefunc();}" ${_RESULT}
  )
endmacro()

macro(_test_compiler_hidden_visibility)

  if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.2")
    set(GCC_TOO_OLD TRUE)
  elseif(CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.2")
    set(GCC_TOO_OLD TRUE)
  elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0")
    set(_INTEL_TOO_OLD TRUE)
  endif()

  # Exclude XL here because it misinterprets -fvisibility=hidden even though
  # the check_compiler_flag passes
  if(NOT GCC_TOO_OLD
      AND NOT _INTEL_TOO_OLD
      AND NOT WIN32
      AND NOT CYGWIN
      AND NOT CMAKE_CXX_COMPILER_ID MATCHES "^(IBMClang|XLClang|XL)$"
      AND NOT CMAKE_CXX_COMPILER_ID MATCHES "^(PGI|NVHPC)$"
      AND NOT CMAKE_CXX_COMPILER_ID MATCHES Watcom)
    if (CMAKE_CXX_COMPILER_LOADED)
      check_compiler_flag(CXX -fvisibility=hidden COMPILER_HAS_HIDDEN_VISIBILITY)
      check_compiler_flag(CXX -fvisibility-inlines-hidden
        COMPILER_HAS_HIDDEN_INLINE_VISIBILITY)
    else()
      check_compiler_flag(C -fvisibility=hidden COMPILER_HAS_HIDDEN_VISIBILITY)
      check_compiler_flag(C -fvisibility-inlines-hidden
        COMPILER_HAS_HIDDEN_INLINE_VISIBILITY)
    endif()
  endif()
endmacro()

macro(_test_compiler_has_deprecated)
  # NOTE:  Some Embarcadero compilers silently compile __declspec(deprecated)
  # without error, but this is not a documented feature and the attribute does
  # not actually generate any warnings.
  if(CMAKE_CXX_COMPILER_ID MATCHES Borland
      OR CMAKE_CXX_COMPILER_ID MATCHES Embarcadero
      OR CMAKE_CXX_COMPILER_ID MATCHES HP
      OR GCC_TOO_OLD
      OR CMAKE_CXX_COMPILER_ID MATCHES "^(PGI|NVHPC)$"
      OR CMAKE_CXX_COMPILER_ID MATCHES Watcom)
    set(COMPILER_HAS_DEPRECATED "" CACHE INTERNAL
      "Compiler support for a deprecated attribute")
  else()
    if (CMAKE_CXX_COMPILER_LOADED)
      _check_cxx_compiler_attribute("__attribute__((__deprecated__))"
        COMPILER_HAS_DEPRECATED_ATTR)
      if(COMPILER_HAS_DEPRECATED_ATTR)
        set(COMPILER_HAS_DEPRECATED "${COMPILER_HAS_DEPRECATED_ATTR}"
          CACHE INTERNAL "Compiler support for a deprecated attribute")
      else()
        _check_cxx_compiler_attribute("__declspec(deprecated)"
          COMPILER_HAS_DEPRECATED)
      endif()
    else()
      _check_c_compiler_attribute("__attribute__((__deprecated__))"
        COMPILER_HAS_DEPRECATED_ATTR)
      if(COMPILER_HAS_DEPRECATED_ATTR)
        set(COMPILER_HAS_DEPRECATED "${COMPILER_HAS_DEPRECATED_ATTR}"
          CACHE INTERNAL "Compiler support for a deprecated attribute")
      else()
        _check_c_compiler_attribute("__declspec(deprecated)"
          COMPILER_HAS_DEPRECATED)
      endif()

    endif()
  endif()
endmacro()

get_filename_component(_GENERATE_EXPORT_HEADER_MODULE_DIR
  "${CMAKE_CURRENT_LIST_FILE}" PATH)

macro(_DO_SET_MACRO_VALUES TARGET_LIBRARY)
  set(DEFINE_DEPRECATED)
  set(DEFINE_EXPORT)
  set(DEFINE_IMPORT)
  set(DEFINE_NO_EXPORT)

  if (COMPILER_HAS_DEPRECATED_ATTR AND NOT WIN32)
    set(DEFINE_DEPRECATED "__attribute__ ((__deprecated__))")
  elseif(COMPILER_HAS_DEPRECATED)
    set(DEFINE_DEPRECATED "__declspec(deprecated)")
  endif()

  get_property(type TARGET ${TARGET_LIBRARY} PROPERTY TYPE)

  if(NOT ${type} STREQUAL "STATIC_LIBRARY")
    if(WIN32 OR CYGWIN)
      set(DEFINE_EXPORT "__declspec(dllexport)")
      set(DEFINE_IMPORT "__declspec(dllimport)")
    elseif(COMPILER_HAS_HIDDEN_VISIBILITY)
      set(DEFINE_EXPORT "__attribute__((visibility(\"default\")))")
      set(DEFINE_IMPORT "__attribute__((visibility(\"default\")))")
      set(DEFINE_NO_EXPORT "__attribute__((visibility(\"hidden\")))")
    endif()
  endif()
endmacro()

macro(_DO_GENERATE_EXPORT_HEADER TARGET_LIBRARY)
  # Option overrides
  set(options DEFINE_NO_DEPRECATED)
  set(oneValueArgs PREFIX_NAME BASE_NAME EXPORT_MACRO_NAME EXPORT_FILE_NAME
    DEPRECATED_MACRO_NAME NO_EXPORT_MACRO_NAME STATIC_DEFINE
    NO_DEPRECATED_MACRO_NAME CUSTOM_CONTENT_FROM_VARIABLE INCLUDE_GUARD_NAME)
  set(multiValueArgs)

  cmake_parse_arguments(_GEH "${options}" "${oneValueArgs}" "${multiValueArgs}"
    ${ARGN})

  set(BASE_NAME "${TARGET_LIBRARY}")

  if(_GEH_BASE_NAME)
    set(BASE_NAME ${_GEH_BASE_NAME})
  endif()

  string(TOUPPER ${BASE_NAME} BASE_NAME_UPPER)
  string(TOLOWER ${BASE_NAME} BASE_NAME_LOWER)

  # Default options
  set(EXPORT_MACRO_NAME "${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_EXPORT")
  set(NO_EXPORT_MACRO_NAME "${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_NO_EXPORT")
  set(EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME_LOWER}_export.h")
  set(DEPRECATED_MACRO_NAME "${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_DEPRECATED")
  set(STATIC_DEFINE "${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_STATIC_DEFINE")
  set(NO_DEPRECATED_MACRO_NAME
    "${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_NO_DEPRECATED")

  if(_GEH_UNPARSED_ARGUMENTS)
    message(FATAL_ERROR "Unknown keywords given to generate_export_header(): \"${_GEH_UNPARSED_ARGUMENTS}\"")
  endif()

  if(_GEH_EXPORT_MACRO_NAME)
    set(EXPORT_MACRO_NAME ${_GEH_PREFIX_NAME}${_GEH_EXPORT_MACRO_NAME})
  endif()
  string(MAKE_C_IDENTIFIER ${EXPORT_MACRO_NAME} EXPORT_MACRO_NAME)
  if(_GEH_EXPORT_FILE_NAME)
    if(IS_ABSOLUTE ${_GEH_EXPORT_FILE_NAME})
      set(EXPORT_FILE_NAME ${_GEH_EXPORT_FILE_NAME})
    else()
      set(EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/${_GEH_EXPORT_FILE_NAME}")
    endif()
  endif()
  if(_GEH_DEPRECATED_MACRO_NAME)
    set(DEPRECATED_MACRO_NAME ${_GEH_PREFIX_NAME}${_GEH_DEPRECATED_MACRO_NAME})
  endif()
  string(MAKE_C_IDENTIFIER ${DEPRECATED_MACRO_NAME} DEPRECATED_MACRO_NAME)
  if(_GEH_NO_EXPORT_MACRO_NAME)
    set(NO_EXPORT_MACRO_NAME ${_GEH_PREFIX_NAME}${_GEH_NO_EXPORT_MACRO_NAME})
  endif()
  string(MAKE_C_IDENTIFIER ${NO_EXPORT_MACRO_NAME} NO_EXPORT_MACRO_NAME)
  if(_GEH_STATIC_DEFINE)
    set(STATIC_DEFINE ${_GEH_PREFIX_NAME}${_GEH_STATIC_DEFINE})
  endif()
  string(MAKE_C_IDENTIFIER ${STATIC_DEFINE} STATIC_DEFINE)

  if(_GEH_DEFINE_NO_DEPRECATED)
    set(DEFINE_NO_DEPRECATED 1)
  else()
    set(DEFINE_NO_DEPRECATED 0)
  endif()

  if(_GEH_NO_DEPRECATED_MACRO_NAME)
    set(NO_DEPRECATED_MACRO_NAME
      ${_GEH_PREFIX_NAME}${_GEH_NO_DEPRECATED_MACRO_NAME})
  endif()
  string(MAKE_C_IDENTIFIER ${NO_DEPRECATED_MACRO_NAME} NO_DEPRECATED_MACRO_NAME)

  if(_GEH_INCLUDE_GUARD_NAME)
    set(INCLUDE_GUARD_NAME ${_GEH_INCLUDE_GUARD_NAME})
  else()
    set(INCLUDE_GUARD_NAME "${EXPORT_MACRO_NAME}_H")
  endif()

  get_target_property(EXPORT_IMPORT_CONDITION ${TARGET_LIBRARY} DEFINE_SYMBOL)

  if(NOT EXPORT_IMPORT_CONDITION)
    set(EXPORT_IMPORT_CONDITION ${TARGET_LIBRARY}_EXPORTS)
  endif()
  string(MAKE_C_IDENTIFIER ${EXPORT_IMPORT_CONDITION} EXPORT_IMPORT_CONDITION)

  if(_GEH_CUSTOM_CONTENT_FROM_VARIABLE)
    if(DEFINED "${_GEH_CUSTOM_CONTENT_FROM_VARIABLE}")
      set(CUSTOM_CONTENT "${${_GEH_CUSTOM_CONTENT_FROM_VARIABLE}}")
    else()
      set(CUSTOM_CONTENT "")
    endif()
  endif()

  configure_file("${_GENERATE_EXPORT_HEADER_MODULE_DIR}/exportheader.cmake.in"
    "${EXPORT_FILE_NAME}" @ONLY)
endmacro()

function(GENERATE_EXPORT_HEADER TARGET_LIBRARY)
  get_property(type TARGET ${TARGET_LIBRARY} PROPERTY TYPE)
  if(NOT ${type} STREQUAL "STATIC_LIBRARY"
      AND NOT ${type} STREQUAL "SHARED_LIBRARY"
      AND NOT ${type} STREQUAL "OBJECT_LIBRARY"
      AND NOT ${type} STREQUAL "MODULE_LIBRARY")
    message(WARNING "This macro can only be used with libraries")
    return()
  endif()
  _test_compiler_hidden_visibility()
  _test_compiler_has_deprecated()
  _do_set_macro_values(${TARGET_LIBRARY})
  _do_generate_export_header(${TARGET_LIBRARY} ${ARGN})
endfunction()

function(add_compiler_export_flags)
  if(NOT CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
    message(DEPRECATION "The add_compiler_export_flags function is obsolete. Use the CXX_VISIBILITY_PRESET and VISIBILITY_INLINES_HIDDEN target properties instead.")
  endif()

  _test_compiler_hidden_visibility()
  _test_compiler_has_deprecated()

  option(USE_COMPILER_HIDDEN_VISIBILITY
    "Use HIDDEN visibility support if available." ON)
  mark_as_advanced(USE_COMPILER_HIDDEN_VISIBILITY)
  if(NOT (USE_COMPILER_HIDDEN_VISIBILITY AND COMPILER_HAS_HIDDEN_VISIBILITY))
    # Just return if there are no flags to add.
    return()
  endif()

  set (EXTRA_FLAGS "-fvisibility=hidden")

  if(COMPILER_HAS_HIDDEN_INLINE_VISIBILITY)
    set (EXTRA_FLAGS "${EXTRA_FLAGS} -fvisibility-inlines-hidden")
  endif()

  # Either return the extra flags needed in the supplied argument, or to the
  # CMAKE_CXX_FLAGS if no argument is supplied.
  if(ARGC GREATER 0)
    set(${ARGV0} "${EXTRA_FLAGS}" PARENT_SCOPE)
  else()
    string(APPEND CMAKE_CXX_FLAGS " ${EXTRA_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" PARENT_SCOPE)
  endif()
endfunction()

# FIXME(#24994): The following module(s) are included only for compatibility
# with projects that accidentally relied on them with CMake 3.26 and below.
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
