jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

221 lines
6.5KB

  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. # Thomas Nagy, 2006-2010 (ita)
  4. """
  5. Support for translation tools such as msgfmt and intltool
  6. Usage::
  7. def configure(conf):
  8. conf.load('gnu_dirs intltool')
  9. def build(bld):
  10. # process the .po files into .gmo files, and install them in LOCALEDIR
  11. bld(features='intltool_po', appname='myapp', podir='po', install_path="${LOCALEDIR}")
  12. # process an input file, substituting the translations from the po dir
  13. bld(
  14. features = "intltool_in",
  15. podir = "../po",
  16. style = "desktop",
  17. flags = ["-u"],
  18. source = 'kupfer.desktop.in',
  19. install_path = "${DATADIR}/applications",
  20. )
  21. Usage of the :py:mod:`waflib.Tools.gnu_dirs` is recommended, but not obligatory.
  22. """
  23. import os, re
  24. from waflib import Configure, Context, TaskGen, Task, Utils, Runner, Options, Build, Logs
  25. import waflib.Tools.ccroot
  26. from waflib.TaskGen import feature, before_method, taskgen_method
  27. from waflib.Logs import error
  28. from waflib.Configure import conf
  29. _style_flags = {
  30. 'ba': '-b',
  31. 'desktop': '-d',
  32. 'keys': '-k',
  33. 'quoted': '--quoted-style',
  34. 'quotedxml': '--quotedxml-style',
  35. 'rfc822deb': '-r',
  36. 'schemas': '-s',
  37. 'xml': '-x',
  38. }
  39. @taskgen_method
  40. def ensure_localedir(self):
  41. """
  42. Expand LOCALEDIR from DATAROOTDIR/locale if possible, or fallback to PREFIX/share/locale
  43. """
  44. # use the tool gnu_dirs to provide options to define this
  45. if not self.env.LOCALEDIR:
  46. if self.env.DATAROOTDIR:
  47. self.env.LOCALEDIR = os.path.join(self.env.DATAROOTDIR, 'locale')
  48. else:
  49. self.env.LOCALEDIR = os.path.join(self.env.PREFIX, 'share', 'locale')
  50. @before_method('process_source')
  51. @feature('intltool_in')
  52. def apply_intltool_in_f(self):
  53. """
  54. Create tasks to translate files by intltool-merge::
  55. def build(bld):
  56. bld(
  57. features = "intltool_in",
  58. podir = "../po",
  59. style = "desktop",
  60. flags = ["-u"],
  61. source = 'kupfer.desktop.in',
  62. install_path = "${DATADIR}/applications",
  63. )
  64. :param podir: location of the .po files
  65. :type podir: string
  66. :param source: source files to process
  67. :type source: list of string
  68. :param style: the intltool-merge mode of operation, can be one of the following values:
  69. ``ba``, ``desktop``, ``keys``, ``quoted``, ``quotedxml``, ``rfc822deb``, ``schemas`` and ``xml``.
  70. See the ``intltool-merge`` man page for more information about supported modes of operation.
  71. :type style: string
  72. :param flags: compilation flags ("-quc" by default)
  73. :type flags: list of string
  74. :param install_path: installation path
  75. :type install_path: string
  76. """
  77. try: self.meths.remove('process_source')
  78. except ValueError: pass
  79. self.ensure_localedir()
  80. podir = getattr(self, 'podir', '.')
  81. podirnode = self.path.find_dir(podir)
  82. if not podirnode:
  83. error("could not find the podir %r" % podir)
  84. return
  85. cache = getattr(self, 'intlcache', '.intlcache')
  86. self.env.INTLCACHE = [os.path.join(str(self.path.get_bld()), podir, cache)]
  87. self.env.INTLPODIR = podirnode.bldpath()
  88. self.env.append_value('INTLFLAGS', getattr(self, 'flags', self.env.INTLFLAGS_DEFAULT))
  89. if '-c' in self.env.INTLFLAGS:
  90. self.bld.fatal('Redundant -c flag in intltool task %r' % self)
  91. style = getattr(self, 'style', None)
  92. if style:
  93. try:
  94. style_flag = _style_flags[style]
  95. except KeyError:
  96. self.bld.fatal('intltool_in style "%s" is not valid' % style)
  97. self.env.append_unique('INTLFLAGS', [style_flag])
  98. for i in self.to_list(self.source):
  99. node = self.path.find_resource(i)
  100. task = self.create_task('intltool', node, node.change_ext(''))
  101. inst = getattr(self, 'install_path', None)
  102. if inst:
  103. self.bld.install_files(inst, task.outputs)
  104. @feature('intltool_po')
  105. def apply_intltool_po(self):
  106. """
  107. Create tasks to process po files::
  108. def build(bld):
  109. bld(features='intltool_po', appname='myapp', podir='po', install_path="${LOCALEDIR}")
  110. The relevant task generator arguments are:
  111. :param podir: directory of the .po files
  112. :type podir: string
  113. :param appname: name of the application
  114. :type appname: string
  115. :param install_path: installation directory
  116. :type install_path: string
  117. The file LINGUAS must be present in the directory pointed by *podir* and list the translation files to process.
  118. """
  119. try: self.meths.remove('process_source')
  120. except ValueError: pass
  121. self.ensure_localedir()
  122. appname = getattr(self, 'appname', getattr(Context.g_module, Context.APPNAME, 'set_your_app_name'))
  123. podir = getattr(self, 'podir', '.')
  124. inst = getattr(self, 'install_path', '${LOCALEDIR}')
  125. linguas = self.path.find_node(os.path.join(podir, 'LINGUAS'))
  126. if linguas:
  127. # scan LINGUAS file for locales to process
  128. file = open(linguas.abspath())
  129. langs = []
  130. for line in file.readlines():
  131. # ignore lines containing comments
  132. if not line.startswith('#'):
  133. langs += line.split()
  134. file.close()
  135. re_linguas = re.compile('[-a-zA-Z_@.]+')
  136. for lang in langs:
  137. # Make sure that we only process lines which contain locales
  138. if re_linguas.match(lang):
  139. node = self.path.find_resource(os.path.join(podir, re_linguas.match(lang).group() + '.po'))
  140. task = self.create_task('po', node, node.change_ext('.mo'))
  141. if inst:
  142. filename = task.outputs[0].name
  143. (langname, ext) = os.path.splitext(filename)
  144. inst_file = inst + os.sep + langname + os.sep + 'LC_MESSAGES' + os.sep + appname + '.mo'
  145. self.bld.install_as(inst_file, task.outputs[0], chmod=getattr(self, 'chmod', Utils.O644), env=task.env)
  146. else:
  147. Logs.pprint('RED', "Error no LINGUAS file found in po directory")
  148. class po(Task.Task):
  149. """
  150. Compile .po files into .gmo files
  151. """
  152. run_str = '${MSGFMT} -o ${TGT} ${SRC}'
  153. color = 'BLUE'
  154. class intltool(Task.Task):
  155. """
  156. Let intltool-merge translate an input file
  157. """
  158. run_str = '${INTLTOOL} ${INTLFLAGS} ${INTLCACHE_ST:INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}'
  159. color = 'BLUE'
  160. @conf
  161. def find_msgfmt(conf):
  162. conf.find_program('msgfmt', var='MSGFMT')
  163. @conf
  164. def find_intltool_merge(conf):
  165. if not conf.env.PERL:
  166. conf.find_program('perl', var='PERL')
  167. conf.env.INTLCACHE_ST = '--cache=%s'
  168. conf.env.INTLFLAGS_DEFAULT = ['-q', '-u']
  169. conf.find_program('intltool-merge', interpreter='PERL', var='INTLTOOL')
  170. def configure(conf):
  171. """
  172. Detect the program *msgfmt* and set *conf.env.MSGFMT*.
  173. Detect the program *intltool-merge* and set *conf.env.INTLTOOL*.
  174. It is possible to set INTLTOOL in the environment, but it must not have spaces in it::
  175. $ INTLTOOL="/path/to/the program/intltool" waf configure
  176. If a C/C++ compiler is present, execute a compilation test to find the header *locale.h*.
  177. """
  178. conf.find_msgfmt()
  179. conf.find_intltool_merge()
  180. if conf.env.CC or conf.env.CXX:
  181. conf.check(header_name='locale.h')