Warning, /frameworks/extra-cmake-modules/modules/ECMGenerateHeaders.cmake is written in an unsupported language. File is not indexed.

0001 # SPDX-FileCopyrightText: 2013 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
0002 # SPDX-FileCopyrightText: 2014 Alex Merry <alex.merry@kdemail.net>
0003 # SPDX-FileCopyrightText: 2015 Patrick Spendrin <patrick.spendrin@kdab.com>
0004 #
0005 # SPDX-License-Identifier: BSD-3-Clause
0006 
0007 #[=======================================================================[.rst:
0008 ECMGenerateHeaders
0009 ------------------
0010 
0011 Generate C/C++ CamelCase forwarding headers.
0012 
0013 ::
0014 
0015   ecm_generate_headers(<camelcase_forwarding_headers_var>
0016       HEADER_NAMES <CamelCaseName> [<CamelCaseName> [...]]
0017       [ORIGINAL <CAMELCASE|LOWERCASE>]
0018       [HEADER_EXTENSION <header_extension>]
0019       [OUTPUT_DIR <output_dir>]
0020       [PREFIX <prefix>]
0021       [REQUIRED_HEADERS <variable>]
0022       [COMMON_HEADER <HeaderName>]
0023       [RELATIVE <relative_path>])
0024 
0025 For each CamelCase header name passed to ``HEADER_NAMES``, a file of that name
0026 will be generated that will include a version with ``.h`` or, if set,
0027 ``.<header_extension>`` appended.
0028 For example, the generated header ``ClassA`` will include ``classa.h`` (or
0029 ``ClassA.h``, see ``ORIGINAL``).
0030 If a CamelCaseName consists of multiple comma-separated files, e.g.
0031 ``ClassA,ClassB,ClassC``, then multiple camelcase header files will be
0032 generated which are redirects to the first header file.
0033 The file locations of these generated headers will be stored in
0034 <camelcase_forwarding_headers_var>.
0035 
0036 ``ORIGINAL`` specifies how the name of the original header is written: lowercased
0037 or also camelcased.  The default is "LOWERCASE". Since 1.8.0.
0038 
0039 ``HEADER_EXTENSION`` specifies what file name extension is used for the header
0040 files.  The default is "h". Since 5.48.0.
0041 
0042 ``PREFIX`` places the generated headers in subdirectories.  This should be a
0043 CamelCase name like ``KParts``, which will cause the CamelCase forwarding
0044 headers to be placed in the ``KParts`` directory (e.g. ``KParts/Part``).  It
0045 will also, for the convenience of code in the source distribution, generate
0046 forwarding headers based on the original names (e.g. ``kparts/part.h``).  This
0047 allows includes like ``"#include <kparts/part.h>"`` to be used before
0048 installation, as long as the include_directories are set appropriately.
0049 
0050 ``OUTPUT_DIR`` specifies where the files will be generated; this should be within
0051 the build directory. By default, ``${CMAKE_CURRENT_BINARY_DIR}`` will be used.
0052 This option can be used to avoid file conflicts.
0053 
0054 ``REQUIRED_HEADERS`` specifies an output variable name where all the required
0055 headers will be appended so that they can be installed together with the
0056 generated ones.  This is mostly intended as a convenience so that adding a new
0057 header to a project only requires specifying the CamelCase variant in the
0058 CMakeLists.txt file; the original variant will then be added to this
0059 variable.
0060 
0061 ``COMMON_HEADER`` generates an additional convenience header which includes all
0062 other header files.
0063 
0064 The ``RELATIVE`` argument indicates where the original headers can be found
0065 relative to ``CMAKE_CURRENT_SOURCE_DIR``.  It does not affect the generated
0066 CamelCase forwarding files, but ``ecm_generate_headers()`` uses it when checking
0067 that the original header exists, and to generate originally named forwarding
0068 headers when ``PREFIX`` is set.
0069 
0070 To allow other parts of the source distribution (eg: tests) to use the
0071 generated headers before installation, it may be desirable to set the
0072 ``INCLUDE_DIRECTORIES`` property for the library target to output_dir.  For
0073 example, if ``OUTPUT_DIR`` is ``CMAKE_CURRENT_BINARY_DIR`` (the default), you could do
0074 
0075 .. code-block:: cmake
0076 
0077   target_include_directories(MyLib PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
0078 
0079 Example usage (without ``PREFIX``):
0080 
0081 .. code-block:: cmake
0082 
0083   ecm_generate_headers(
0084       MyLib_FORWARDING_HEADERS
0085       HEADERS
0086           MLFoo
0087           MLBar
0088           # etc
0089       REQUIRED_HEADERS MyLib_HEADERS
0090       COMMON_HEADER MLGeneral
0091   )
0092   install(FILES ${MyLib_FORWARDING_HEADERS} ${MyLib_HEADERS}
0093           DESTINATION ${CMAKE_INSTALL_PREFIX}/include
0094           COMPONENT Devel)
0095 
0096 Example usage (with ``PREFIX``):
0097 
0098 .. code-block:: cmake
0099 
0100   ecm_generate_headers(
0101       MyLib_FORWARDING_HEADERS
0102       HEADERS
0103           Foo
0104           # several classes are contained in bar.h, so generate
0105           # additional files
0106           Bar,BarList
0107           # etc
0108       PREFIX MyLib
0109       REQUIRED_HEADERS MyLib_HEADERS
0110   )
0111   install(FILES ${MyLib_FORWARDING_HEADERS}
0112           DESTINATION ${CMAKE_INSTALL_PREFIX}/include/MyLib
0113           COMPONENT Devel)
0114   install(FILES ${MyLib_HEADERS}
0115           DESTINATION ${CMAKE_INSTALL_PREFIX}/include/mylib
0116           COMPONENT Devel)
0117 
0118 Since pre-1.0.0.
0119 #]=======================================================================]
0120 
0121 function(ECM_GENERATE_HEADERS camelcase_forwarding_headers_var)
0122     set(options)
0123     set(oneValueArgs ORIGINAL HEADER_EXTENSION OUTPUT_DIR PREFIX REQUIRED_HEADERS COMMON_HEADER RELATIVE)
0124     set(multiValueArgs HEADER_NAMES)
0125     cmake_parse_arguments(EGH "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
0126 
0127     if (EGH_UNPARSED_ARGUMENTS)
0128         message(FATAL_ERROR "Unexpected arguments to ECM_GENERATE_HEADERS: ${EGH_UNPARSED_ARGUMENTS}")
0129     endif()
0130 
0131     if(NOT EGH_HEADER_NAMES)
0132        message(FATAL_ERROR "Missing header_names argument to ECM_GENERATE_HEADERS")
0133     endif()
0134 
0135     if(NOT EGH_ORIGINAL)
0136         # default
0137         set(EGH_ORIGINAL "LOWERCASE")
0138     endif()
0139     if(NOT EGH_ORIGINAL STREQUAL "LOWERCASE" AND NOT EGH_ORIGINAL STREQUAL "CAMELCASE")
0140         message(FATAL_ERROR "Unexpected value for original argument to ECM_GENERATE_HEADERS: ${EGH_ORIGINAL}")
0141     endif()
0142 
0143     if(NOT EGH_HEADER_EXTENSION)
0144         set(EGH_HEADER_EXTENSION "h")
0145     endif()
0146 
0147     if(NOT EGH_OUTPUT_DIR)
0148         set(EGH_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
0149     endif()
0150 
0151     # Make sure EGH_RELATIVE is /-terminated when it's not empty
0152     if (EGH_RELATIVE AND NOT "${EGH_RELATIVE}" MATCHES "^.*/$")
0153         set(EGH_RELATIVE "${EGH_RELATIVE}/")
0154     endif()
0155 
0156     set(originalprefix)
0157     if (EGH_PREFIX)
0158         if (NOT "${EGH_PREFIX}" MATCHES "^.*/$")
0159             set(EGH_PREFIX "${EGH_PREFIX}/")
0160         endif()
0161         if (EGH_ORIGINAL STREQUAL "CAMELCASE")
0162             set(originalprefix "${EGH_PREFIX}")
0163         else()
0164             string(TOLOWER "${EGH_PREFIX}" originalprefix)
0165         endif()
0166     endif()
0167 
0168     foreach(_classnameentry ${EGH_HEADER_NAMES})
0169         string(REPLACE "," ";" _classnames ${_classnameentry})
0170         list(GET _classnames 0 _baseclass)
0171 
0172         if (EGH_ORIGINAL STREQUAL "CAMELCASE")
0173             set(originalbasename "${_baseclass}")
0174         else()
0175             string(TOLOWER "${_baseclass}" originalbasename)
0176         endif()
0177 
0178         set(_actualheader "${CMAKE_CURRENT_SOURCE_DIR}/${EGH_RELATIVE}${originalbasename}.${EGH_HEADER_EXTENSION}")
0179         if (NOT EXISTS ${_actualheader})
0180             message(FATAL_ERROR "Could not find \"${_actualheader}\"")
0181         endif()
0182 
0183         foreach(_CLASSNAME ${_classnames})
0184             set(FANCY_HEADER_FILE "${EGH_OUTPUT_DIR}/${EGH_PREFIX}${_CLASSNAME}")
0185             if (NOT EXISTS ${FANCY_HEADER_FILE})
0186                 file(WRITE ${FANCY_HEADER_FILE} "#include \"${originalprefix}${originalbasename}.${EGH_HEADER_EXTENSION}\"\n")
0187             endif()
0188             list(APPEND ${camelcase_forwarding_headers_var} "${FANCY_HEADER_FILE}")
0189             if (EGH_PREFIX)
0190                 # Local forwarding header, for namespaced headers, e.g. kparts/part.h
0191                 if(EGH_ORIGINAL STREQUAL "CAMELCASE")
0192                     set(originalclassname "${_CLASSNAME}")
0193                 else()
0194                     string(TOLOWER "${_CLASSNAME}" originalclassname)
0195                 endif()
0196                 set(REGULAR_HEADER_NAME ${EGH_OUTPUT_DIR}/${originalprefix}${originalclassname}.${EGH_HEADER_EXTENSION})
0197                 if (NOT EXISTS ${REGULAR_HEADER_NAME})
0198                     file(WRITE ${REGULAR_HEADER_NAME} "#include \"${_actualheader}\"\n")
0199                 endif()
0200             endif()
0201         endforeach()
0202 
0203         list(APPEND _REQUIRED_HEADERS "${_actualheader}")
0204     endforeach()
0205 
0206     if(EGH_COMMON_HEADER)
0207         #combine required headers into 1 big convenience header
0208         set(COMMON_HEADER ${EGH_OUTPUT_DIR}/${EGH_PREFIX}${EGH_COMMON_HEADER})
0209         file(WRITE ${COMMON_HEADER} "// convenience header\n")
0210         foreach(_header ${_REQUIRED_HEADERS})
0211             get_filename_component(_base ${_header} NAME)
0212             file(APPEND ${COMMON_HEADER} "#include \"${_base}\"\n")
0213         endforeach()
0214         list(APPEND ${camelcase_forwarding_headers_var} "${COMMON_HEADER}")
0215     endif()
0216 
0217     set(${camelcase_forwarding_headers_var} ${${camelcase_forwarding_headers_var}} PARENT_SCOPE)
0218     if (EGH_REQUIRED_HEADERS)
0219         set(${EGH_REQUIRED_HEADERS} ${${EGH_REQUIRED_HEADERS}} ${_REQUIRED_HEADERS} PARENT_SCOPE)
0220     endif ()
0221 endfunction()