#.rst: # ECMGenerateHeaders # ------------------ # # Generate C/C++ CamelCase forwarding headers. # # :: # # ecm_generate_headers( # HEADER_NAMES [ [...]] # [ORIGINAL ] # [OUTPUT_DIR ] # [PREFIX ] # [REQUIRED_HEADERS ] # [COMMON_HEADER ] # [RELATIVE ]) # # For each CamelCase header name passed to HEADER_NAMES, a file of that name # will be generated that will include a version with ``.h`` appended. # For example, the generated header ``ClassA`` will include ``classa.h`` (or # ``ClassA.h``, see ORIGINAL). # If a CamelCaseName consists of multiple comma-separated files, e.g. # ``ClassA,ClassB,ClassC``, then multiple camelcase header files will be # generated which are redirects to the first header file. # The file locations of these generated headers will be stored in # . # # ORIGINAL specifies how the name of the original header is written: lowercased # or also camelcased. The default is LOWERCASE. Since 1.8.0. # # PREFIX places the generated headers in subdirectories. This should be a # CamelCase name like ``KParts``, which will cause the CamelCase forwarding # headers to be placed in the ``KParts`` directory (e.g. ``KParts/Part``). It # will also, for the convenience of code in the source distribution, generate # forwarding headers based on the original names (e.g. ``kparts/part.h``). This # allows includes like ``"#include "`` to be used before # installation, as long as the include_directories are set appropriately. # # OUTPUT_DIR specifies where the files will be generated; this should be within # the build directory. By default, ``${CMAKE_CURRENT_BINARY_DIR}`` will be used. # This option can be used to avoid file conflicts. # # REQUIRED_HEADERS specifies an output variable name where all the required # headers will be appended so that they can be installed together with the # generated ones. This is mostly intended as a convenience so that adding a new # header to a project only requires specifying the CamelCase variant in the # CMakeLists.txt file; the original variant will then be added to this # variable. # # COMMON_HEADER generates an additional convenience header which includes all # other header files. # # The RELATIVE argument indicates where the original headers can be found # relative to CMAKE_CURRENT_SOURCE_DIR. It does not affect the generated # CamelCase forwarding files, but ecm_generate_headers() uses it when checking # that the original header exists, and to generate originally named forwarding # headers when PREFIX is set. # # To allow other parts of the source distribution (eg: tests) to use the # generated headers before installation, it may be desirable to set the # INCLUDE_DIRECTORIES property for the library target to output_dir. For # example, if OUTPUT_DIR is CMAKE_CURRENT_BINARY_DIR (the default), you could do # # .. code-block:: cmake # # target_include_directories(MyLib PUBLIC "$") # # Example usage (without PREFIX): # # .. code-block:: cmake # # ecm_generate_headers( # MyLib_FORWARDING_HEADERS # HEADERS # MLFoo # MLBar # # etc # REQUIRED_HEADERS MyLib_HEADERS # COMMON_HEADER MLGeneral # ) # install(FILES ${MyLib_FORWARDING_HEADERS} ${MyLib_HEADERS} # DESTINATION ${CMAKE_INSTALL_PREFIX}/include # COMPONENT Devel) # # Example usage (with PREFIX): # # .. code-block:: cmake # # ecm_generate_headers( # MyLib_FORWARDING_HEADERS # HEADERS # Foo # # several classes are contained in bar.h, so generate # # additional files # Bar,BarList # # etc # PREFIX MyLib # REQUIRED_HEADERS MyLib_HEADERS # ) # install(FILES ${MyLib_FORWARDING_HEADERS} # DESTINATION ${CMAKE_INSTALL_PREFIX}/include/MyLib # COMPONENT Devel) # install(FILES ${MyLib_HEADERS} # DESTINATION ${CMAKE_INSTALL_PREFIX}/include/mylib # COMPONENT Devel) # # Since pre-1.0.0. #============================================================================= # Copyright 2013 Aleix Pol Gonzalez # Copyright 2014 Alex Merry # Copyright 2015 Patrick Spendrin # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. The name of the author may not be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. include(CMakeParseArguments) function(ECM_GENERATE_HEADERS camelcase_forwarding_headers_var) set(options) set(oneValueArgs ORIGINAL OUTPUT_DIR PREFIX REQUIRED_HEADERS COMMON_HEADER RELATIVE) set(multiValueArgs HEADER_NAMES) cmake_parse_arguments(EGH "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if (EGH_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unexpected arguments to ECM_GENERATE_HEADERS: ${EGH_UNPARSED_ARGUMENTS}") endif() if(NOT EGH_HEADER_NAMES) message(FATAL_ERROR "Missing header_names argument to ECM_GENERATE_HEADERS") endif() if(NOT EGH_ORIGINAL) # default set(EGH_ORIGINAL "LOWERCASE") endif() if(NOT EGH_ORIGINAL STREQUAL "LOWERCASE" AND NOT EGH_ORIGINAL STREQUAL "CAMELCASE") message(FATAL_ERROR "Unexpected value for original argument to ECM_GENERATE_HEADERS: ${EGH_ORIGINAL}") endif() if(NOT EGH_OUTPUT_DIR) set(EGH_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}") endif() # Make sure EGH_RELATIVE is /-terminated when it's not empty if (EGH_RELATIVE AND NOT "${EGH_RELATIVE}" MATCHES "^.*/$") set(EGH_RELATIVE "${EGH_RELATIVE}/") endif() if (EGH_PREFIX) if (NOT "${EGH_PREFIX}" MATCHES "^.*/$") set(EGH_PREFIX "${EGH_PREFIX}/") endif() if (EGH_ORIGINAL STREQUAL "CAMELCASE") set(originalprefix "${EGH_PREFIX}") else() string(TOLOWER "${EGH_PREFIX}" originalprefix) endif() endif() foreach(_classnameentry ${EGH_HEADER_NAMES}) string(REPLACE "," ";" _classnames ${_classnameentry}) list(GET _classnames 0 _baseclass) if (EGH_ORIGINAL STREQUAL "CAMELCASE") set(originalbasename "${_baseclass}") else() string(TOLOWER "${_baseclass}" originalbasename) endif() set(_actualheader "${CMAKE_CURRENT_SOURCE_DIR}/${EGH_RELATIVE}${originalbasename}.h") if (NOT EXISTS ${_actualheader}) message(FATAL_ERROR "Could not find \"${_actualheader}\"") endif() foreach(_CLASSNAME ${_classnames}) set(FANCY_HEADER_FILE "${EGH_OUTPUT_DIR}/${EGH_PREFIX}${_CLASSNAME}") if (NOT EXISTS ${FANCY_HEADER_FILE}) file(WRITE ${FANCY_HEADER_FILE} "#include \"${originalprefix}${originalbasename}.h\"\n") endif() list(APPEND ${camelcase_forwarding_headers_var} "${FANCY_HEADER_FILE}") if (EGH_PREFIX) # Local forwarding header, for namespaced headers, e.g. kparts/part.h if(EGH_ORIGINAL STREQUAL "CAMELCASE") set(originalclassname "${_CLASSNAME}") else() string(TOLOWER "${_CLASSNAME}" originalclassname) endif() set(REGULAR_HEADER_NAME ${EGH_OUTPUT_DIR}/${originalprefix}${originalclassname}.h) if (NOT EXISTS ${REGULAR_HEADER_NAME}) file(WRITE ${REGULAR_HEADER_NAME} "#include \"${_actualheader}\"\n") endif() endif() endforeach() list(APPEND _REQUIRED_HEADERS "${_actualheader}") endforeach() if(EGH_COMMON_HEADER) #combine required headers into 1 big convenience header set(COMMON_HEADER ${EGH_OUTPUT_DIR}/${EGH_PREFIX}${EGH_COMMON_HEADER}) file(WRITE ${COMMON_HEADER} "// convenience header\n") foreach(_header ${_REQUIRED_HEADERS}) get_filename_component(_base ${_header} NAME) file(APPEND ${COMMON_HEADER} "#include \"${_base}\"\n") endforeach() list(APPEND ${camelcase_forwarding_headers_var} "${COMMON_HEADER}") endif() set(${camelcase_forwarding_headers_var} ${${camelcase_forwarding_headers_var}} PARENT_SCOPE) if (NOT EGH_REQUIRED_HEADERS STREQUAL "") set(${EGH_REQUIRED_HEADERS} ${${EGH_REQUIRED_HEADERS}} ${_REQUIRED_HEADERS} PARENT_SCOPE) endif () endfunction()