1 # translations.cmake - Translations using APT's translation system.
2 # Copyright (C) 2009, 2016 Julian Andres Klode <jak@debian.org>
4 function(apt_add_translation_domain)
6 set(oneValueArgs DOMAIN)
7 set(multiValueArgs TARGETS SCRIPTS EXCLUDE_LANGUAGES)
8 cmake_parse_arguments(NLS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
9 # Build the list of source files of the target
15 set(targets ${NLS_TARGETS})
16 set(domain ${NLS_DOMAIN})
20 --package-name=${PROJECT_NAME}
21 --package-version=${PACKAGE_VERSION}
22 --msgid-bugs-address=${PACKAGE_MAIL}
24 foreach(source ${NLS_SCRIPTS})
25 path_join(file "${CMAKE_CURRENT_SOURCE_DIR}" "${source}")
26 file(RELATIVE_PATH relfile ${PROJECT_SOURCE_DIR} ${file})
27 list(APPEND scripts ${relfile})
28 list(APPEND abs_scripts ${file})
30 foreach(target ${targets})
31 get_target_property(source_dir ${target} SOURCE_DIR)
32 get_target_property(sources ${target} SOURCES)
33 foreach(source ${sources})
34 path_join(file "${source_dir}" "${source}")
35 file(RELATIVE_PATH relfile ${PROJECT_SOURCE_DIR} ${file})
36 set(files ${files} ${relfile})
37 set(abs_files ${abs_files} ${file})
40 target_compile_definitions(${target} PRIVATE -DAPT_DOMAIN="${domain}")
43 if("${scripts}" STREQUAL "")
44 set(sh_pot "/dev/null")
46 set(sh_pot ${CMAKE_CURRENT_BINARY_DIR}/${domain}.sh.pot)
47 # Create the template for this specific sub-domain
48 add_custom_command (OUTPUT ${sh_pot}
49 COMMAND xgettext ${xgettext_params} -L Shell
50 -o ${sh_pot} ${scripts}
51 DEPENDS ${abs_scripts}
53 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
58 add_custom_command (OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${domain}.c.pot
59 COMMAND xgettext ${xgettext_params} -k_ -kN_
61 -o ${CMAKE_CURRENT_BINARY_DIR}/${domain}.c.pot ${files}
64 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
67 # We are building a ${domain}.pot with a header for launchpad, but we also
68 # build a ${domain.pot}-tmp as a byproduct. The msgfmt command than depend
69 # on the byproduct while their target depends on the output, so that msgfmt
70 # does not have to be rerun if nothing in the template changed.
72 # Make sure the .pot-tmp has no line numbers, to avoid useless rebuilding
74 add_custom_command (OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot
75 BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot-tmp
76 COMMAND msgcomm --more-than=0 --omit-header --sort-by-file --add-location=file
78 ${CMAKE_CURRENT_BINARY_DIR}/${domain}.c.pot
79 --output=${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot-tmp0
80 COMMAND msgcomm --more-than=0 --sort-by-file
82 ${CMAKE_CURRENT_BINARY_DIR}/${domain}.c.pot
83 --output=${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot
84 COMMAND cmake -E copy_if_different
85 ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot-tmp0
86 ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot-tmp
88 ${CMAKE_CURRENT_BINARY_DIR}/${domain}.c.pot
89 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
92 # We need a target to depend on otherwise, the msgmerge might not get called
93 # with the make generator
94 add_custom_target(nls-${domain}-template DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot)
97 file(GLOB translations "${PROJECT_SOURCE_DIR}/po/*.po")
98 list(SORT translations)
99 foreach(file ${translations})
100 get_filename_component(langcode ${file} NAME_WE)
101 if ("${langcode}" IN_LIST NLS_EXCLUDE_LANGUAGES)
104 set(outdir ${CMAKE_CURRENT_BINARY_DIR}/locale/${langcode}/LC_MESSAGES)
105 file(MAKE_DIRECTORY ${outdir})
106 # Command to merge and compile the messages. As explained in the custom
107 # command for msgcomm, this depends on byproduct to avoid reruns
108 add_custom_command(OUTPUT ${outdir}/${domain}.po
109 COMMAND msgmerge -qo ${outdir}/${domain}.po ${file} ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot-tmp
110 DEPENDS ${file} ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot-tmp
112 add_custom_command(OUTPUT ${outdir}/${domain}.mo
113 COMMAND msgfmt --statistics -o ${outdir}/${domain}.mo ${outdir}/${domain}.po
114 DEPENDS ${outdir}/${domain}.po
117 set(mofiles ${mofiles} ${outdir}/${domain}.mo)
118 install(FILES ${outdir}/${domain}.mo
119 DESTINATION "${CMAKE_INSTALL_LOCALEDIR}/${langcode}/LC_MESSAGES")
120 endforeach(file ${translations})
122 add_custom_target(nls-${domain} ALL DEPENDS ${mofiles} nls-${domain}-template)
125 # Usage: apt_add_update_po(output domain [domain ...])
126 function(apt_add_update_po)
128 set(oneValueArgs TEMPLATE)
129 set(multiValueArgs DOMAINS EXCLUDE_LANGUAGES)
130 cmake_parse_arguments(NLS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
131 set(output ${CMAKE_CURRENT_SOURCE_DIR}/${NLS_TEMPLATE}.pot)
132 foreach(domain ${NLS_DOMAINS})
133 list(APPEND potfiles ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot)
136 get_filename_component(master_name ${output} NAME_WE)
137 add_custom_target(nls-${master_name}
138 COMMAND msgcomm --sort-by-file --add-location=file
139 --more-than=0 --output=${output}
143 file(GLOB translations "${PROJECT_SOURCE_DIR}/po/*.po")
144 if (NOT TARGET update-po)
145 add_custom_target(update-po)
147 foreach(translation ${translations})
148 get_filename_component(langcode ${translation} NAME_WE)
149 if ("${langcode}" IN_LIST NLS_EXCLUDE_LANGUAGES)
152 add_custom_target(update-po-${langcode}
153 COMMAND msgmerge -q --previous --update --backup=none ${translation} ${output}
154 DEPENDS nls-${master_name}
156 add_dependencies(update-po update-po-${langcode})
158 add_dependencies(update-po nls-${master_name})
161 function(apt_add_po_statistics excluded)
162 add_custom_target(statistics)
163 file(GLOB translations "${PROJECT_SOURCE_DIR}/po/*.po")
164 foreach(translation ${translations})
165 get_filename_component(langcode ${translation} NAME_WE)
166 if ("${langcode}" IN_LIST excluded)
168 TARGET statistics PRE_BUILD
169 COMMAND printf "%-6s " "${langcode}:"
170 COMMAND echo "ignored"
176 TARGET statistics PRE_BUILD
177 COMMAND printf "%-6s " "${langcode}:"
178 COMMAND msgfmt --statistics -o /dev/null ${translation}