From e164341c20625f62a44be16e6f3fbab66334f130 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 9 Aug 2016 13:10:28 +0200 Subject: CMake: Translations: Avoid rebuilding .mo if .pot did not change Use the witness/byproducts approach to build the translations. A byproduct of a command is like an output, but may be older than the input. Here, we generate a normal template with headers in the normal way as a witness (and for Launchpad translations), but we also generate a .pot-tmp0 template file without a header that gets copied to a .pot-tmp byproduct only if it changed. This way, the .pot-tmp is only updated if an actual string translation changed. We also create a custom target for the .pot file that we'll depend on later in the overall target creating the mo files to ensure that the template is build before we try to build mo files. Then we make the msgmerge depend on the .pot-tmp instead of the .pot file, which means that msgmerge and msgfmt only get re-run if a string change occured. Gbp-Dch: ignore --- CMake/Translations.cmake | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'CMake') diff --git a/CMake/Translations.cmake b/CMake/Translations.cmake index 8b657c20f..584c5c5af 100644 --- a/CMake/Translations.cmake +++ b/CMake/Translations.cmake @@ -75,16 +75,32 @@ function(apt_add_translation_domain) WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} ) + # We are building a ${domain}.pot with a header for launchpad, but we also + # build a ${domain.pot}-tmp as a byproduct. The msgfmt command than depend + # on the byproduct while their target depends on the output, so that msgfmt + # does not have to be rerun if nothing in the template changed. add_custom_command (OUTPUT ${PROJECT_BINARY_DIR}/${domain}.pot + BYPRODUCTS ${PROJECT_BINARY_DIR}/${domain}.pot-tmp COMMAND msgcomm --more-than=0 --sort-by-file ${sh_pot} ${PROJECT_BINARY_DIR}/${domain}.c.pot --output=${PROJECT_BINARY_DIR}/${domain}.pot + COMMAND msgcomm --more-than=0 --omit-header --sort-by-file + ${sh_pot} + ${PROJECT_BINARY_DIR}/${domain}.c.pot + --output=${PROJECT_BINARY_DIR}/${domain}.pot-tmp0 + COMMAND cmake -E copy_if_different + ${PROJECT_BINARY_DIR}/${domain}.pot-tmp0 + ${PROJECT_BINARY_DIR}/${domain}.pot-tmp DEPENDS ${sh_pot} ${PROJECT_BINARY_DIR}/${domain}.c.pot WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} ) + # We need a target to depend on otherwise, the msgmerge might not get called + # with the make generator + add_custom_target(nls-${domain}-template DEPENDS ${PROJECT_BINARY_DIR}/${domain}.pot) + # Build .mo files file(GLOB translations "${PROJECT_SOURCE_DIR}/po/*.po") list(SORT translations) @@ -92,10 +108,11 @@ function(apt_add_translation_domain) get_filename_component(langcode ${file} NAME_WE) set(outdir ${PROJECT_BINARY_DIR}/locale/${langcode}/LC_MESSAGES) file(MAKE_DIRECTORY ${outdir}) - # Command to merge and compile the messages + # Command to merge and compile the messages. As explained in the custom + # command for msgcomm, this depends on byproduct to avoid reruns add_custom_command(OUTPUT ${outdir}/${domain}.po - COMMAND msgmerge -qo ${outdir}/${domain}.po ${file} ${PROJECT_BINARY_DIR}/${domain}.pot - DEPENDS ${file} ${PROJECT_BINARY_DIR}/${domain}.pot + COMMAND msgmerge -qo ${outdir}/${domain}.po ${file} ${PROJECT_BINARY_DIR}/${domain}.pot-tmp + DEPENDS ${file} ${PROJECT_BINARY_DIR}/${domain}.pot-tmp ) add_custom_command(OUTPUT ${outdir}/${domain}.mo COMMAND msgfmt --statistics -o ${outdir}/${domain}.mo ${outdir}/${domain}.po @@ -107,7 +124,7 @@ function(apt_add_translation_domain) DESTINATION "${CMAKE_INSTALL_LOCALEDIR}/${langcode}/LC_MESSAGES") endforeach(file ${translations}) - add_custom_target(nls-${domain} ALL DEPENDS ${mofiles}) + add_custom_target(nls-${domain} ALL DEPENDS ${mofiles} nls-${domain}-template) endfunction() # Usage: apt_add_update_po(output domain [domain ...]) -- cgit v1.2.3