Warning, /frameworks/extra-cmake-modules/modules/ECMCreateQmFromPoFiles.cmake is written in an unsupported language. File is not indexed.

0001 # SPDX-FileCopyrightText: 2014 Aurélien Gâteau <agateau@kde.org>
0002 #
0003 # SPDX-License-Identifier: BSD-3-Clause
0004 
0005 #[=======================================================================[.rst:
0006 ECMCreateQmFromPoFiles
0007 ----------------------
0008 
0009 .. warning:: This module is deprecated and will be removed by ECM 1.0. Use
0010              :module:`ECMPoQmTools` instead.
0011 
0012 Generate QTranslator (.qm) catalogs from Gettext (.po) catalogs.
0013 
0014 ::
0015 
0016   ecm_create_qm_from_po_files(PO_FILES <file1>... <fileN>
0017                               [CATALOG_NAME <catalog_name>]
0018                               [INSTALL_DESTINATION <install_destination>])
0019 
0020 Creates the necessary rules to compile .po files into .qm files, and install
0021 them.
0022 
0023 The .qm files are installed in ``<install_destination>/<lang>/LC_MESSAGES``,
0024 where <install_destination> is the INSTALL_DESTINATION argument and <lang> is
0025 extracted from the "Language" field inside the .po file.
0026 
0027 INSTALL_DESTINATION defaults to ``${LOCALE_INSTALL_DIR}`` if defined,
0028 otherwise it uses ``${CMAKE_INSTALL_LOCALEDIR}`` if that is defined, otherwise
0029 it uses ``share/locale``.
0030 
0031 CATALOG_NAME defines the name of the installed .qm files. If set, .qm files
0032 will be installed as ``<catalog_name>.qm``. If not set .qm files will be named
0033 after the name of their source .po file.
0034 
0035 Setting the catalog name is useful when all .po files for a target are kept
0036 in a single source directory. For example, the "mylib" probject might keep all
0037 its translations in a "po" directory, like this::
0038 
0039   po/
0040       es.po
0041       fr.po
0042 
0043 Without setting CATALOG_NAME, those .po will be turned into .qm and installed
0044 as::
0045 
0046   share/locale/fr/LC_MESSAGES/fr.qm
0047   share/locale/es/LC_MESSAGES/es.qm
0048 
0049 If CATALOG_NAME is set to "mylib", they will be installed as::
0050 
0051   share/locale/fr/LC_MESSAGES/mylib.qm
0052   share/locale/es/LC_MESSAGES/mylib.qm
0053 
0054 Which is what the loader created by ecm_create_qm_loader() expects.
0055 
0056 ecm_create_qm_from_po_files() creates a "translation" target. This target
0057 builds all .po files into .qm files.
0058 
0059 ::
0060 
0061   ecm_create_qm_loader(<source_files_var> <catalog_name>)
0062 
0063 ecm_create_qm_loader() generates a C++ file which ensures translations are
0064 automatically loaded at startup. The path of the .cpp file is appended to
0065 <source_files_var>.  Typical usage is like:
0066 
0067 .. code-block:: cmake
0068 
0069   set(mylib_SRCS foo.cpp bar.cpp)
0070   ecm_create_qm_loader(mylib_SRCS mylib)
0071   add_library(mylib ${mylib_SRCS})
0072 
0073 This generates a C++ file which loads "mylib.qm" at startup, assuming it has
0074 been installed by ecm_create_qm_from_po_files(), and compiles it into ``mylib``.
0075 
0076 Since pre-1.0.0.
0077 #]=======================================================================]
0078 
0079 message(AUTHOR_WARNING "ECMCreateQmFromPoFiles is deprecated and will be removed before the release of Extra CMake Modules 1.0. Use ECMPoQmTools instead.")
0080 
0081 # Stolen from FindGettext.cmake
0082 function(_ECM_QM_GET_UNIQUE_TARGET_NAME _name _unique_name)
0083    set(propertyName "_ECM_QM_UNIQUE_COUNTER_${_name}")
0084    get_property(currentCounter GLOBAL PROPERTY "${propertyName}")
0085    if(NOT currentCounter)
0086       set(currentCounter 1)
0087    endif()
0088    set(${_unique_name} "${_name}_${currentCounter}" PARENT_SCOPE)
0089    math(EXPR currentCounter "${currentCounter} + 1")
0090    set_property(GLOBAL PROPERTY ${propertyName} ${currentCounter} )
0091 endfunction()
0092 
0093 function(_ECM_QM_EXTRACT_LANGUAGE out_language po_file)
0094     file(READ ${po_file} content)
0095     # msginit uses "Language: <lang>" but lconvert uses "X-Language: <lang>"
0096     string(REGEX MATCH "\"(X-)?Language: ([a-z_A-Z]+)" match "${content}")
0097     if (NOT match)
0098         message(FATAL_ERROR "_ECM_QM_EXTRACT_LANGUAGE: Could not extract language from ${po_file}")
0099     endif()
0100     set(${out_language} ${CMAKE_MATCH_2} PARENT_SCOPE)
0101 endfunction()
0102 
0103 function(_ECM_QM_CREATE_TARGET install_destination catalog_name)
0104     # Find lconvert
0105     if(TARGET Qt5::lconvert)
0106         set(lconvert_executable Qt5::lconvert)
0107     else()
0108         # Qt < 5.3.1 does not define Qt5::lconvert
0109         get_target_property(lrelease_location Qt5::lrelease LOCATION)
0110         get_filename_component(lrelease_path ${lrelease_location} PATH)
0111         find_program(lconvert_executable
0112             NAMES lconvert-qt5 lconvert
0113             PATHS ${lrelease_path}
0114             NO_DEFAULT_PATH
0115             )
0116     endif()
0117 
0118     if (catalog_name)
0119         set(install_args RENAME ${catalog_name}.qm)
0120     else()
0121         set(install_args)
0122     endif()
0123 
0124     foreach (it ${ARGN})
0125         get_filename_component(filename_base ${it} ABSOLUTE)
0126         get_filename_component(filename_base ${it} NAME_WE)
0127 
0128         file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
0129         set(tsfile ${CMAKE_CURRENT_BINARY_DIR}/${filename_base}.ts)
0130         set(qmfile ${CMAKE_CURRENT_BINARY_DIR}/${filename_base}.qm)
0131 
0132         _ECM_QM_EXTRACT_LANGUAGE(language ${it})
0133 
0134         # lconvert from .po to .ts and then run lupdate to generate the correct
0135         # strings. Finally run lrelease to create the .qm files.
0136         add_custom_command(OUTPUT ${qmfile}
0137             COMMAND ${lconvert_executable}
0138                 ARGS -i ${it} -o ${tsfile} -target-language ${language}
0139             COMMAND Qt5::lrelease
0140                 ARGS -removeidentical -silent ${tsfile} -qm ${qmfile}
0141             DEPENDS ${it}
0142             )
0143         install(
0144             FILES ${qmfile}
0145             DESTINATION ${install_destination}/${language}/LC_MESSAGES
0146             ${install_args}
0147         )
0148         set(qmfiles ${qmfiles} ${qmfile})
0149     endforeach()
0150 
0151     if(NOT TARGET translations)
0152         add_custom_target(translations ALL)
0153     endif()
0154     _ecm_qm_get_unique_target_name(translations target_name)
0155     add_custom_target(${target_name} DEPENDS ${qmfiles})
0156     add_dependencies(translations ${target_name})
0157 endfunction()
0158 
0159 function(ECM_CREATE_QM_LOADER out_var catalog_name)
0160     # catalog_name is used in ECMQmLoader.cpp.in
0161     configure_file(${ECM_MODULE_DIR}/ECMQmLoader.cpp.in ECMQmLoader.cpp @ONLY)
0162     set(${out_var} ${${out_var}} ${CMAKE_CURRENT_BINARY_DIR}/ECMQmLoader.cpp PARENT_SCOPE)
0163 endfunction()
0164 
0165 function(ECM_CREATE_QM_FROM_PO_FILES)
0166     # This gives us Qt5::lrelease and Qt5::lupdate but unfortunately no Qt5::lconvert
0167     # See https://bugreports.qt-project.org/browse/QTBUG-37937
0168     find_package(Qt5LinguistTools CONFIG REQUIRED)
0169 
0170     foreach (arg ${ARGN})
0171         if (arg STREQUAL "PO_DIR")
0172             _ecm_create_qm_from_po_files_legacy(${ARGN})
0173             return()
0174         endif()
0175     endforeach()
0176 
0177     set(options)
0178     set(oneValueArgs CATALOG_NAME INSTALL_DESTINATION)
0179     set(multiValueArgs PO_FILES)
0180     cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
0181 
0182     if(ARGS_UNPARSED_ARGUMENTS)
0183         message(FATAL_ERROR "Unknown keywords given to ECM_CREATE_QM_FROM_PO_FILES(): \"${ARGS_UNPARSED_ARGUMENTS}\"")
0184     endif()
0185 
0186     if(NOT ARGS_PO_FILES)
0187         message(FATAL_ERROR "ECM_CREATE_QM_FROM_PO_FILES(): Must be called with PO_FILES argument")
0188     endif()
0189 
0190     if(NOT ARGS_INSTALL_DESTINATION)
0191         if (LOCALE_INSTALL_DIR)
0192             set(ARGS_INSTALL_DESTINATION "${LOCALE_INSTALL_DIR}")
0193         elseif (CMAKE_INSTALL_LOCALEDIR)
0194             set(ARGS_INSTALL_DESTINATION "${CMAKE_INSTALL_LOCALEDIR}")
0195         else()
0196             set(ARGS_INSTALL_DESTINATION share/locale)
0197         endif()
0198     endif()
0199 
0200     _ecm_qm_create_target(${ARGS_INSTALL_DESTINATION} "${ARGS_CATALOG_NAME}" ${ARGS_PO_FILES})
0201 endfunction()
0202 
0203 # Handles the syntax exposed in ECM 0.0.12, shipped with KDE Frameworks 5.0beta1
0204 #
0205 # This is a macro so that the value written in ${ARGS_CREATE_LOADER} is
0206 # correctly propagated to ECM_CREATE_QM_FROM_PO_FILES parent scope. If it were
0207 # not a macro, ECM_CREATE_QM_FROM_PO_FILES would have to ckeck if
0208 # CREATE_LOADER is in the arguments and propagate the value itself.
0209 macro(_ECM_CREATE_QM_FROM_PO_FILES_LEGACY)
0210     set(options)
0211     set(oneValueArgs PO_DIR POT_NAME DATA_INSTALL_DIR DATA_INSTALL_SUB_DIR CREATE_LOADER)
0212     set(multiValueArgs)
0213     cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
0214 
0215     if(ARGS_UNPARSED_ARGUMENTS)
0216         message(FATAL_ERROR "Unknown keywords given to _ECM_CREATE_QM_FROM_PO_FILES_LEGACY(): \"${ARGS_UNPARSED_ARGUMENTS}\"")
0217     endif()
0218 
0219     if(NOT ARGS_POT_NAME)
0220         message(FATAL_ERROR "Required argument POT_NAME missing in _ECM_CREATE_QM_FROM_PO_FILES_LEGACY() call")
0221     endif()
0222     get_filename_component(catalog_name ${ARGS_POT_NAME} NAME_WE)
0223 
0224     if (LOCALE_INSTALL_DIR)
0225         set(install_destination "${LOCALE_INSTALL_DIR}")
0226     elseif (CMAKE_INSTALL_LOCALEDIR)
0227         set(install_destination "${CMAKE_INSTALL_LOCALEDIR}")
0228     else()
0229         set(install_destination share/locale)
0230     endif()
0231 
0232     file(GLOB po_files "${ARGS_PO_DIR}/*.po")
0233     _ecm_qm_create_target(${install_destination} "${catalog_name}" ${po_files})
0234 
0235     if (ARGS_CREATE_LOADER)
0236         ecm_create_qm_loader(loader ${catalog_name})
0237         set(${ARGS_CREATE_LOADER} ${loader} PARENT_SCOPE)
0238     endif()
0239 endmacro()