aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/module/ECMPoQmTools.rst1
-rw-r--r--modules/ECMCreateQmFromPoFiles.cmake5
-rw-r--r--modules/ECMPoQmTools.cmake201
-rw-r--r--modules/ECMQmLoader.cpp.in2
-rw-r--r--tests/CMakeLists.txt13
-rw-r--r--tests/ECMPoQmToolsTest/CMakeLists.txt22
-rw-r--r--tests/ECMPoQmToolsTest/check_tree.cmake.in55
-rw-r--r--tests/ECMPoQmToolsTest/po/es/install-test.po18
-rw-r--r--tests/ECMPoQmToolsTest/po/fr/install-test.po18
-rw-r--r--tests/ECMPoQmToolsTest/test.po18
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 ""