Home | History | Annotate | Download | only in build
      1 #!/usr/bin/env python
      2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 """Helper script to repack paks for a list of locales.
      7 
      8 Gyp doesn't have any built-in looping capability, so this just provides a way to
      9 loop over a list of locales when repacking pak files, thus avoiding a
     10 proliferation of mostly duplicate, cut-n-paste gyp actions.
     11 """
     12 
     13 import optparse
     14 import os
     15 import sys
     16 
     17 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..',
     18                              'tools', 'grit'))
     19 from grit.format import data_pack
     20 
     21 # The gyp "branding" variable.
     22 BRANDING = None
     23 
     24 # Some build paths defined by gyp.
     25 GRIT_DIR = None
     26 SHARE_INT_DIR = None
     27 INT_DIR = None
     28 
     29 # The target platform. If it is not defined, sys.platform will be used.
     30 OS = None
     31 
     32 # Note that OS is normally set to 'linux' when building for chromeos.
     33 CHROMEOS = False
     34 
     35 USE_ASH = False
     36 USE_ATHENA = False
     37 ENABLE_AUTOFILL_DIALOG = False
     38 ENABLE_EXTENSIONS = False
     39 
     40 WHITELIST = None
     41 
     42 # Extra input files.
     43 EXTRA_INPUT_FILES = []
     44 
     45 class Usage(Exception):
     46   def __init__(self, msg):
     47     self.msg = msg
     48 
     49 
     50 def calc_output(locale):
     51   """Determine the file that will be generated for the given locale."""
     52   #e.g. '<(INTERMEDIATE_DIR)/repack/da.pak',
     53   # For Fake Bidi, generate it at a fixed path so that tests can safely
     54   # reference it.
     55   if locale == 'fake-bidi':
     56     return '%s/%s.pak' % (INT_DIR, locale)
     57   if OS == 'mac' or OS == 'ios':
     58     # For Cocoa to find the locale at runtime, it needs to use '_' instead
     59     # of '-' (http://crbug.com/20441).  Also, 'en-US' should be represented
     60     # simply as 'en' (http://crbug.com/19165, http://crbug.com/25578).
     61     if locale == 'en-US':
     62       locale = 'en'
     63     return '%s/repack/%s.lproj/locale.pak' % (INT_DIR, locale.replace('-', '_'))
     64   else:
     65     return os.path.join(INT_DIR, 'repack', locale + '.pak')
     66 
     67 
     68 def calc_inputs(locale):
     69   """Determine the files that need processing for the given locale."""
     70   inputs = []
     71 
     72   #e.g. '<(grit_out_dir)/generated_resources_da.pak'
     73   inputs.append(os.path.join(GRIT_DIR, 'generated_resources_%s.pak' % locale))
     74 
     75   #e.g. '<(grit_out_dir)/locale_settings_da.pak'
     76   inputs.append(os.path.join(GRIT_DIR, 'locale_settings_%s.pak' % locale))
     77 
     78   #e.g. '<(grit_out_dir)/platform_locale_settings_da.pak'
     79   inputs.append(os.path.join(GRIT_DIR,
     80                 'platform_locale_settings_%s.pak' % locale))
     81 
     82   #e.g. '<(SHARED_INTERMEDIATE_DIR)/components/strings/
     83   # components_strings_da.pak',
     84   inputs.append(os.path.join(SHARE_INT_DIR, 'components', 'strings',
     85                 'components_strings_%s.pak' % locale))
     86 
     87   if USE_ASH:
     88     #e.g. '<(SHARED_INTERMEDIATE_DIR)/ash/strings/ash_strings_da.pak',
     89     inputs.append(os.path.join(SHARE_INT_DIR, 'ash', 'strings',
     90                   'ash_strings_%s.pak' % locale))
     91 
     92   if USE_ATHENA:
     93     #e.g. '<(SHARED_INTERMEDIATE_DIR)/athena/strings/athena_strings_da.pak',
     94     inputs.append(os.path.join(SHARE_INT_DIR, 'athena', 'strings',
     95                   'athena_strings_%s.pak' % locale))
     96 
     97   if CHROMEOS:
     98     inputs.append(os.path.join(SHARE_INT_DIR, 'ui', 'chromeos', 'strings',
     99                   'ui_chromeos_strings_%s.pak' % locale))
    100 
    101   if OS != 'ios':
    102     #e.g.
    103     # '<(SHARED_INTERMEDIATE_DIR)/content/app/strings/content_strings_da.pak'
    104     inputs.append(os.path.join(SHARE_INT_DIR, 'content', 'app', 'strings',
    105                   'content_strings_%s.pak' % locale))
    106 
    107     #e.g. '<(SHARED_INTERMEDIATE_DIR)/ui/strings/ui_strings_da.pak',
    108     inputs.append(os.path.join(SHARE_INT_DIR, 'ui', 'strings',
    109                   'ui_strings_%s.pak' % locale))
    110 
    111     #e.g. '<(SHARED_INTERMEDIATE_DIR)/ui/strings/app_locale_settings_da.pak',
    112     inputs.append(os.path.join(SHARE_INT_DIR, 'ui', 'strings',
    113                   'app_locale_settings_%s.pak' % locale))
    114 
    115   if ENABLE_AUTOFILL_DIALOG and OS != 'ios' and OS != 'android':
    116     #e.g. '<(SHARED_INTERMEDIATE_DIR)/third_party/libaddressinput/
    117     # address_input_strings_da.pak',
    118     inputs.append(os.path.join(SHARE_INT_DIR, 'third_party', 'libaddressinput',
    119                                'address_input_strings_%s.pak' % locale))
    120 
    121   if ENABLE_EXTENSIONS:
    122     #e.g. '<(SHARED_INTERMEDIATE_DIR)/device/bluetooth/strings/
    123     # device_bluetooth_strings_da.pak',
    124     inputs.append(os.path.join(SHARE_INT_DIR, 'device', 'bluetooth', 'strings',
    125                   'device_bluetooth_strings_%s.pak' % locale))
    126 
    127     # For example:
    128     # '<(SHARED_INTERMEDIATE_DIR)/extensions/strings/extensions_strings_da.pak
    129     # TODO(jamescook): When Android stops building extensions code move this
    130     # to the OS != 'ios' and OS != 'android' section below.
    131     inputs.append(os.path.join(SHARE_INT_DIR, 'extensions', 'strings',
    132                   'extensions_strings_%s.pak' % locale))
    133 
    134   #e.g. '<(grit_out_dir)/google_chrome_strings_da.pak'
    135   #     or
    136   #     '<(grit_out_dir)/chromium_strings_da.pak'
    137   inputs.append(os.path.join(
    138       GRIT_DIR, '%s_strings_%s.pak' % (BRANDING, locale)))
    139 
    140   # Add any extra input files.
    141   for extra_file in EXTRA_INPUT_FILES:
    142     inputs.append('%s_%s.pak' % (extra_file, locale))
    143 
    144   return inputs
    145 
    146 
    147 def list_outputs(locales):
    148   """Returns the names of files that will be generated for the given locales.
    149 
    150   This is to provide gyp the list of output files, so build targets can
    151   properly track what needs to be built.
    152   """
    153   outputs = []
    154   for locale in locales:
    155     outputs.append(calc_output(locale))
    156   # Quote each element so filename spaces don't mess up gyp's attempt to parse
    157   # it into a list.
    158   return " ".join(['"%s"' % x for x in outputs])
    159 
    160 
    161 def list_inputs(locales):
    162   """Returns the names of files that will be processed for the given locales.
    163 
    164   This is to provide gyp the list of input files, so build targets can properly
    165   track their prerequisites.
    166   """
    167   inputs = []
    168   for locale in locales:
    169     inputs += calc_inputs(locale)
    170   # Quote each element so filename spaces don't mess up gyp's attempt to parse
    171   # it into a list.
    172   return " ".join(['"%s"' % x for x in inputs])
    173 
    174 
    175 def repack_locales(locales):
    176   """ Loop over and repack the given locales."""
    177   for locale in locales:
    178     inputs = []
    179     inputs += calc_inputs(locale)
    180     output = calc_output(locale)
    181     data_pack.DataPack.RePack(output, inputs, whitelist_file=WHITELIST)
    182 
    183 
    184 def DoMain(argv):
    185   global BRANDING
    186   global GRIT_DIR
    187   global SHARE_INT_DIR
    188   global INT_DIR
    189   global OS
    190   global CHROMEOS
    191   global USE_ASH
    192   global USE_ATHENA
    193   global WHITELIST
    194   global ENABLE_AUTOFILL_DIALOG
    195   global ENABLE_EXTENSIONS
    196   global EXTRA_INPUT_FILES
    197 
    198   parser = optparse.OptionParser("usage: %prog [options] locales")
    199   parser.add_option("-i", action="store_true", dest="inputs", default=False,
    200                     help="Print the expected input file list, then exit.")
    201   parser.add_option("-o", action="store_true", dest="outputs", default=False,
    202                     help="Print the expected output file list, then exit.")
    203   parser.add_option("-g", action="store", dest="grit_dir",
    204                     help="GRIT build files output directory.")
    205   parser.add_option("-x", action="store", dest="int_dir",
    206                     help="Intermediate build files output directory.")
    207   parser.add_option("-s", action="store", dest="share_int_dir",
    208                     help="Shared intermediate build files output directory.")
    209   parser.add_option("-b", action="store", dest="branding",
    210                     help="Branding type of this build.")
    211   parser.add_option("-e", action="append", dest="extra_input", default=[],
    212                     help="Full path to an extra input pak file without the\
    213                          locale suffix and \".pak\" extension.")
    214   parser.add_option("-p", action="store", dest="os",
    215                     help="The target OS. (e.g. mac, linux, win, etc.)")
    216   parser.add_option("--use-ash", action="store", dest="use_ash",
    217                     help="Whether to include ash strings")
    218   parser.add_option("--use-athena", action="store", dest="use_athena",
    219                     help="Whether to include athena strings")
    220   parser.add_option("--chromeos", action="store",
    221                     help="Whether building for Chrome OS")
    222   parser.add_option("--whitelist", action="store", help="Full path to the "
    223                     "whitelist used to filter output pak file resource IDs")
    224   parser.add_option("--enable-autofill-dialog", action="store",
    225                     dest="enable_autofill_dialog",
    226                     help="Whether to include strings for autofill dialog")
    227   parser.add_option("--enable-extensions", action="store",
    228                     dest="enable_extensions",
    229                     help="Whether to include strings for extensions")
    230   options, locales = parser.parse_args(argv)
    231 
    232   if not locales:
    233     parser.error('Please specificy at least one locale to process.\n')
    234 
    235   print_inputs = options.inputs
    236   print_outputs = options.outputs
    237   GRIT_DIR = options.grit_dir
    238   INT_DIR = options.int_dir
    239   SHARE_INT_DIR = options.share_int_dir
    240   BRANDING = options.branding
    241   EXTRA_INPUT_FILES = options.extra_input
    242   OS = options.os
    243   CHROMEOS = options.chromeos == '1'
    244   USE_ASH = options.use_ash == '1'
    245   USE_ATHENA = options.use_athena == '1'
    246   WHITELIST = options.whitelist
    247   ENABLE_AUTOFILL_DIALOG = options.enable_autofill_dialog == '1'
    248   ENABLE_EXTENSIONS = options.enable_extensions == '1'
    249 
    250   if not OS:
    251     if sys.platform == 'darwin':
    252       OS = 'mac'
    253     elif sys.platform.startswith('linux'):
    254       OS = 'linux'
    255     elif sys.platform in ('cygwin', 'win32'):
    256       OS = 'win'
    257     else:
    258       OS = sys.platform
    259 
    260   if not (GRIT_DIR and INT_DIR and SHARE_INT_DIR):
    261     parser.error('Please specify all of "-g" and "-x" and "-s".\n')
    262   if print_inputs and print_outputs:
    263     parser.error('Please specify only one of "-i" or "-o".\n')
    264   # Need to know the branding, unless we're just listing the outputs.
    265   if not print_outputs and not BRANDING:
    266     parser.error('Please specify "-b" to determine the input files.\n')
    267 
    268   if print_inputs:
    269     return list_inputs(locales)
    270 
    271   if print_outputs:
    272     return list_outputs(locales)
    273 
    274   return repack_locales(locales)
    275 
    276 if __name__ == '__main__':
    277   results = DoMain(sys.argv[1:])
    278   if results:
    279     print results
    280