From a078e08390e41385a3145f22e83afbf622621c2f Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Tue, 21 Aug 2018 23:31:45 +0200 Subject: [PATCH] cmake: Modernize translation generation Refactor and modernize the CMake support for translation generation. Properly use targets, custom commands and dependencies to ensure that files are only regenerated when needed, and avoid useless rebuilds. Avoid individual invocations of lupdate and lrelease, which both support processing multiple files at once. Make use of the newly added quassel_add_resource function instead of building the .qrc file explicitly. Fix LINGUAS support, which was previously not working as intended. --- cmake/QuasselMacros.cmake | 35 ---------- po/CMakeLists.txt | 135 +++++++++++++++++++++----------------- 2 files changed, 74 insertions(+), 96 deletions(-) diff --git a/cmake/QuasselMacros.cmake b/cmake/QuasselMacros.cmake index 318defb8..1c0c687c 100644 --- a/cmake/QuasselMacros.cmake +++ b/cmake/QuasselMacros.cmake @@ -158,38 +158,3 @@ function(target_link_if_exists _target) endforeach() endif() endfunction() - -###################################### -# Macros for dealing with translations -###################################### - -# This generates a .ts from a .po file -macro(generate_ts outvar basename) - set(input ${basename}.po) - set(output ${CMAKE_BINARY_DIR}/po/${basename}.ts) - add_custom_command(OUTPUT ${output} - COMMAND $ - ARGS -i ${input} - -of ts - -o ${output} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/po -# This is a workaround to add (duplicate) strings that lconvert missed to the .ts - COMMAND $ - ARGS -silent - ${CMAKE_SOURCE_DIR}/src/ - -ts ${output} - DEPENDS ${basename}.po) - set(${outvar} ${output}) -endmacro(generate_ts outvar basename) - -# This generates a .qm from a .ts file -macro(generate_qm outvar basename) - set(input ${CMAKE_BINARY_DIR}/po/${basename}.ts) - set(output ${CMAKE_BINARY_DIR}/po/${basename}.qm) - add_custom_command(OUTPUT ${output} - COMMAND $ - ARGS -silent - ${input} - DEPENDS ${basename}.ts) - set(${outvar} ${output}) -endmacro(generate_qm outvar basename) diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt index 196e13d8..e7df6271 100644 --- a/po/CMakeLists.txt +++ b/po/CMakeLists.txt @@ -1,71 +1,84 @@ -# Generate and add translations -# The LINGUAS variable can be used to limit that set +# Generate translations +# The LINGUAS environment variable can be used to limit the set of supported languages + +# Generate a .ts file from a .po file +function(generate_ts basename) + set(pofile ${CMAKE_CURRENT_SOURCE_DIR}/${basename}.po) + set(tsfile ${CMAKE_CURRENT_BINARY_DIR}/${basename}.ts) + + add_custom_command(VERBATIM + COMMENT "Preparing translation for language '${basename}'" + COMMAND $ -i ${pofile} -target-language ${basename} -of ts -o ${tsfile} + DEPENDS ${pofile} + OUTPUT ${tsfile} + ) +endfunction() + +# Clear variables just in case +set(tsfiles ) +set(qmfiles ) +set(linguas ) if (TARGET Qt5::lconvert) - # get environment variable for translations - set(LINGUAS "$ENV{LINGUAS}") - string(REGEX REPLACE "[ \t]+" \; output "${LINGUAS}") - # Find more languages - # We support xx.po and xx_YY.po, and additionally translations for qt using qt_xx.po or qt_xx_YY.po - file(GLOB avail_pofiles *.po) - foreach(PO_FILE ${avail_pofiles}) - get_filename_component(basename ${PO_FILE} NAME_WE) - # CMake can't use MATCH to get the second catch... - string(REGEX REPLACE "(qt_)?([a-zA-Z]+)(_.+)?$" "\\2" lang ${basename}) + # LINGUAS can be used to limit the included languages + set(LINGUAS "$ENV{LINGUAS}") + # Normalize and convert into list + string(REGEX REPLACE "[ \t,;]+" ";" LINGUAS "${LINGUAS}") - # test if we want this language - set(flg 1) - if(LINGUAS) - string(REGEX MATCH "${lang}" flg ${LINGUAS}) - endif() - if(flg) - generate_ts(QM ${basename}) - generate_qm(QM ${basename}) - list(APPEND qm_files ${QM}) - list(APPEND gen_linguas ${lang}) + # We support xx.po and xx_YY.po, and additionally translations for qt using qt_xx.po or qt_xx_YY.po + file(GLOB pofiles *.po) + foreach(pofile ${pofiles}) + get_filename_component(basename ${pofile} NAME_WE) + # CMake can't use MATCH to get the second catch... + string(REGEX REPLACE "(qt_)?([a-zA-Z]+)(_.+)?$" "\\2" lang ${basename}) + # Test if we want this language + set(idx 0) + if(LINGUAS) + list(FIND LINGUAS ${lang} idx) # idx will be -1 if ${lang} is not found in LINGUAS + endif() + if(idx GREATER -1) + generate_ts(${basename}) + list(APPEND tsfiles ${CMAKE_CURRENT_BINARY_DIR}/${basename}.ts) + list(APPEND qmfiles ${CMAKE_CURRENT_BINARY_DIR}/${basename}.qm) + list(APPEND linguas ${lang}) + endif() + endforeach() + + if (tsfiles) + # Synchronize the (possibly outdated) .ts files with the current source tree + add_custom_command(VERBATIM + COMMENT "Syncing translations" + COMMAND $ -silent ${CMAKE_SOURCE_DIR}/src -ts ${tsfiles} + COMMAND ${CMAKE_COMMAND} -E touch tsfiles.done + DEPENDS ${tsfiles} + OUTPUT tsfiles.depends + ) + + # Generate the final translation files (.qm) for use by Qt + add_custom_command(VERBATIM + COMMENT "Compressing translations" + COMMAND $ -silent ${tsfiles} + DEPENDS tsfiles.depends + OUTPUT ${qmfiles} + ) + + # Curate the language list and give diagnostic output + list(REMOVE_DUPLICATES linguas) + list(SORT linguas) + string(REPLACE ";" ", " linguas_string "${linguas}") + message(STATUS "Enabling translations for: ${linguas_string}") + else() + message(STATUS "No translations enabled") endif() - endforeach(PO_FILE ${avail_pofiles}) - if(gen_linguas) - list(REMOVE_DUPLICATES gen_linguas) - endif() - message(STATUS "Including languages: ${gen_linguas}") else() - message(STATUS "WARNING: lconvert not found, you won't have translations!") + message(WARNING "Qt Linguist Tools not found, you won't have translations!") endif() -# For a Win32 build, we need to include Qt translations if available -if(QT_TRANSLATIONS_DIR) - if(WIN32) - foreach(LANG ${gen_linguas}) - file(GLOB lang_files ${QT_TRANSLATIONS_DIR}/qt_${LANG}*.qm) - foreach(absfile ${lang_files}) - get_filename_component(filename ${absfile} NAME) - message(STATUS "Importing ${filename}") - configure_file(${absfile} ${CMAKE_CURRENT_BINARY_DIR}/${filename} COPYONLY) - list(APPEND qm_files ${CMAKE_CURRENT_BINARY_DIR}/${filename}) - endforeach(absfile ${lang_files}) - endforeach(LANG ${gen_linguas}) - endif() -endif() - -# Write resource file -set(resfile ${CMAKE_CURRENT_BINARY_DIR}/i18n.qrc) -file(WRITE ${resfile} "\n" - "\n") -foreach(file ${qm_files}) - get_filename_component(file ${file} NAME) - file(APPEND ${resfile} " ${file}\n") -endforeach(file ${qm_files}) -file(APPEND ${resfile} "\n\n") - -#add_custom_command(OUTPUT ${resfile} DEPENDS ${qm_files}) -set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${qm_files};i18n.qrc") +# Always generate translations +add_custom_target(translations ALL DEPENDS ${qmfiles}) -if(EMBED_DATA) - quassel_add_module(Resource::I18n) - target_sources(${TARGET} PRIVATE ${resfile}) - add_custom_target(po DEPENDS ${qm_files}) - add_dependencies(${TARGET} po) +if (EMBED_DATA) + quassel_add_resource(I18n PREFIX i18n BASEDIR ${CMAKE_CURRENT_BINARY_DIR} PATTERNS ${qmfiles} DEPENDS translations) else() - install(FILES ${qm_files} DESTINATION ${CMAKE_INSTALL_DATADIR}/quassel/translations) + install(FILES ${qmfiles} DESTINATION ${CMAKE_INSTALL_DATADIR}/quassel/translations) endif() -- 2.20.1