summaryrefslogtreecommitdiff
path: root/CMake/Translations.cmake
blob: 7bdcab6abecab451d6eb8cdfa17903f0b91301ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# translations.cmake - Translations using APT's translation system.
# Copyright (C) 2009, 2016 Julian Andres Klode <jak@debian.org>

function(apt_add_translation_domain)
    set(options)
    set(oneValueArgs DOMAIN)
    set(multiValueArgs TARGETS SCRIPTS EXCLUDE_LANGUAGES)
    cmake_parse_arguments(NLS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
    # Build the list of source files of the target
    set(files "")
    set(abs_files "")
    set(scripts "")
    set(abs_scripts "")
    set(targets ${NLS_TARGETS})
    set(domain ${NLS_DOMAIN})
    set(xgettext_params
        --add-comments
        --foreign
        --package-name=${PROJECT_NAME}
        --package-version=${PACKAGE_VERSION}
        --msgid-bugs-address=${PACKAGE_MAIL}
    )
    foreach(source ${NLS_SCRIPTS})
            string(SUBSTRING ${source} 0 1 init_char)
            string(COMPARE EQUAL ${init_char} "/" is_absolute)
            if (${is_absolute})
                set(file "${source}")
            else()
                set(file "${CMAKE_CURRENT_SOURCE_DIR}/${source}")
            endif()
            file(RELATIVE_PATH relfile ${PROJECT_SOURCE_DIR} ${file})
            list(APPEND scripts ${relfile})
            list(APPEND abs_scripts ${file})
        endforeach()
    foreach(target ${targets})
        get_target_property(source_dir ${target} SOURCE_DIR)
        get_target_property(sources ${target} SOURCES)
        foreach(source ${sources})
            string(SUBSTRING ${source} 0 1 init_char)
            string(COMPARE EQUAL ${init_char} "/" is_absolute)
            if (${is_absolute})
                set(file "${source}")
            else()
                set(file "${source_dir}/${source}")
            endif()
            file(RELATIVE_PATH relfile ${PROJECT_SOURCE_DIR} ${file})
            set(files ${files} ${relfile})
            set(abs_files ${abs_files} ${file})
        endforeach()

        target_compile_definitions(${target} PRIVATE -DAPT_DOMAIN="${domain}")
    endforeach()

    if("${scripts}" STREQUAL "")
        set(sh_pot "/dev/null")
    else()
        set(sh_pot ${CMAKE_CURRENT_BINARY_DIR}/${domain}.sh.pot)
        # Create the template for this specific sub-domain
        add_custom_command (OUTPUT ${sh_pot}
            COMMAND xgettext ${xgettext_params} -L Shell
                             -o ${sh_pot} ${scripts}
            DEPENDS ${abs_scripts}
            VERBATIM
            WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
        )
    endif()


    add_custom_command (OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${domain}.c.pot
        COMMAND xgettext ${xgettext_params} -k_ -kN_
                         --keyword=P_:1,2
                         -o ${CMAKE_CURRENT_BINARY_DIR}/${domain}.c.pot ${files}
        DEPENDS ${abs_files}
        VERBATIM
        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 ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot
        BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot-tmp
        COMMAND msgcomm --more-than=0 --sort-by-file
                         ${sh_pot}
                         ${CMAKE_CURRENT_BINARY_DIR}/${domain}.c.pot
                         --output=${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot
        COMMAND msgcomm --more-than=0 --omit-header --sort-by-file
                         ${sh_pot}
                         ${CMAKE_CURRENT_BINARY_DIR}/${domain}.c.pot
                         --output=${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot-tmp0
        COMMAND cmake -E copy_if_different
                         ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot-tmp0
                         ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot-tmp
        DEPENDS ${sh_pot}
                ${CMAKE_CURRENT_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 ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot)

    # Build .mo files
    file(GLOB translations "${PROJECT_SOURCE_DIR}/po/*.po")
    list(SORT translations)
    foreach(file ${translations})
        get_filename_component(langcode ${file} NAME_WE)
        if ("${langcode}" IN_LIST NLS_EXCLUDE_LANGUAGES)
            continue()
        endif()
        set(outdir ${CMAKE_CURRENT_BINARY_DIR}/locale/${langcode}/LC_MESSAGES)
        file(MAKE_DIRECTORY ${outdir})
        # 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} ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot-tmp
            DEPENDS ${file} ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot-tmp
        )
        add_custom_command(OUTPUT ${outdir}/${domain}.mo
            COMMAND msgfmt --statistics -o ${outdir}/${domain}.mo  ${outdir}/${domain}.po
            DEPENDS ${outdir}/${domain}.po
        )

        set(mofiles ${mofiles} ${outdir}/${domain}.mo)
        install(FILES ${outdir}/${domain}.mo
                DESTINATION "${CMAKE_INSTALL_LOCALEDIR}/${langcode}/LC_MESSAGES")
    endforeach(file ${translations})

    add_custom_target(nls-${domain} ALL DEPENDS ${mofiles} nls-${domain}-template)
endfunction()

# Usage: apt_add_update_po(output domain [domain ...])
function(apt_add_update_po)
    set(options)
    set(oneValueArgs TEMPLATE)
    set(multiValueArgs DOMAINS EXCLUDE_LANGUAGES)
    cmake_parse_arguments(NLS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
    set(output ${CMAKE_CURRENT_SOURCE_DIR}/${NLS_TEMPLATE}.pot)
    foreach(domain ${NLS_DOMAINS})
        list(APPEND potfiles ${CMAKE_CURRENT_BINARY_DIR}/${domain}.pot)
    endforeach()

    get_filename_component(master_name ${output} NAME_WE)
    add_custom_target(nls-${master_name}
                       COMMAND msgcomm --sort-by-file --add-location=file
                                        --more-than=0 --output=${output}
                                ${potfiles}
                       DEPENDS ${potfiles})

    file(GLOB translations "${PROJECT_SOURCE_DIR}/po/*.po")
    if (NOT TARGET update-po)
        add_custom_target(update-po)
    endif()
    foreach(translation ${translations})
            get_filename_component(langcode ${translation} NAME_WE)
            if ("${langcode}" IN_LIST NLS_EXCLUDE_LANGUAGES)
                continue()
            endif()
            add_custom_target(update-po-${langcode}
                COMMAND msgmerge -q --update --backup=none ${translation} ${output}
                DEPENDS nls-${master_name}
            )
            add_dependencies(update-po update-po-${langcode})
    endforeach()
    add_dependencies(update-po nls-${master_name})
endfunction()

function(apt_add_po_statistics excluded)
    add_custom_target(statistics)
    file(GLOB translations "${PROJECT_SOURCE_DIR}/po/*.po")
    foreach(translation ${translations})
            get_filename_component(langcode ${translation} NAME_WE)
            if ("${langcode}" IN_LIST excluded)
                add_custom_command(
                    TARGET statistics PRE_BUILD
                    COMMAND printf "%-6s " "${langcode}:"
                    COMMAND echo "ignored"
                    VERBATIM
                )
                continue()
            endif()
            add_custom_command(
                TARGET statistics PRE_BUILD
                COMMAND printf "%-6s " "${langcode}:"
                COMMAND msgfmt --statistics -o /dev/null ${translation}
                VERBATIM
            )
    endforeach()
endfunction()