diff options
| author | Alex Merry <alex.merry@kde.org> | 2015-07-29 22:46:44 +0200 | 
|---|---|---|
| committer | Alex Merry <alex.merry@kde.org> | 2015-08-18 23:02:11 +0100 | 
| commit | 9bffa7a202cad3a29103f3e9a8b50b9a61277310 (patch) | |
| tree | 1312c922a8097904a4abc53a2c0d00cd4886ae3f | |
| parent | 7af8bdcc7610df1de24c36ceeedd8c9f82529634 (diff) | |
| download | extra-cmake-modules-9bffa7a202cad3a29103f3e9a8b50b9a61277310.tar.gz extra-cmake-modules-9bffa7a202cad3a29103f3e9a8b50b9a61277310.tar.bz2 | |
Add macro to generate logging category declarations for Qt5.
This makes life a bit easier for developers who use the categorised
logging in Qt5 in the common case - rather than creating two new files,
and remembering to put in the #ifdef for the default verbosity settings
in Qt 5.4, they can just add a couple of lines to their CMakeLists.txt.
REVIEW: 124595
| -rw-r--r-- | docs/module/ECMQtDeclareLoggingCategory.rst | 1 | ||||
| -rw-r--r-- | modules/ECMQtDeclareLoggingCategory.cmake | 118 | ||||
| -rw-r--r-- | modules/ECMQtDeclareLoggingCategory.cpp.in | 11 | ||||
| -rw-r--r-- | modules/ECMQtDeclareLoggingCategory.h.in | 11 | ||||
| -rw-r--r-- | tests/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | tests/ECMQtDeclareLoggingCategoryTest/CMakeLists.txt | 42 | ||||
| -rw-r--r-- | tests/ECMQtDeclareLoggingCategoryTest/testmain.cpp | 83 | 
7 files changed, 269 insertions, 0 deletions
| diff --git a/docs/module/ECMQtDeclareLoggingCategory.rst b/docs/module/ECMQtDeclareLoggingCategory.rst new file mode 100644 index 00000000..8f0af2ac --- /dev/null +++ b/docs/module/ECMQtDeclareLoggingCategory.rst @@ -0,0 +1 @@ +.. ecm-module:: ../../modules/ECMQtDeclareLoggingCategory.cmake diff --git a/modules/ECMQtDeclareLoggingCategory.cmake b/modules/ECMQtDeclareLoggingCategory.cmake new file mode 100644 index 00000000..b7f1ad39 --- /dev/null +++ b/modules/ECMQtDeclareLoggingCategory.cmake @@ -0,0 +1,118 @@ +#.rst: +# ECMQtDeclareLoggingCategory +# --------------------------- +# +# Generate declarations for logging categories in Qt5. +# +# :: +# +#   ecm_qt_declare_logging_category(<sources_var> +#                                   HEADER <filename> +#                                   IDENTIFIER <identifier> +#                                   CATEGORY_NAME <category_name> +#                                   [DEFAULT_SEVERITY +#                                        <Debug|Info|Warning| +#                                         Critical|Fatal>]) +# +# A header file, ``<filename>``, will be generated along with a corresponding +# source file, which will be added to ``<sources_var>``. These will provide a +# QLoggingCategory category that can be referred to from C++ code using +# ``<identifier>``, and from the logging configuration using +# ``<category_name>``. +# +# If ``<filename>`` is not absolute, it will be taken relative to the current +# binary directory. +# +# If the code is compiled against Qt 5.4 or later, by default it will only log +# output that is at least the severity specified by ``DEFAULT_SEVERITY``, or +# "Warning" level if ``DEFAULT_SEVERITY`` is not given. Note that, due to a +# bug in Qt 5.5, "Info" may be treated as more severe than "Fatal". +# +# ``<identifier>`` may include namespaces (eg: ``foo::bar::IDENT``). +# +# Since 5.14.0. + +#============================================================================= +# Copyright 2015 Alex Merry <alex.merry@kde.org> +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file COPYING-CMAKE-SCRIPTS for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of extra-cmake-modules, substitute the full +#  License text for the above reference.) + +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_declare_logging_category sources_var) +    set(options) +    set(oneValueArgs HEADER IDENTIFIER CATEGORY_NAME DEFAULT_SEVERITY) +    set(multiValueArgs) +    cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + +    if(ARG_UNPARSED_ARGUMENTS) +        message(FATAL_ERROR "Unexpected arguments to ecm_qt_declare_logging_category: ${ARG_UNPARSED_ARGUMENTS}") +    endif() +    if(NOT ARG_HEADER) +        message(FATAL_ERROR "Missing HEADER argument for ecm_qt_declare_logging_category") +    endif() +    if(NOT ARG_IDENTIFIER) +        message(FATAL_ERROR "Missing IDENTIFIER argument for ecm_qt_declare_logging_category") +    endif() +    if(NOT ARG_CATEGORY_NAME) +        message(FATAL_ERROR "Missing CATEGORY_NAME argument for ecm_qt_declare_logging_category") +    endif() +    if(NOT ARG_DEFAULT_SEVERITY) +        set(ARG_DEFAULT_SEVERITY Warning) +    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() +    endif() + +    if (NOT IS_ABSOLUTE "${ARG_HEADER}") +        set(ARG_HEADER "${CMAKE_CURRENT_BINARY_DIR}/${ARG_HEADER}") +    endif() + +    string(REPLACE "::" ";" namespaces "${ARG_IDENTIFIER}") +    list(LENGTH namespaces len) +    math(EXPR last_pos "${len} - 1") +    list(GET namespaces ${last_pos} IDENTIFIER) +    list(REMOVE_AT namespaces ${last_pos}) + +    set(OPEN_NAMESPACES) +    set(CLOSE_NAMESPACES) +    foreach(ns ${namespaces}) +        set(OPEN_NAMESPACES "${OPEN_NAMESPACES} namespace ${ns} {") +        set(CLOSE_NAMESPACES "} ${CLOSE_NAMESPACES}") +    endforeach() + +    string(FIND "${ARG_HEADER}" "." pos REVERSE) +    if (pos EQUAL -1) +        set(cpp_filename "${ARG_HEADER}.cpp") +    else() +        string(SUBSTRING "${ARG_HEADER}" 0 ${pos} cpp_filename) +        set(cpp_filename "${cpp_filename}.cpp") +    endif() + +    get_filename_component(HEADER_NAME "${ARG_HEADER}" NAME) + +    string(REPLACE "::" "_" GUARD_NAME "${ARG_IDENTIFIER}_H") +    string(TOUPPER "${GUARD_NAME}" GUARD_NAME) + +    configure_file("${_ECM_QT_DECLARE_LOGGING_CATEGORY_TEMPLATE_CPP}" "${cpp_filename}") +    configure_file("${_ECM_QT_DECLARE_LOGGING_CATEGORY_TEMPLATE_H}" "${ARG_HEADER}") + +    set(sources "${${sources_var}}") +    list(APPEND sources "${cpp_filename}") +    set(${sources_var} "${sources}" PARENT_SCOPE) +endfunction() + diff --git a/modules/ECMQtDeclareLoggingCategory.cpp.in b/modules/ECMQtDeclareLoggingCategory.cpp.in new file mode 100644 index 00000000..20c14af5 --- /dev/null +++ b/modules/ECMQtDeclareLoggingCategory.cpp.in @@ -0,0 +1,11 @@ +// This file is autogenerated by CMake: DO NOT EDIT + +#include "@HEADER_NAME@" + +@OPEN_NAMESPACES@ +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) +Q_LOGGING_CATEGORY(@IDENTIFIER@, "@ARG_CATEGORY_NAME@", Qt@ARG_DEFAULT_SEVERITY@Msg) +#else +Q_LOGGING_CATEGORY(@IDENTIFIER@, "@ARG_CATEGORY_NAME@") +#endif +@CLOSE_NAMESPACES@ diff --git a/modules/ECMQtDeclareLoggingCategory.h.in b/modules/ECMQtDeclareLoggingCategory.h.in new file mode 100644 index 00000000..fedecd2f --- /dev/null +++ b/modules/ECMQtDeclareLoggingCategory.h.in @@ -0,0 +1,11 @@ +// This file is autogenerated by CMake: DO NOT EDIT + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <QLoggingCategory> +@OPEN_NAMESPACES@ +Q_DECLARE_LOGGING_CATEGORY(@IDENTIFIER@) +@CLOSE_NAMESPACES@ + +#endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7960154a..8a75ae61 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -85,6 +85,9 @@ if (TARGET Qt5::qmake)      add_test_variant(KDEInstallDirsTest.relative_or_absolute_qt                       KDEInstallDirsTest.relative_or_absolute dummy)  endif () +if (Qt5Core_FOUND) +    add_test_macro(ECMQtDeclareLoggingCategoryTest testmain) +endif()  add_test_macro(FindModules dummy)  add_test_macro(UseFindModules dummy) diff --git a/tests/ECMQtDeclareLoggingCategoryTest/CMakeLists.txt b/tests/ECMQtDeclareLoggingCategoryTest/CMakeLists.txt new file mode 100644 index 00000000..15ece187 --- /dev/null +++ b/tests/ECMQtDeclareLoggingCategoryTest/CMakeLists.txt @@ -0,0 +1,42 @@ +project(ECMQtDeclareLoggingCategoryTest) +cmake_minimum_required(VERSION 2.8.12) +set(ECM_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../modules") + +set(CMAKE_MODULE_PATH ${ECM_MODULE_DIR}) + +include(ECMQtDeclareLoggingCategory) + +ecm_qt_declare_logging_category( +    sources +    HEADER "log1.h" +    IDENTIFIER "log1" +    CATEGORY_NAME "log.one" +) + +ecm_qt_declare_logging_category( +    sources +    HEADER "log2.h" +    IDENTIFIER "foo::bar::log2" +    CATEGORY_NAME "log.two" +) + +ecm_qt_declare_logging_category( +    sources +    HEADER "${CMAKE_CURRENT_BINARY_DIR}/log3.h" +    IDENTIFIER "log3" +    CATEGORY_NAME "three" +    DEFAULT_SEVERITY Critical +) + +find_package(Qt5Core REQUIRED) + +add_executable(testmain testmain.cpp ${sources}) +target_include_directories(testmain +    PRIVATE +        "${CMAKE_CURRENT_BINARY_DIR}" +) +target_link_libraries(testmain +    PRIVATE +        Qt5::Core +) + diff --git a/tests/ECMQtDeclareLoggingCategoryTest/testmain.cpp b/tests/ECMQtDeclareLoggingCategoryTest/testmain.cpp new file mode 100644 index 00000000..a06614a1 --- /dev/null +++ b/tests/ECMQtDeclareLoggingCategoryTest/testmain.cpp @@ -0,0 +1,83 @@ +#include <QCoreApplication> + +#include "log1.h" +#include "log2.h" +#include "log3.h" + +#include <iostream> + +int main(int argc, char **argv) { +    QCoreApplication qapp(argc, argv); + +    bool success = true; + +    // NB: we cannot test against QtInfoMsg, as that (a) does not exist before +    // Qt 5.5, and (b) has incorrect semantics in Qt 5.5, in that it is +    // treated as more severe than QtCriticalMsg. + +    if (log1().categoryName() != QLatin1String("log.one")) { +        qWarning("log1 category was \"%s\", expected \"log.one\"", log1().categoryName()); +        success = false; +    } +#if QT_VERSION < QT_VERSION_CHECK(5, 4, 0) +    if (!log1().isDebugEnabled()) { +        qWarning("log1 debug messages were not enabled"); +        success = false; +    } +#else +    if (log1().isDebugEnabled()) { +        qWarning("log1 debug messages were enabled"); +        success = false; +    } +    if (!log1().isWarningEnabled()) { +        qWarning("log1 warning messages were not enabled"); +        success = false; +    } +#endif + +    if (foo::bar::log2().categoryName() != QLatin1String("log.two")) { +        qWarning("log2 category was \"%s\", expected \"log.two\"", foo::bar::log2().categoryName()); +        success = false; +    } +#if QT_VERSION < QT_VERSION_CHECK(5, 4, 0) +    if (!foo::bar::log2().isDebugEnabled()) { +        qWarning("log2 debug messages were not enabled"); +        success = false; +    } +#else +    if (foo::bar::log2().isDebugEnabled()) { +        qWarning("log2 debug messages were enabled"); +        success = false; +    } +    if (!foo::bar::log2().isWarningEnabled()) { +        qWarning("log2 warning messages were not enabled"); +        success = false; +    } +#endif + +    if (log3().categoryName() != QLatin1String("three")) { +        qWarning("log3 category was \"%s\", expected \"three\"", log3().categoryName()); +        success = false; +    } +#if QT_VERSION < QT_VERSION_CHECK(5, 4, 0) +    if (!log3().isDebugEnabled()) { +        qWarning("log3 debug messages were not enabled"); +        success = false; +    } +#else +    if (log3().isDebugEnabled()) { +        qWarning("log3 debug messages were enabled"); +        success = false; +    } +    if (log3().isWarningEnabled()) { +        qWarning("log3 warning messages were enabled"); +        success = false; +    } +    if (!log3().isCriticalEnabled()) { +        qWarning("log3 critical messages were not enabled"); +        success = false; +    } +#endif + +    return success ? 0 : 1; +} | 
