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