#.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( [ALL] # [INSTALL_DESTINATION ] # PO_FILES [ [...]]) # # Compile .po files into .qm files for the given language. # # If INSTALL_DESTINATION is given, the .qm files are installed in # ``//LC_MESSAGES``. Typically, # ```` 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( ) # # Generates a C++ file which ensures translations are automatically loaded at # startup. The path of the .cpp file is appended to ````. # # It assumes that the .qm file for the language code ```` is installed as # ``/locale//LC_MESSAGES/.qm``, where # ```` 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() # # 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 # ``//``, where ```` 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 ``/fr/LC_MESSAGES``. # ```` 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 # Copyright 2014 Aurélien Gâteau # # 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} NO_DEFAULT_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 po_files "${podir}/*/*.po") foreach(po_file ${po_files}) get_filename_component(po_dir ${po_file} DIRECTORY) get_filename_component(lang ${po_dir} NAME) ecm_process_po_files_as_qm( ${lang} ALL PO_FILES ${po_file} INSTALL_DESTINATION ${install_destination} ) endforeach() endfunction()