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 8Gyp doesn't have any built-in looping capability, so this just provides a way to 9loop over a list of locales when repacking pak files, thus avoiding a 10proliferation of mostly duplicate, cut-n-paste gyp actions. 11""" 12 13import optparse 14import os 15import sys 16 17sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', 18 'tools', 'grit')) 19from grit.format import data_pack 20 21# The gyp "branding" variable. 22BRANDING = None 23 24# Some build paths defined by gyp. 25GRIT_DIR = None 26SHARE_INT_DIR = None 27INT_DIR = None 28 29# The target platform. If it is not defined, sys.platform will be used. 30OS = None 31 32# Note that OS is normally set to 'linux' when building for chromeos. 33CHROMEOS = False 34 35USE_ASH = False 36USE_ATHENA = False 37ENABLE_AUTOFILL_DIALOG = False 38ENABLE_EXTENSIONS = False 39 40WHITELIST = None 41 42# Extra input files. 43EXTRA_INPUT_FILES = [] 44 45class Usage(Exception): 46 def __init__(self, msg): 47 self.msg = msg 48 49 50def 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 68def 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 147def 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 161def 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 175def 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 184def 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 276if __name__ == '__main__': 277 results = DoMain(sys.argv[1:]) 278 if results: 279 print results 280