Browse Source

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
debian/1.8.y
Julian Andres Klode 6 years ago
parent
commit
e164341c20
  1. 25
      CMake/Translations.cmake

25
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 ...])

Loading…
Cancel
Save