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 USE_ASH = False
     33 ENABLE_AUTOFILL_DIALOG = False
     34 
     35 WHITELIST = None
     36 
     37 # Extra input files.
     38 EXTRA_INPUT_FILES = []
     39 
     40 class Usage(Exception):
     41   def __init__(self, msg):
     42     self.msg = msg
     43 
     44 
     45 def calc_output(locale):
     46   """Determine the file that will be generated for the given locale."""
     47   #e.g. '<(INTERMEDIATE_DIR)/repack/da.pak',
     48   # For Fake Bidi, generate it at a fixed path so that tests can safely
     49   # reference it.
     50   if locale == 'fake-bidi':
     51     return '%s/%s.pak' % (INT_DIR, locale)
     52   if OS == 'mac' or OS == 'ios':
     53     # For Cocoa to find the locale at runtime, it needs to use '_' instead
     54     # of '-' (http://crbug.com/20441).  Also, 'en-US' should be represented
     55     # simply as 'en' (http://crbug.com/19165, http://crbug.com/25578).
     56     if locale == 'en-US':
     57       locale = 'en'
     58     return '%s/repack/%s.lproj/locale.pak' % (INT_DIR, locale.replace('-', '_'))
     59   else:
     60     return os.path.join(INT_DIR, 'repack', locale + '.pak')
     61 
     62 
     63 def calc_inputs(locale):
     64   """Determine the files that need processing for the given locale."""
     65   inputs = []
     66 
     67   #e.g. '<(grit_out_dir)/generated_resources_da.pak'
     68   inputs.append(os.path.join(GRIT_DIR, 'generated_resources_%s.pak' % locale))
     69 
     70   #e.g. '<(grit_out_dir)/locale_settings_da.pak'
     71   inputs.append(os.path.join(GRIT_DIR, 'locale_settings_%s.pak' % locale))
     72 
     73   #e.g. '<(grit_out_dir)/platform_locale_settings_da.pak'
     74   inputs.append(os.path.join(GRIT_DIR,
     75                 'platform_locale_settings_%s.pak' % locale))
     76 
     77   #e.g. '<(SHARED_INTERMEDIATE_DIR)/components/strings/
     78   # components_strings_da.pak',
     79   inputs.append(os.path.join(SHARE_INT_DIR, 'components', 'strings',
     80                 'components_strings_%s.pak' % locale))
     81 
     82   if USE_ASH:
     83     #e.g. '<(SHARED_INTERMEDIATE_DIR)/ash/strings/ash_strings_da.pak',
     84     inputs.append(os.path.join(SHARE_INT_DIR, 'ash', 'strings',
     85                   'ash_strings_%s.pak' % locale))
     86 
     87   if OS != 'ios':
     88     #e.g. '<(SHARED_INTERMEDIATE_DIR)/webkit/webkit_strings_da.pak'
     89     inputs.append(os.path.join(SHARE_INT_DIR, 'webkit',
     90                   'webkit_strings_%s.pak' % locale))
     91 
     92     #e.g. '<(SHARED_INTERMEDIATE_DIR)/ui/ui_strings_da.pak',
     93     inputs.append(os.path.join(SHARE_INT_DIR, 'ui', 'ui_strings',
     94                   'ui_strings_%s.pak' % locale))
     95 
     96     #e.g. '<(SHARED_INTERMEDIATE_DIR)/device/bluetooth/strings/
     97     # device_bluetooth_strings_da.pak',
     98     inputs.append(os.path.join(SHARE_INT_DIR, 'device', 'bluetooth', 'strings',
     99                   'device_bluetooth_strings_%s.pak' % locale))
    100 
    101     #e.g. '<(SHARED_INTERMEDIATE_DIR)/ui/app_locale_settings_da.pak',
    102     inputs.append(os.path.join(SHARE_INT_DIR, 'ui', 'app_locale_settings',
    103                   'app_locale_settings_%s.pak' % locale))
    104 
    105     # For example:
    106     # '<(SHARED_INTERMEDIATE_DIR)/extensions/strings/extensions_strings_da.pak
    107     # TODO(jamescook): When Android stops building extensions code move this
    108     # to the OS != 'ios' and OS != 'android' section below.
    109     inputs.append(os.path.join(SHARE_INT_DIR, 'extensions', 'strings',
    110                   'extensions_strings_%s.pak' % locale))
    111 
    112   if ENABLE_AUTOFILL_DIALOG and OS != 'ios' and OS != 'android':
    113     #e.g. '<(SHARED_INTERMEDIATE_DIR)/third_party/libaddressinput/
    114     # libaddressinput_strings_da.pak',
    115     inputs.append(os.path.join(SHARE_INT_DIR, 'third_party', 'libaddressinput',
    116                                'libaddressinput_strings_%s.pak' % locale))
    117 
    118     #e.g. '<(SHARED_INTERMEDIATE_DIR)/grit/libaddressinput/
    119     # address_input_strings_da.pak',
    120     inputs.append(os.path.join(SHARE_INT_DIR, 'grit', 'libaddressinput',
    121                                'address_input_strings_%s.pak' % locale))
    122 
    123   #e.g. '<(grit_out_dir)/google_chrome_strings_da.pak'
    124   #     or
    125   #     '<(grit_out_dir)/chromium_strings_da.pak'
    126   inputs.append(os.path.join(
    127       GRIT_DIR, '%s_strings_%s.pak' % (BRANDING, locale)))
    128 
    129   # Add any extra input files.
    130   for extra_file in EXTRA_INPUT_FILES:
    131     inputs.append('%s_%s.pak' % (extra_file, locale))
    132 
    133   return inputs
    134 
    135 
    136 def list_outputs(locales):
    137   """Returns the names of files that will be generated for the given locales.
    138 
    139   This is to provide gyp the list of output files, so build targets can
    140   properly track what needs to be built.
    141   """
    142   outputs = []
    143   for locale in locales:
    144     outputs.append(calc_output(locale))
    145   # Quote each element so filename spaces don't mess up gyp's attempt to parse
    146   # it into a list.
    147   return " ".join(['"%s"' % x for x in outputs])
    148 
    149 
    150 def list_inputs(locales):
    151   """Returns the names of files that will be processed for the given locales.
    152 
    153   This is to provide gyp the list of input files, so build targets can properly
    154   track their prerequisites.
    155   """
    156   inputs = []
    157   for locale in locales:
    158     inputs += calc_inputs(locale)
    159   # Quote each element so filename spaces don't mess up gyp's attempt to parse
    160   # it into a list.
    161   return " ".join(['"%s"' % x for x in inputs])
    162 
    163 
    164 def repack_locales(locales):
    165   """ Loop over and repack the given locales."""
    166   for locale in locales:
    167     inputs = []
    168     inputs += calc_inputs(locale)
    169     output = calc_output(locale)
    170     data_pack.DataPack.RePack(output, inputs, whitelist_file=WHITELIST)
    171 
    172 
    173 def DoMain(argv):
    174   global BRANDING
    175   global GRIT_DIR
    176   global SHARE_INT_DIR
    177   global INT_DIR
    178   global OS
    179   global USE_ASH
    180   global WHITELIST
    181   global ENABLE_AUTOFILL_DIALOG
    182   global EXTRA_INPUT_FILES
    183 
    184   parser = optparse.OptionParser("usage: %prog [options] locales")
    185   parser.add_option("-i", action="store_true", dest="inputs", default=False,
    186                     help="Print the expected input file list, then exit.")
    187   parser.add_option("-o", action="store_true", dest="outputs", default=False,
    188                     help="Print the expected output file list, then exit.")
    189   parser.add_option("-g", action="store", dest="grit_dir",
    190                     help="GRIT build files output directory.")
    191   parser.add_option("-x", action="store", dest="int_dir",
    192                     help="Intermediate build files output directory.")
    193   parser.add_option("-s", action="store", dest="share_int_dir",
    194                     help="Shared intermediate build files output directory.")
    195   parser.add_option("-b", action="store", dest="branding",
    196                     help="Branding type of this build.")
    197   parser.add_option("-e", action="append", dest="extra_input", default=[],
    198                     help="Full path to an extra input pak file without the\
    199                          locale suffix and \".pak\" extension.")
    200   parser.add_option("-p", action="store", dest="os",
    201                     help="The target OS. (e.g. mac, linux, win, etc.)")
    202   parser.add_option("--use-ash", action="store", dest="use_ash",
    203                     help="Whether to include ash strings")
    204   parser.add_option("--whitelist", action="store", help="Full path to the "
    205                     "whitelist used to filter output pak file resource IDs")
    206   parser.add_option("--enable-autofill-dialog", action="store",
    207                     dest="enable_autofill_dialog",
    208                     help="Whether to include strings for autofill dialog")
    209   options, locales = parser.parse_args(argv)
    210 
    211   if not locales:
    212     parser.error('Please specificy at least one locale to process.\n')
    213 
    214   print_inputs = options.inputs
    215   print_outputs = options.outputs
    216   GRIT_DIR = options.grit_dir
    217   INT_DIR = options.int_dir
    218   SHARE_INT_DIR = options.share_int_dir
    219   BRANDING = options.branding
    220   EXTRA_INPUT_FILES = options.extra_input
    221   OS = options.os
    222   USE_ASH = options.use_ash == '1'
    223   WHITELIST = options.whitelist
    224   ENABLE_AUTOFILL_DIALOG = options.enable_autofill_dialog == '1'
    225 
    226   if not OS:
    227     if sys.platform == 'darwin':
    228       OS = 'mac'
    229     elif sys.platform.startswith('linux'):
    230       OS = 'linux'
    231     elif sys.platform in ('cygwin', 'win32'):
    232       OS = 'win'
    233     else:
    234       OS = sys.platform
    235 
    236   if not (GRIT_DIR and INT_DIR and SHARE_INT_DIR):
    237     parser.error('Please specify all of "-g" and "-x" and "-s".\n')
    238   if print_inputs and print_outputs:
    239     parser.error('Please specify only one of "-i" or "-o".\n')
    240   # Need to know the branding, unless we're just listing the outputs.
    241   if not print_outputs and not BRANDING:
    242     parser.error('Please specify "-b" to determine the input files.\n')
    243 
    244   if print_inputs:
    245     return list_inputs(locales)
    246 
    247   if print_outputs:
    248     return list_outputs(locales)
    249 
    250   return repack_locales(locales)
    251 
    252 if __name__ == '__main__':
    253   results = DoMain(sys.argv[1:])
    254   if results:
    255     print results
    256