diff options
| author | Aurélien Gâteau <agateau@kde.org> | 2014-05-04 20:43:42 +0100 | 
|---|---|---|
| committer | Alex Merry <alex.merry@kde.org> | 2014-05-04 20:59:53 +0100 | 
| commit | 73992f139276b75aeddf78f476644a2d82f9e802 (patch) | |
| tree | 109b63c6061a2e8f39454a7d069643fd5d2050cb | |
| parent | 09d355975a6b9d3f89da280627a71e46c606d563 (diff) | |
| download | extra-cmake-modules-73992f139276b75aeddf78f476644a2d82f9e802.tar.gz extra-cmake-modules-73992f139276b75aeddf78f476644a2d82f9e802.tar.bz2 | |
Add ECMPoQmTools module
ecm_create_qm_from_po_files() was actually not very useful in practice.
So that is deprecated, to be removed before ECM 1.0.
Instead, the ECMPoQmTools provides several useful functions:
ecm_create_qm_loader() (which already existed in
ECMCreateQmFromPoFiles), ecm_process_po_files_as_qm() (which has the
same signature as gettext_process_po_files() from the FindGettext
module) and ecm_install_po_files_as_qm(), which is a convenience
function mostly for the benefit of KDE Frameworks (although potentially
useful for whatever other projects have the unusual requirement of a
Gettext translation workflow but no Gettext usage in the code).
NB: some clean-up to the documentation was done by Alex Merry
<alex.merry@kde.org> as part of this commit.
REVIEW: 117823
| -rw-r--r-- | docs/module/ECMPoQmTools.rst | 1 | ||||
| -rw-r--r-- | modules/ECMCreateQmFromPoFiles.cmake | 5 | ||||
| -rw-r--r-- | modules/ECMPoQmTools.cmake | 201 | ||||
| -rw-r--r-- | modules/ECMQmLoader.cpp.in | 2 | ||||
| -rw-r--r-- | tests/CMakeLists.txt | 13 | ||||
| -rw-r--r-- | tests/ECMPoQmToolsTest/CMakeLists.txt | 22 | ||||
| -rw-r--r-- | tests/ECMPoQmToolsTest/check_tree.cmake.in | 55 | ||||
| -rw-r--r-- | tests/ECMPoQmToolsTest/po/es/install-test.po | 18 | ||||
| -rw-r--r-- | tests/ECMPoQmToolsTest/po/fr/install-test.po | 18 | ||||
| -rw-r--r-- | tests/ECMPoQmToolsTest/test.po | 18 | 
10 files changed, 352 insertions, 1 deletions
| diff --git a/docs/module/ECMPoQmTools.rst b/docs/module/ECMPoQmTools.rst new file mode 100644 index 00000000..21e6d919 --- /dev/null +++ b/docs/module/ECMPoQmTools.rst @@ -0,0 +1 @@ +.. ecm-module:: ../../modules/ECMPoQmTools.cmake diff --git a/modules/ECMCreateQmFromPoFiles.cmake b/modules/ECMCreateQmFromPoFiles.cmake index 7457fc51..4a31a93e 100644 --- a/modules/ECMCreateQmFromPoFiles.cmake +++ b/modules/ECMCreateQmFromPoFiles.cmake @@ -2,6 +2,9 @@  # ECMCreateQmFromPoFiles  # ----------------------  # +# .. warning:: This module is deprecated and will be removed by ECM 1.0. Use +#              ECMPoQmTools instead. +#  # Generate QTranslator (.qm) catalogs from Gettext (.po) catalogs.  #  # :: @@ -79,6 +82,8 @@  # (To distribute this file outside of extra-cmake-modules, substitute the full  #  License text for the above reference.) +message(AUTHOR_WARNING "ECMCreateQmFromPoFiles is deprecated and will be removed before the release of Extra CMake Modules 1.0. Use ECMPoQmTools instead.") +  # Stolen from FindGettext.cmake  function(_ECM_QM_GET_UNIQUE_TARGET_NAME _name _unique_name)     set(propertyName "_ECM_QM_UNIQUE_COUNTER_${_name}") diff --git a/modules/ECMPoQmTools.cmake b/modules/ECMPoQmTools.cmake new file mode 100644 index 00000000..e217dd3e --- /dev/null +++ b/modules/ECMPoQmTools.cmake @@ -0,0 +1,201 @@ +#.rst: +# ECMPoQmTools +# ------------ +# +# This module provides the ``ecm_process_po_files_as_qm`` and +# ``ecm_install_po_files_as_qm`` functions for generating QTranslator (.qm) +# catalogs from Gettext (.po) catalogs, and the ``ecm_create_qm_loader`` +# function for generating the necessary code to load them in a Qt application +# or library. +# +# :: +# +#   ecm_process_po_files_as_qm(<lang> [ALL] +#                              [INSTALL_DESTINATION <install_destination>] +#                              PO_FILES <pofile> [<pofile> [...]]) +# +# Compile .po files into .qm files for the given language. +# +# If INSTALL_DESTINATION is given, the .qm files are installed in +# ``<install_destination>/<lang>/LC_MESSAGES``. Typically, +# ``<install_destination>`` is set to ``share/locale``. +# +# ``ecm_process_po_files_as_qm`` creates a "translations" target. This target +# builds all .po files into .qm files.  If ALL is specified, these rules are +# added to the "all" target (and so the .qm files will be built by default). +# +# :: +# +#   ecm_create_qm_loader(<source_files_var> <catalog_name>) +# +# Generates a C++ file which ensures translations are automatically loaded at +# startup. The path of the .cpp file is appended to ``<source_files_var>``. +# +# It assumes that the .qm file for the language code ``<lang>`` is installed as +# ``<sharedir>/locale/<lang>/LC_MESSAGES/<catalog_name>.qm``, where +# ``<sharedir>`` is one of the directories given by the ``GenericDataLocation`` +# of ``QStandardPaths``. +# +# Typical usage is like: +# +# .. code-block:: cmake +# +#   set(mylib_SRCS foo.cpp bar.cpp) +#   ecm_create_qm_loader(mylib_SRCS mylib) +#   add_library(mylib ${mylib_SRCS}) +# +# :: +# +#   ecm_install_po_files_as_qm(<podir>) +# +# Searches for .po files and installs them to the standard location. +# +# This is a convenience function which relies on all .po files being kept in +# ``<podir>/<lang>/``, where ``<lang>`` is the language the .po files are +# written in. +# +# For example, given the following directory structure:: +# +#  po/ +#    fr/ +#      mylib.po +# +# ``ecm_install_po_files_as_qm(po)`` compiles ``mylib.po`` into ``mylib.mo`` and +# installs it in ``<install_destination>/fr/LC_MESSAGES``. +# ``<install_destination>`` defaults to ``${LOCALE_INSTALL_DIR}`` if defined, +# otherwise it uses ``${CMAKE_INSTALL_LOCALEDIR}`` if that is defined, otherwise +# it uses ``share/locale``. + +#============================================================================= +# Copyright 2007-2009 Kitware, Inc. +# Copyright 2007      Alexander Neundorf <neundorf@kde.org> +# Copyright 2014      Aurélien Gâteau <agateau@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) + +# Copied from FindGettext.cmake +function(_ecm_qm_get_unique_target_name _name _unique_name) +   set(propertyName "_ECM_QM_UNIQUE_COUNTER_${_name}") +   get_property(currentCounter GLOBAL PROPERTY "${propertyName}") +   if(NOT currentCounter) +      set(currentCounter 1) +   endif() +   set(${_unique_name} "${_name}_${currentCounter}" PARENT_SCOPE) +   math(EXPR currentCounter "${currentCounter} + 1") +   set_property(GLOBAL PROPERTY ${propertyName} ${currentCounter} ) +endfunction() + + +function(ecm_create_qm_loader out_var catalog_name) +    # catalog_name is used in ECMQmLoader.cpp.in +    configure_file(${ECM_MODULE_DIR}/ECMQmLoader.cpp.in ECMQmLoader.cpp @ONLY) +    set(${out_var} ${${out_var}} ${CMAKE_CURRENT_BINARY_DIR}/ECMQmLoader.cpp PARENT_SCOPE) +endfunction() + + +function(ecm_process_po_files_as_qm lang) +    # Parse arguments +    set(options ALL) +    set(oneValueArgs INSTALL_DESTINATION) +    set(multiValueArgs PO_FILES) +    cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + +    if(ARGS_UNPARSED_ARGUMENTS) +        message(FATAL_ERROR "Unknown keywords given to ecm_process_po_files_as_qm(): \"${ARGS_UNPARSED_ARGUMENTS}\"") +    endif() + +    if(NOT ARGS_PO_FILES) +        message(FATAL_ERROR "ecm_process_po_files_as_qm() must be called with PO_FILES argument") +    endif() + +    # Find lrelease and lconvert + +    # This gives us Qt5::lrelease but unfortunately no Qt5::lconvert See +    # https://bugreports.qt-project.org/browse/QTBUG-37937 +    find_package(Qt5LinguistTools CONFIG REQUIRED) + +    get_target_property(lrelease_location Qt5::lrelease LOCATION) +    get_filename_component(lrelease_path ${lrelease_location} PATH) +    find_program(lconvert_executable +        NAMES lconvert-qt5 lconvert +        PATHS ${lrelease_path} +        ) + +    # Create commands to turn po files into qm files +    set(qm_files) +    foreach (po_file ${ARGS_PO_FILES}) +        get_filename_component(po_file ${po_file} ABSOLUTE) +        get_filename_component(filename_base ${po_file} NAME_WE) + +        # Include ${lang} in build dir because we might be called multiple times +        # with the same ${filename_base} +        set(build_dir ${CMAKE_CURRENT_BINARY_DIR}/${lang}) +        set(ts_file ${build_dir}/${filename_base}.ts) +        set(qm_file ${build_dir}/${filename_base}.qm) + +        file(MAKE_DIRECTORY ${build_dir}) + +        # lconvert from .po to .ts, then lrelease from .ts to .qm. +        add_custom_command(OUTPUT ${qm_file} +            COMMAND ${lconvert_executable} +                ARGS -i ${po_file} -o ${ts_file} -target-language ${lang} +            COMMAND Qt5::lrelease +                ARGS -compress -removeidentical -silent ${ts_file} -qm ${qm_file} +            DEPENDS ${po_file} +            ) +        if (ARGS_INSTALL_DESTINATION) +            install( +                FILES ${qm_file} +                DESTINATION ${ARGS_INSTALL_DESTINATION}/${lang}/LC_MESSAGES +            ) +        endif() +        list(APPEND qm_files ${qm_file}) +    endforeach() + +    # Hook qm files to targets +    if(NOT TARGET translations) +        add_custom_target(translations) +    endif() + +    _ecm_qm_get_unique_target_name(translations target_name) + +    if (ARGS_ALL) +        add_custom_target(${target_name} ALL DEPENDS ${qm_files}) +    else() +        add_custom_target(${target_name} DEPENDS ${qm_files}) +    endif() + +    add_dependencies(translations ${target_name}) +endfunction() + + +function(ecm_install_po_files_as_qm podir) +    if (LOCALE_INSTALL_DIR) +        set(install_destination "${LOCALE_INSTALL_DIR}") +    elseif (CMAKE_INSTALL_LOCALEDIR) +        set(install_destination "${CMAKE_INSTALL_LOCALEDIR}") +    else() +        set(install_destination share/locale) +    endif() + +    file(GLOB lang_dirs "${podir}/*") +    foreach(lang_dir ${lang_dirs}) +        file(GLOB po_files "${lang_dir}/*.po") +        get_filename_component(lang ${lang_dir} NAME) +        ecm_process_po_files_as_qm( +            ${lang} ALL +            PO_FILES ${po_files} +            INSTALL_DESTINATION ${install_destination} +        ) +    endforeach() +endfunction() diff --git a/modules/ECMQmLoader.cpp.in b/modules/ECMQmLoader.cpp.in index 2d8531f3..bc01bf98 100644 --- a/modules/ECMQmLoader.cpp.in +++ b/modules/ECMQmLoader.cpp.in @@ -1,4 +1,4 @@ -/* This file is generated by ECM_CREATE_QM_FROM_PO_FILES. Do not modify! +/* This file has been generated by ecm_create_qm_loader(). Do not modify!   *   * Building this file in a library ensures translations are automatically loaded   * when an application makes use of the library. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 171f44af..cc11aec2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -19,6 +19,8 @@ macro(ADD_TEST_MACRO NAME COMMAND)      --test-command ${COMMAND} ${ARGN})  endmacro(ADD_TEST_MACRO) +find_package(Qt5LinguistTools CONFIG) +  add_test_macro(ExecuteCoreModules dummy)  add_test_macro(ExecuteKDEModules dummy)  add_test_macro(FindModules dummy) @@ -32,3 +34,14 @@ set(ECMInstallIconsTest_EXTRA_OPTIONS  add_test_macro(ECMInstallIconsTest      ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/ECMInstallIconsTest/check_tree.cmake"  ) + +if (Qt5LinguistTools_FOUND) +    set(ECMPoQmToolsTest_EXTRA_OPTIONS +        --build-target install +        --build-options +            "-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/ECMPoQmToolsTest/InstallDirectory" +    ) +    add_test_macro(ECMPoQmToolsTest +        ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/ECMPoQmToolsTest/check_tree.cmake" +    ) +endif() diff --git a/tests/ECMPoQmToolsTest/CMakeLists.txt b/tests/ECMPoQmToolsTest/CMakeLists.txt new file mode 100644 index 00000000..eabf2b88 --- /dev/null +++ b/tests/ECMPoQmToolsTest/CMakeLists.txt @@ -0,0 +1,22 @@ +project(ECMPoQmToolsTest) +cmake_minimum_required(VERSION 2.8.12) +set(ECM_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../modules") + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../modules) + +# make sure the test install dir is clean +file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}") + +include(ECMPoQmTools) + +ecm_create_qm_loader(QMLOADER_PATH catalog) + +ecm_process_po_files_as_qm(fr ALL +    INSTALL_DESTINATION share/locale +    PO_FILES test.po +) + +ecm_install_po_files_as_qm(po) + +# this will be run by CTest +configure_file(check_tree.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/check_tree.cmake" @ONLY) diff --git a/tests/ECMPoQmToolsTest/check_tree.cmake.in b/tests/ECMPoQmToolsTest/check_tree.cmake.in new file mode 100644 index 00000000..71cbaa8d --- /dev/null +++ b/tests/ECMPoQmToolsTest/check_tree.cmake.in @@ -0,0 +1,55 @@ +set(BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@") +set(ACTUAL_TREE "@CMAKE_INSTALL_PREFIX@") +set(QMLOADER_PATH "@QMLOADER_PATH@") + +set(fail OFF) + +macro(mark_failed msg) +    message(WARNING "FAIL: ${msg}") +    set(fail ON) +endmacro() + +macro(check_strequal var expected) +    if (NOT "${${var}}" STREQUAL "${expected}") +        mark_failed("${var} is:\n  \"${${var}}\"\nExpected:\n  \"${expected}\"") +    endif() +endmacro() + +macro(check_exists file) +    if (NOT EXISTS ${file}) +        mark_failed("File \"${file}\" does not exist") +    endif() +endmacro() + +check_exists(${BINARY_DIR}/ECMQmLoader.cpp) +check_strequal(QMLOADER_PATH "${BINARY_DIR}/ECMQmLoader.cpp") + +set(exp_files  +    "share/locale/fr/LC_MESSAGES/test.qm" +    "share/locale/fr/LC_MESSAGES/install-test.qm" +    "share/locale/es/LC_MESSAGES/install-test.qm" +) +file(GLOB_RECURSE actual_files RELATIVE "${ACTUAL_TREE}" "${ACTUAL_TREE}/*") +list(SORT exp_files) +list(SORT actual_files) + +if(NOT exp_files STREQUAL actual_files) +    foreach(f ${exp_files}) +        list(FIND actual_files "${f}" result) +        if(result EQUAL -1) +            message(WARNING "${f} was expected, but not found") +            set(fail ON) +        endif() +    endforeach() +    foreach(f ${actual_files}) +        list(FIND exp_files "${f}" result) +        if(result EQUAL -1) +            message(WARNING "${f} was found, but not expected") +            set(fail ON) +        endif() +    endforeach() +endif() + +if (fail) +    message("Test failed!") +endif() diff --git a/tests/ECMPoQmToolsTest/po/es/install-test.po b/tests/ECMPoQmToolsTest/po/es/install-test.po new file mode 100644 index 00000000..107d1b08 --- /dev/null +++ b/tests/ECMPoQmToolsTest/po/es/install-test.po @@ -0,0 +1,18 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Language: fr\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Qt-Contexts: true\n" +"X-Generator: Poedit 1.5.4\n" + +#: ../../home/aurelien/src/kf5/frameworks/kbookmarks/src/kbookmark.cpp:307 +msgctxt "KBookmark|Bookmark separator" +msgid "--- separator ---" +msgstr "" diff --git a/tests/ECMPoQmToolsTest/po/fr/install-test.po b/tests/ECMPoQmToolsTest/po/fr/install-test.po new file mode 100644 index 00000000..107d1b08 --- /dev/null +++ b/tests/ECMPoQmToolsTest/po/fr/install-test.po @@ -0,0 +1,18 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Language: fr\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Qt-Contexts: true\n" +"X-Generator: Poedit 1.5.4\n" + +#: ../../home/aurelien/src/kf5/frameworks/kbookmarks/src/kbookmark.cpp:307 +msgctxt "KBookmark|Bookmark separator" +msgid "--- separator ---" +msgstr "" diff --git a/tests/ECMPoQmToolsTest/test.po b/tests/ECMPoQmToolsTest/test.po new file mode 100644 index 00000000..107d1b08 --- /dev/null +++ b/tests/ECMPoQmToolsTest/test.po @@ -0,0 +1,18 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Language: fr\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Qt-Contexts: true\n" +"X-Generator: Poedit 1.5.4\n" + +#: ../../home/aurelien/src/kf5/frameworks/kbookmarks/src/kbookmark.cpp:307 +msgctxt "KBookmark|Bookmark separator" +msgid "--- separator ---" +msgstr "" | 
