diff options
4 files changed, 349 insertions, 9 deletions
diff --git a/modules/ECMQtDeclareLoggingCategory.cmake b/modules/ECMQtDeclareLoggingCategory.cmake index 0db401c4..2bee4f93 100644 --- a/modules/ECMQtDeclareLoggingCategory.cmake +++ b/modules/ECMQtDeclareLoggingCategory.cmake @@ -2,17 +2,25 @@  # ECMQtDeclareLoggingCategory  # ---------------------------  # -# Generate declarations for logging categories in Qt5. +# This module provides the ``ecm_qt_declare_logging_category`` function for +# generating declarations for logging categories in Qt5, and the +# ``ecm_qt_install_logging_categories`` function for generating and installing +# a file in KDebugSettings format with the info about all those categories, +# as well as a file with info about any renamed categories if defined. +# To include in that file any logging categories that are manually defined +# also a function ``ecm_qt_export_logging_category`` is provided.  #  # ::  #  #   ecm_qt_declare_logging_category(<sources_var> -#                                   HEADER <filename> -#                                   IDENTIFIER <identifier> -#                                   CATEGORY_NAME <category_name> -#                                   [DEFAULT_SEVERITY -#                                        <Debug|Info|Warning| -#                                         Critical|Fatal>]) +#       HEADER <filename> +#       IDENTIFIER <identifier> +#       CATEGORY_NAME <category_name> +#       [OLD_CATEGORY_NAMES <oldest_cat_name> [<second_oldest_cat_name> [...]]] +#       [DEFAULT_SEVERITY <Debug|Info|Warning|Critical|Fatal>] +#       [EXPORT <exportid>] +#       [DESCRIPTION <description>] +#   )  #  # A header file, ``<filename>``, will be generated along with a corresponding  # source file, which will be added to ``<sources_var>``. These will provide a @@ -30,10 +38,109 @@  #  # ``<identifier>`` may include namespaces (eg: ``foo::bar::IDENT``).  # +# If ``EXPORT`` is passed, the category will be registered for the group id +# ``<exportid>``. Info about the categories of that group can then be +# generated in a file and installed by that group id with the +# ``ecm_qt_install_logging_categories`` function. In that case also ``DESCRIPTION`` +# will need to be passed, with ``<description>`` being a short single line text. +# And ``OLD_CATEGORY_NAMES`` can be used to inform about any renamings of the category, +# so user settings can be migrated. Since 5.68.0. +#  # Since 5.14.0. +# +# :: +# +#   ecm_qt_export_logging_category( +#       IDENTIFIER <identifier> +#       CATEGORY_NAME <category_name> +#       [OLD_CATEGORY_NAMES <oldest_category_name> [<second_oldest_category_name> [...]]] +#       EXPORT <exportid> +#       DESCRIPTION <description> +#       [DEFAULT_SEVERITY <Debug|Info|Warning|Critical|Fatal>] +#   ) +# +# Registers a logging category for being included in the generated and +# installed KDebugSettings files. To be used for categories who are declared by +# manual code or other ways instead of code generated with +# ``ecm_qt_declare_logging_category``. +# +# ``<identifier>`` may include namespaces (eg: ``foo::bar::IDENT``). +# +# ``EXPORT`` specifies the group id with which the category will be registered. +# Info about the categories of that group can then be generated in a file and +# installed by that group id with the ``ecm_qt_install_logging_categories`` function. +# +# ``DESCRIPTION`` specifies a short single line text describing the category. +# +# ``OLD_CATEGORY_NAMES`` can be used to inform about any renamings of the category, +# so user settings can be migrated. +# +# Since 5.68.0. +# +# :: +# +#   ecm_qt_install_logging_categories( +#       EXPORT <exportid> +#       [FILE <filename>] +#       DESTINATION <install_path> +#       [SORT] +#       [COMPONENT <component>] +#   ) +# +# Generates and installs a file in KDebugSettings format with the info about all +# the categories registered for the group ``<exportid>``, as well as a file with +# info about any renamed categories, if there are. +# +# The method call needs to be after the last ``ecm_qt_declare_logging_category`` +# call which uses the same ``<exportid>``. This can be in the same directory, or +# any subdirectory or parent directory. +# +# ``EXPORT`` specifies the group id of categories whose informatipn should be +# stored in the file generated and installed. +# +# ``FILE`` specifies the name of the file generated and installed. It will default +# to lower-cased ``<exportid>.categories``. +# +# ``DESTINATION`` specifies where the generated file will be +# installed. +# +# IF ``SORT`` is set, entries will be sorted by identifiers. +# +# ``COMPONENT`` specifies the installation component name with which the install +# rules for the generated file are associated. +# +# Example usage: +# +# .. code-block:: cmake +# +#   ecm_qt_declare_logging_category( +#       MYPROJECT_SRCS +#       HEADER "myproject_debug.h" +#       IDENTIFIER "MYPROJECT_DEBUG" +#       CATEGORY_NAME "myproject" +#       OLD_CATEGORY_NAMES "myprojectlog" +#       DESCRIPTION "My project" +#       EXPORT MyProject +#   ) +# +#   ecm_qt_export_logging_category( +#       IDENTIFIER "MYPROJECT_SUBMODULE_DEBUG" +#       CATEGORY_NAME "myproject.submodule" +#       DESCRIPTION "My project - submodule" +#       EXPORT MyProject +#   ) +# +#   ecm_qt_install_logging_categories( +#       EXPORT MyProject +#       FILE myproject.categories +#       DESTINATION "${KDE_INSTALL_LOGGINGCATEGORIESDIR}" +#   ) +# +# Since 5.68.0.  #=============================================================================  # Copyright 2015 Alex Merry <alex.merry@kde.org> +# Copyright 2020 Friedrich W. H. Kossebau <kossebau@kde.org>  #  # Redistribution and use in source and binary forms, with or without  # modification, are permitted provided that the following conditions @@ -63,10 +170,55 @@ include(CMakeParseArguments)  set(_ECM_QT_DECLARE_LOGGING_CATEGORY_TEMPLATE_CPP "${CMAKE_CURRENT_LIST_DIR}/ECMQtDeclareLoggingCategory.cpp.in")  set(_ECM_QT_DECLARE_LOGGING_CATEGORY_TEMPLATE_H   "${CMAKE_CURRENT_LIST_DIR}/ECMQtDeclareLoggingCategory.h.in") +function(ecm_qt_export_logging_category) +    set(options) +    set(oneValueArgs IDENTIFIER CATEGORY_NAME DEFAULT_SEVERITY EXPORT DESCRIPTION) +    set(multiValueArgs OLD_CATEGORY_NAMES) +    cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + +    if(ARG_UNPARSED_ARGUMENTS) +        message(FATAL_ERROR "Unexpected arguments to ecm_qt_export_logging_category: ${ARG_UNPARSED_ARGUMENTS}") +    endif() +    if(NOT ARG_IDENTIFIER) +        message(FATAL_ERROR "Missing IDENTIFIER argument for ecm_qt_export_logging_category") +    endif() +    if(NOT ARG_CATEGORY_NAME) +        message(FATAL_ERROR "Missing CATEGORY_NAME argument for ecm_qt_export_logging_category") +    endif() +    if(NOT ARG_DEFAULT_SEVERITY) +        set(ARG_DEFAULT_SEVERITY Info) +        set(is_explicite_default_severity FALSE) +    else() +        set(acceptible_severities Debug Info Warning Critical Fatal) +        list(FIND acceptible_severities "${ARG_DEFAULT_SEVERITY}" pos) +        if (pos EQUAL -1) +            message(FATAL_ERROR "Unknown DEFAULT_SEVERITY ${pos}") +        endif() +        set(is_explicite_default_severity TRUE) +    endif() +    if(NOT ARG_EXPORT) +        message(FATAL_ERROR "Missing EXPORT argument for ecm_qt_export_logging_category.") +    endif() +    if(NOT ARG_DESCRIPTION) +        message(FATAL_ERROR "Missing DESCRIPTION argument for ecm_qt_export_logging_category.") +    endif() + +    # note data in global properties +    set(_propertyprefix "ECM_QT_LOGGING_CATEGORY_${ARG_EXPORT}") +    set_property(GLOBAL APPEND PROPERTY "${_propertyprefix}_CATEGORIES" ${ARG_CATEGORY_NAME}) +    set_property(GLOBAL PROPERTY "${_propertyprefix}_IDENTIFIER_${ARG_CATEGORY_NAME}" "${ARG_IDENTIFIER}") +    set_property(GLOBAL PROPERTY "${_propertyprefix}_DESCRIPTION_${ARG_CATEGORY_NAME}" "${ARG_DESCRIPTION}") +    set_property(GLOBAL PROPERTY "${_propertyprefix}_OLD_NAMES_${ARG_CATEGORY_NAME}" "${ARG_OLD_CATEGORY_NAMES}") +    if (is_explicite_default_severity) +        set_property(GLOBAL PROPERTY "${_propertyprefix}_DEFAULT_SEVERITY_${ARG_CATEGORY_NAME}" "${ARG_DEFAULT_SEVERITY}") +    endif() +endfunction() + +  function(ecm_qt_declare_logging_category sources_var)      set(options) -    set(oneValueArgs HEADER IDENTIFIER CATEGORY_NAME DEFAULT_SEVERITY) -    set(multiValueArgs) +    set(oneValueArgs HEADER IDENTIFIER CATEGORY_NAME DEFAULT_SEVERITY EXPORT DESCRIPTION) +    set(multiValueArgs OLD_CATEGORY_NAMES)      cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})      if(ARG_UNPARSED_ARGUMENTS) @@ -83,12 +235,17 @@ function(ecm_qt_declare_logging_category sources_var)      endif()      if(NOT ARG_DEFAULT_SEVERITY)          set(ARG_DEFAULT_SEVERITY Info) +        set(is_explicite_default_severity FALSE)      else()          set(acceptible_severities Debug Info Warning Critical Fatal)          list(FIND acceptible_severities "${ARG_DEFAULT_SEVERITY}" pos)          if (pos EQUAL -1)              message(FATAL_ERROR "Unknown DEFAULT_SEVERITY ${pos}")          endif() +        set(is_explicite_default_severity TRUE) +    endif() +    if(ARG_EXPORT AND NOT ARG_DESCRIPTION) +        message(FATAL_ERROR "Missing DESCRIPTION argument for ecm_qt_declare_logging_category.")      endif()      if (NOT IS_ABSOLUTE "${ARG_HEADER}") @@ -132,4 +289,125 @@ function(ecm_qt_declare_logging_category sources_var)      set(sources "${${sources_var}}")      list(APPEND sources "${cpp_filename}")      set(${sources_var} "${sources}" PARENT_SCOPE) + +    # note data in global properties +    if (ARG_EXPORT) +        set(_default_severity) +        if (is_explicite_default_severity) +            set(_default_severity DEFAULT_SEVERITY ${ARG_DEFAULT_SEVERITY}) +        endif() +        set(_old_category_name) +        if (ARG_OLD_CATEGORY_NAMES) +            set(_old_category_names OLD_CATEGORY_NAMES ${ARG_OLD_CATEGORY_NAMES}) +        endif() +        ecm_qt_export_logging_category( +            IDENTIFIER ${ARG_IDENTIFIER} +            CATEGORY_NAME ${ARG_CATEGORY_NAME} +            ${_old_category_names} +            ${_default_severity} +            EXPORT ${ARG_EXPORT} +            DESCRIPTION "${ARG_DESCRIPTION}" +        ) +    endif() +endfunction() + + +function(ecm_qt_install_logging_categories) +    set(options SORT) +    set(oneValueArgs FILE EXPORT DESTINATION COMPONENT) +    set(multiValueArgs) + +    cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + +    if(NOT ARGS_EXPORT) +        message(FATAL_ERROR "Missing EXPORT argument for ecm_qt_install_logging_categories") +    endif() + +    if(NOT ARGS_DESTINATION) +        message(FATAL_ERROR "Missing DESTINATION argument for ecm_qt_install_logging_categories") +    endif() + +    if(NOT ARGS_FILE) +        string(TOLOWER "${ARGS_EXPORT}.categories" ARGS_FILE) +    endif() + +    set(_propertyprefix "ECM_QT_LOGGING_CATEGORY_${ARGS_EXPORT}") +    get_property(has_category GLOBAL PROPERTY "${_propertyprefix}_CATEGORIES" SET) + +    if (NOT has_category) +        message(FATAL_ERROR "${ARGS_EXPORT} is an unknown qt logging category export name.") +    endif() + +    get_property(_categories GLOBAL PROPERTY "${_propertyprefix}_CATEGORIES") +    if (ARGS_SORT) +        list(SORT _categories) +    endif() + +    set(_renamed_categories) + +    # generate categories file +    if (NOT IS_ABSOLUTE "${ARGS_FILE}") +        set(ARGS_FILE "${CMAKE_CURRENT_BINARY_DIR}/${ARGS_FILE}") +    endif() + +    file(WRITE ${ARGS_FILE} +"# KDebugSettings data file +# This file was generated by ecm_qt_install_logging_categories(). DO NOT EDIT! + +") + +    foreach(_category IN LISTS _categories) +        get_property(_description GLOBAL PROPERTY "${_propertyprefix}_DESCRIPTION_${_category}") +        get_property(_identifier GLOBAL PROPERTY "${_propertyprefix}_IDENTIFIER_${_category}") +        get_property(_default_severity GLOBAL PROPERTY "${_propertyprefix}_DEFAULT_SEVERITY_${_category}") +        if (_default_severity) +            string(TOUPPER "${_default_severity}" _default_severity) +            set(_default_severity "DEFAULT_SEVERITY [${_default_severity}] ") # final space wanted +        endif() +        get_property(_old_category_names GLOBAL PROPERTY "${_propertyprefix}_OLD_NAMES_${_category}") +        if (_old_category_names) +            list(APPEND _renamed_categories ${_category}) +        endif() + +        # Format: +        # logname<space>description(optional <space> DEFAULT_SEVERITY [DEFAULT_CATEGORY] as WARNING/DEBUG/INFO/CRITICAL) optional IDENTIFIER [...]) +        file(APPEND ${ARGS_FILE} "${_category} ${_description} ${_default_severity}IDENTIFIER [${_identifier}]\n") +    endforeach() + +    set(_renamed_cats_file) +    if (_renamed_categories) +        get_filename_component(_dir ${ARGS_FILE} DIRECTORY) +        get_filename_component(_base_name ${ARGS_FILE} NAME_WLE) +        set(_renamed_cats_file "${_dir}/${_base_name}.renamecategories") +        file(WRITE ${_renamed_cats_file} +"# KDebugSettings data file +# This file was generated by ecm_qt_install_logging_categories(). DO NOT EDIT! + +") + +        foreach(_category IN LISTS _renamed_categories) +            get_property(_category_name_history GLOBAL PROPERTY "${_propertyprefix}_OLD_NAMES_${_category}") + +            list(APPEND _category_name_history ${_category}) +            list(GET _category_name_history 0 _old_category_name) +            list(REMOVE_AT _category_name_history 0) +            foreach(_category_name IN LISTS _category_name_history) +                # Format: +                # oldlogname<space>newlogname +                file(APPEND ${_renamed_cats_file} "${_old_category_name} ${_category_name}\n") +                set(_old_category_name ${_category_name}) +            endforeach() +        endforeach() +    endif() + +    # install files +    set(_component_install) +    if (ARGS_COMPONENT) +        set(_component_install COMPONENT ${ARGS_COMPONENT}) +    endif() +    install( +        FILES ${ARGS_FILE} ${_renamed_cats_file} +        DESTINATION "${ARGS_DESTINATION}" +        ${_component_install} +    )  endfunction() diff --git a/tests/ECMQtDeclareLoggingCategoryTest/CMakeLists.txt b/tests/ECMQtDeclareLoggingCategoryTest/CMakeLists.txt index 74f24317..a921fd3b 100644 --- a/tests/ECMQtDeclareLoggingCategoryTest/CMakeLists.txt +++ b/tests/ECMQtDeclareLoggingCategoryTest/CMakeLists.txt @@ -5,12 +5,35 @@ set(ECM_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../modules")  set(CMAKE_MODULE_PATH ${ECM_MODULE_DIR})  include(ECMQtDeclareLoggingCategory) +include(CMakeParseArguments) + +function (check_file) +    set(options) +    set(oneValueArgs GENERATED EXPECTED) +    set(multiValueArgs) +    cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + +    if (NOT EXISTS "${ARGS_GENERATED}") +        message(FATAL_ERROR "${ARGS_GENERATED} was not generated") +    endif() +    file(READ "${ARGS_GENERATED}" generated_contents) +    if (NOT EXISTS "${ARGS_EXPECTED}") +        message(FATAL_ERROR "Original ${ARGS_EXPECTED} was not found") +    endif() +    file(READ "${ARGS_EXPECTED}" original_contents) +    if (NOT "${generated_contents}" STREQUAL "${original_contents}") +        message(FATAL_ERROR "${generated_file} contains '${generated_contents}' instead of '${original_contents}'") +    endif() +endfunction()  ecm_qt_declare_logging_category(      sources      HEADER "log1.h"      IDENTIFIER "log1"      CATEGORY_NAME "log.one" +    OLD_CATEGORY_NAMES "log1old" +    DESCRIPTION "log 1" +    EXPORT LOG  )  ecm_qt_declare_logging_category( @@ -18,6 +41,9 @@ ecm_qt_declare_logging_category(      HEADER "log2.h"      IDENTIFIER "foo::bar::log2"      CATEGORY_NAME "log.two" +    DEFAULT_SEVERITY Info +    DESCRIPTION "log 2" +    EXPORT LOG  )  ecm_qt_declare_logging_category( @@ -28,6 +54,15 @@ ecm_qt_declare_logging_category(      DEFAULT_SEVERITY Critical  ) +ecm_qt_export_logging_category( +    IDENTIFIER "log4" +    CATEGORY_NAME "log.four" +    OLD_CATEGORY_NAMES "logfouroldest" "log4old" +    DEFAULT_SEVERITY Warning +    EXPORT LOG +    DESCRIPTION "log 4" +) +  find_package(Qt5Core REQUIRED)  add_executable(testmain testmain.cpp ${sources}) @@ -40,3 +75,18 @@ target_link_libraries(testmain          Qt5::Core  ) +ecm_qt_install_logging_categories( +    EXPORT LOG +    FILE log.categories +    DESTINATION "${CMAKE_BINARY_DIR}/dummyinstall" +) + +check_file( +    GENERATED "${CMAKE_CURRENT_BINARY_DIR}/log.categories" +    EXPECTED "${CMAKE_CURRENT_SOURCE_DIR}/log.categories" +) +check_file( +    GENERATED "${CMAKE_CURRENT_BINARY_DIR}/log.renamecategories" +    EXPECTED "${CMAKE_CURRENT_SOURCE_DIR}/log.renamecategories" +) + diff --git a/tests/ECMQtDeclareLoggingCategoryTest/log.categories b/tests/ECMQtDeclareLoggingCategoryTest/log.categories new file mode 100644 index 00000000..267c5064 --- /dev/null +++ b/tests/ECMQtDeclareLoggingCategoryTest/log.categories @@ -0,0 +1,6 @@ +# KDebugSettings data file +# This file was generated by ecm_qt_install_logging_categories(). DO NOT EDIT! + +log.one log 1 IDENTIFIER [log1] +log.two log 2 DEFAULT_SEVERITY [INFO] IDENTIFIER [foo::bar::log2] +log.four log 4 DEFAULT_SEVERITY [WARNING] IDENTIFIER [log4] diff --git a/tests/ECMQtDeclareLoggingCategoryTest/log.renamecategories b/tests/ECMQtDeclareLoggingCategoryTest/log.renamecategories new file mode 100644 index 00000000..7bcac2fb --- /dev/null +++ b/tests/ECMQtDeclareLoggingCategoryTest/log.renamecategories @@ -0,0 +1,6 @@ +# KDebugSettings data file +# This file was generated by ecm_qt_install_logging_categories(). DO NOT EDIT! + +log1old log.one +logfouroldest log4old +log4old log.four  | 
