1# Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2# file Copyright.txt or https://cmake.org/licensing for details. 3 4#[=======================================================================[.rst: 5FindGettext 6----------- 7 8Find GNU gettext tools 9 10This module looks for the GNU gettext tools. This module defines the 11following values: 12 13:: 14 15 GETTEXT_MSGMERGE_EXECUTABLE: the full path to the msgmerge tool. 16 GETTEXT_MSGFMT_EXECUTABLE: the full path to the msgfmt tool. 17 GETTEXT_FOUND: True if gettext has been found. 18 GETTEXT_VERSION_STRING: the version of gettext found (since CMake 2.8.8) 19 20 21 22Additionally it provides the following macros: 23 24GETTEXT_CREATE_TRANSLATIONS ( outputFile [ALL] file1 ... fileN ) 25 26:: 27 28 This will create a target "translations" which will convert the 29 given input po files into the binary output mo file. If the 30 ALL option is used, the translations will also be created when 31 building the default target. 32 33GETTEXT_PROCESS_POT_FILE( <potfile> [ALL] [INSTALL_DESTINATION <destdir>] 34LANGUAGES <lang1> <lang2> ... ) 35 36:: 37 38 Process the given pot file to mo files. 39 If INSTALL_DESTINATION is given then automatically install rules will 40 be created, the language subdirectory will be taken into account 41 (by default use share/locale/). 42 If ALL is specified, the pot file is processed when building the all target. 43 It creates a custom target "potfile". 44 45GETTEXT_PROCESS_PO_FILES( <lang> [ALL] [INSTALL_DESTINATION <dir>] 46PO_FILES <po1> <po2> ... ) 47 48:: 49 50 Process the given po files to mo files for the given language. 51 If INSTALL_DESTINATION is given then automatically install rules will 52 be created, the language subdirectory will be taken into account 53 (by default use share/locale/). 54 If ALL is specified, the po files are processed when building the all target. 55 It creates a custom target "pofiles". 56 57.. versionadded:: 3.2 58 If you wish to use the Gettext library (libintl), use :module:`FindIntl`. 59#]=======================================================================] 60 61find_program(GETTEXT_MSGMERGE_EXECUTABLE msgmerge) 62 63find_program(GETTEXT_MSGFMT_EXECUTABLE msgfmt) 64 65if(GETTEXT_MSGMERGE_EXECUTABLE) 66 execute_process(COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} --version 67 OUTPUT_VARIABLE gettext_version 68 ERROR_QUIET 69 OUTPUT_STRIP_TRAILING_WHITESPACE) 70 get_filename_component(msgmerge_name ${GETTEXT_MSGMERGE_EXECUTABLE} NAME) 71 get_filename_component(msgmerge_namewe ${GETTEXT_MSGMERGE_EXECUTABLE} NAME_WE) 72 if (gettext_version MATCHES "^(${msgmerge_name}|${msgmerge_namewe}) \\([^\\)]*\\) ([0-9\\.]+[^ \n]*)") 73 set(GETTEXT_VERSION_STRING "${CMAKE_MATCH_2}") 74 endif() 75 unset(gettext_version) 76 unset(msgmerge_name) 77 unset(msgmerge_namewe) 78endif() 79 80include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) 81FIND_PACKAGE_HANDLE_STANDARD_ARGS(Gettext 82 REQUIRED_VARS GETTEXT_MSGMERGE_EXECUTABLE GETTEXT_MSGFMT_EXECUTABLE 83 VERSION_VAR GETTEXT_VERSION_STRING) 84 85function(_GETTEXT_GET_UNIQUE_TARGET_NAME _name _unique_name) 86 set(propertyName "_GETTEXT_UNIQUE_COUNTER_${_name}") 87 get_property(currentCounter GLOBAL PROPERTY "${propertyName}") 88 if(NOT currentCounter) 89 set(currentCounter 1) 90 endif() 91 set(${_unique_name} "${_name}_${currentCounter}" PARENT_SCOPE) 92 math(EXPR currentCounter "${currentCounter} + 1") 93 set_property(GLOBAL PROPERTY ${propertyName} ${currentCounter} ) 94endfunction() 95 96macro(GETTEXT_CREATE_TRANSLATIONS _potFile _firstPoFileArg) 97 # make it a real variable, so we can modify it here 98 set(_firstPoFile "${_firstPoFileArg}") 99 100 set(_gmoFiles) 101 get_filename_component(_potName ${_potFile} NAME) 102 string(REGEX REPLACE "^(.+)(\\.[^.]+)$" "\\1" _potBasename ${_potName}) 103 get_filename_component(_absPotFile ${_potFile} ABSOLUTE) 104 105 set(_addToAll) 106 if(${_firstPoFile} STREQUAL "ALL") 107 set(_addToAll "ALL") 108 set(_firstPoFile) 109 endif() 110 111 foreach (_currentPoFile ${_firstPoFile} ${ARGN}) 112 get_filename_component(_absFile ${_currentPoFile} ABSOLUTE) 113 get_filename_component(_abs_PATH ${_absFile} PATH) 114 get_filename_component(_lang ${_absFile} NAME_WE) 115 set(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo) 116 117 add_custom_command( 118 OUTPUT ${_gmoFile} 119 COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} --quiet --update --backup=none -s ${_absFile} ${_absPotFile} 120 COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_absFile} 121 DEPENDS ${_absPotFile} ${_absFile} 122 ) 123 124 install(FILES ${_gmoFile} DESTINATION share/locale/${_lang}/LC_MESSAGES RENAME ${_potBasename}.mo) 125 set(_gmoFiles ${_gmoFiles} ${_gmoFile}) 126 127 endforeach () 128 129 if(NOT TARGET translations) 130 add_custom_target(translations) 131 endif() 132 133 _GETTEXT_GET_UNIQUE_TARGET_NAME(translations uniqueTargetName) 134 135 add_custom_target(${uniqueTargetName} ${_addToAll} DEPENDS ${_gmoFiles}) 136 137 add_dependencies(translations ${uniqueTargetName}) 138 139endmacro() 140 141 142function(GETTEXT_PROCESS_POT_FILE _potFile) 143 set(_gmoFiles) 144 set(_options ALL) 145 set(_oneValueArgs INSTALL_DESTINATION) 146 set(_multiValueArgs LANGUAGES) 147 148 CMAKE_PARSE_ARGUMENTS(_parsedArguments "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) 149 150 get_filename_component(_potName ${_potFile} NAME) 151 string(REGEX REPLACE "^(.+)(\\.[^.]+)$" "\\1" _potBasename ${_potName}) 152 get_filename_component(_absPotFile ${_potFile} ABSOLUTE) 153 154 foreach (_lang ${_parsedArguments_LANGUAGES}) 155 set(_poFile "${CMAKE_CURRENT_BINARY_DIR}/${_lang}.po") 156 set(_gmoFile "${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo") 157 158 add_custom_command( 159 OUTPUT "${_poFile}" 160 COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} --quiet --update --backup=none -s ${_poFile} ${_absPotFile} 161 DEPENDS ${_absPotFile} 162 ) 163 164 add_custom_command( 165 OUTPUT "${_gmoFile}" 166 COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_poFile} 167 DEPENDS ${_absPotFile} ${_poFile} 168 ) 169 170 if(_parsedArguments_INSTALL_DESTINATION) 171 install(FILES ${_gmoFile} DESTINATION ${_parsedArguments_INSTALL_DESTINATION}/${_lang}/LC_MESSAGES RENAME ${_potBasename}.mo) 172 endif() 173 list(APPEND _gmoFiles ${_gmoFile}) 174 endforeach () 175 176 if(NOT TARGET potfiles) 177 add_custom_target(potfiles) 178 endif() 179 180 _GETTEXT_GET_UNIQUE_TARGET_NAME( potfiles uniqueTargetName) 181 182 if(_parsedArguments_ALL) 183 add_custom_target(${uniqueTargetName} ALL DEPENDS ${_gmoFiles}) 184 else() 185 add_custom_target(${uniqueTargetName} DEPENDS ${_gmoFiles}) 186 endif() 187 188 add_dependencies(potfiles ${uniqueTargetName}) 189 190endfunction() 191 192 193function(GETTEXT_PROCESS_PO_FILES _lang) 194 set(_options ALL) 195 set(_oneValueArgs INSTALL_DESTINATION) 196 set(_multiValueArgs PO_FILES) 197 set(_gmoFiles) 198 199 CMAKE_PARSE_ARGUMENTS(_parsedArguments "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) 200 201 foreach(_current_PO_FILE ${_parsedArguments_PO_FILES}) 202 get_filename_component(_name ${_current_PO_FILE} NAME) 203 string(REGEX REPLACE "^(.+)(\\.[^.]+)$" "\\1" _basename ${_name}) 204 set(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.gmo) 205 add_custom_command(OUTPUT ${_gmoFile} 206 COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_current_PO_FILE} 207 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 208 DEPENDS ${_current_PO_FILE} 209 ) 210 211 if(_parsedArguments_INSTALL_DESTINATION) 212 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.gmo DESTINATION ${_parsedArguments_INSTALL_DESTINATION}/${_lang}/LC_MESSAGES/ RENAME ${_basename}.mo) 213 endif() 214 list(APPEND _gmoFiles ${_gmoFile}) 215 endforeach() 216 217 218 if(NOT TARGET pofiles) 219 add_custom_target(pofiles) 220 endif() 221 222 _GETTEXT_GET_UNIQUE_TARGET_NAME( pofiles uniqueTargetName) 223 224 if(_parsedArguments_ALL) 225 add_custom_target(${uniqueTargetName} ALL DEPENDS ${_gmoFiles}) 226 else() 227 add_custom_target(${uniqueTargetName} DEPENDS ${_gmoFiles}) 228 endif() 229 230 add_dependencies(pofiles ${uniqueTargetName}) 231 232endfunction() 233