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 get_source_file_property(_generated "${_actualheader}" GENERATED)
0180 if (NOT _generated AND NOT EXISTS ${_actualheader})
0181 message(FATAL_ERROR "Could not find \"${_actualheader}\"")
0182 endif()
0183
0184 foreach(_CLASSNAME ${_classnames})
0185 set(FANCY_HEADER_FILE "${EGH_OUTPUT_DIR}/${EGH_PREFIX}${_CLASSNAME}")
0186 if (NOT EXISTS ${FANCY_HEADER_FILE})
0187 file(WRITE ${FANCY_HEADER_FILE} "#include \"${originalprefix}${originalbasename}.${EGH_HEADER_EXTENSION}\"\n")
0188 endif()
0189 list(APPEND ${camelcase_forwarding_headers_var} "${FANCY_HEADER_FILE}")
0190 if (EGH_PREFIX)
0191 # Local forwarding header, for namespaced headers, e.g. kparts/part.h
0192 if(EGH_ORIGINAL STREQUAL "CAMELCASE")
0193 set(originalclassname "${_CLASSNAME}")
0194 else()
0195 string(TOLOWER "${_CLASSNAME}" originalclassname)
0196 endif()
0197 set(REGULAR_HEADER_NAME ${EGH_OUTPUT_DIR}/${originalprefix}${originalclassname}.${EGH_HEADER_EXTENSION})
0198 if (NOT EXISTS ${REGULAR_HEADER_NAME})
0199 file(WRITE ${REGULAR_HEADER_NAME} "#include \"${_actualheader}\"\n")
0200 endif()
0201 endif()
0202 endforeach()
0203
0204 list(APPEND _REQUIRED_HEADERS "${_actualheader}")
0205 endforeach()
0206
0207 if(EGH_COMMON_HEADER)
0208 #combine required headers into 1 big convenience header
0209 set(COMMON_HEADER ${EGH_OUTPUT_DIR}/${EGH_PREFIX}${EGH_COMMON_HEADER})
0210 file(WRITE ${COMMON_HEADER} "// convenience header\n")
0211 foreach(_header ${_REQUIRED_HEADERS})
0212 get_filename_component(_base ${_header} NAME)
0213 file(APPEND ${COMMON_HEADER} "#include \"${_base}\"\n")
0214 endforeach()
0215 list(APPEND ${camelcase_forwarding_headers_var} "${COMMON_HEADER}")
0216 endif()
0217
0218 set(${camelcase_forwarding_headers_var} ${${camelcase_forwarding_headers_var}} PARENT_SCOPE)
0219 if (EGH_REQUIRED_HEADERS)
0220 set(${EGH_REQUIRED_HEADERS} ${${EGH_REQUIRED_HEADERS}} ${_REQUIRED_HEADERS} PARENT_SCOPE)
0221 endif ()
0222 endfunction()