| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2008 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import fnmatch | |
| 6 import os | |
| 7 import re | |
| 8 import shutil | |
| 9 import subprocess | |
| 10 import utils | |
| 11 import SCons.Node | |
| 12 | |
| 13 Import('env') | |
| 14 | |
| 15 env = env.Clone() | |
| 16 | |
| 17 if env['OS'] in ['win32', 'wince']: | |
| 18 env.Append(DATE = 'echo %DATE%.%TIME%') | |
| 19 else: | |
| 20 env.Append(DATE = 'date') | |
| 21 | |
| 22 def GetInputs(var): return utils.GetInputs(var, env) | |
| 23 | |
| 24 def Shell(cmd): | |
| 25 """Execute a shell command and return the output.""" | |
| 26 cmd[0] = env.Entry(cmd[0]).abspath | |
| 27 cmd = env.subst(cmd) | |
| 28 return subprocess.Popen( | |
| 29 cmd, shell=True, stdout=subprocess.PIPE).communicate()[0] | |
| 30 | |
| 31 if env['OS'] == 'win32': | |
| 32 def GGUIDGen(value): | |
| 33 """Generate a GGUID for the given value.""" | |
| 34 return Shell(['$GGUIDGEN', '$NAMESPACE_GUID', value + '-$VERSION']) | |
| 35 env.Replace( | |
| 36 GGUIDGEN = '#/$OPEN_DIR/tools/gguidgen.exe', | |
| 37 NAMESPACE_GUID = '36F65206-5D4E-4752-9D52-27708E10DA79', | |
| 38 # MSI version numbers must have the form <major>.<minor>.<build>. To meet this, | |
| 39 # we combine our build and patch version numbers like so: | |
| 40 # MSI_VERSION = <major>.<minor>.<BUILD * 100 + PATCH>. | |
| 41 # Note: This assumes that the BUILD and PATCH variables adhere to the range | |
| 42 # requirements in version.mk. See comments in version.mk for more details. | |
| 43 MSI_BUILD = eval(env.subst('$BUILD * 100 + $PATCH')), | |
| 44 MSI_VERSION = '${MAJOR}.${MINOR}.${MSI_BUILD}', | |
| 45 ) | |
| 46 | |
| 47 # Building wxiobjs with candle | |
| 48 env.Replace( | |
| 49 CANDLEDEFPREFIX = '-d', | |
| 50 CANDLEDEFSUFFIX = '', | |
| 51 _CANDLEDEFFLAGS = ('${_defines(CANDLEDEFPREFIX, CANDLEDEFINES, ' | |
| 52 'CANDLEDEFSUFFIX, __env__)}'), | |
| 53 CANDLECOM = 'candle.exe -out $TARGET $SOURCE ${_CANDLEDEFFLAGS}', | |
| 54 ) | |
| 55 env.Append( | |
| 56 # Note: Since light.exe is run from $OPEN_DIR, candle.exe must generate | |
| 57 # output with paths relative to that dir. | |
| 58 SCONS_DIR = '..', # the scons dir relative to OPEN_DIR | |
| 59 # You can change the names of ProductId vars, but NEVER change their values! | |
| 60 CANDLEDEFINES = [ | |
| 61 ('OurWin32ProductId', | |
| 62 GGUIDGen('OUR_PRODUCT_ID')), | |
| 63 ('OurComponentGUID_FFComponentsDirFiles', | |
| 64 GGUIDGen('OUR_COMPONENT_GUID_FF_COMPONENTS_DIR_FILES')), | |
| 65 ('OurComponentGUID_FFContentDirFiles', | |
| 66 GGUIDGen('OUR_COMPONENT_GUID_FF_CONTENT_DIR_FILES')), | |
| 67 ('OurComponentGUID_FFDirFiles', | |
| 68 GGUIDGen('OUR_COMPONENT_GUID_FF_DIR_FILES')), | |
| 69 ('OurComponentGUID_FFLibDirFiles', | |
| 70 GGUIDGen('OUR_COMPONENT_GUID_FF_LIB_DIR_FILES')), | |
| 71 ('OurComponentGUID_FFRegistry', | |
| 72 GGUIDGen('OUR_COMPONENT_GUID_FF_REGISTRY')), | |
| 73 ('OurComponentGUID_IEFiles', | |
| 74 GGUIDGen('OUR_COMPONENT_GUID_IE_FILES')), | |
| 75 ('OurComponentGUID_IERegistry', | |
| 76 GGUIDGen('OUR_COMPONENT_GUID_IE_REGISTRY')), | |
| 77 ('OurComponentGUID_SharedFiles', | |
| 78 GGUIDGen('OUR_COMPONENT_GUID_SHARED_FILES')), | |
| 79 ('OurComponentGUID_SharedVersionedFiles', | |
| 80 GGUIDGen('OUR_COMPONENT_GUID_SHARED_VERSIONED_FILES')), | |
| 81 ('OurComponentGUID_SharedRegistry', | |
| 82 GGUIDGen('OUR_COMPONENT_GUID_SHARED_REGISTRY')), | |
| 83 ('OurNpapiProductId', | |
| 84 GGUIDGen('OUR_2ND_PRODUCT_ID')), | |
| 85 ('OurComponentGUID_NpapiFiles', | |
| 86 GGUIDGen('OUR_COMPONENT_GUID_NPAPI_FILES')), | |
| 87 ('OurComponentGUID_NpapiRegistry', | |
| 88 GGUIDGen('OUR_COMPONENT_GUID_NPAPI_REGISTRY')), | |
| 89 ('OurMsiVersion', '$MSI_VERSION'), | |
| 90 ('OurCommonPath', '$COMMON_OUTDIR'), | |
| 91 ('OurIEPath', '$IE_OUTDIR'), | |
| 92 ('OurIpcTestPath', '$COMMON_OUTDIR'), | |
| 93 ('OurFFPath', '$INSTALLER_OUTDIR/$INSTALLER_BASENAME'), | |
| 94 ('OurNpapiPath', '$NPAPI_OUTDIR'), | |
| 95 ] | |
| 96 ) | |
| 97 wix_langs = [re.sub('-', '_', lang) for lang in env['I18N_LANGS']] | |
| 98 env.Append( | |
| 99 CANDLEDEFINES = | |
| 100 [('OurComponentGUID_FFLang' + lang + 'DirFiles', | |
| 101 GGUIDGen('OUR_COMPONENT_GUID_FF_' + lang + '_DIR_FILES')) | |
| 102 for lang in wix_langs], | |
| 103 ) | |
| 104 | |
| 105 def SafeMkdir(dir): | |
| 106 """Like the builtin Mkdir, but doesn't fail if the dir exists.""" | |
| 107 def Func(target, source, env): | |
| 108 dir_subst = env.subst(dir, target=target) | |
| 109 if not os.path.exists(dir_subst): | |
| 110 os.makedirs(dir_subst) | |
| 111 return 0 | |
| 112 return Action(Func, 'SafeMkdir("' + dir + '")') | |
| 113 | |
| 114 def RecursiveDelete(pattern): | |
| 115 """Recursively deletes directories matching a pattern.""" | |
| 116 def Func(target, source, env): | |
| 117 # strip off '.dir' suffix | |
| 118 target_dir = env.subst('${TARGET.base}', target=target) | |
| 119 for root, dirs, files in os.walk(target_dir): | |
| 120 if fnmatch.fnmatch(os.path.normpath(root), pattern): | |
| 121 print 'Deleting', root | |
| 122 shutil.rmtree(root) | |
| 123 return 0 | |
| 124 return Action(Func, 'RecursiveDelete("' + pattern + '")') | |
| 125 | |
| 126 def ToUnixPath(path): | |
| 127 """Converts windows-style \ to unix-style /.""" | |
| 128 return re.sub(r'\\', r'/', path) | |
| 129 | |
| 130 def DirBuilder(env, dirtarget, dirsrcs): | |
| 131 """Builder that makes a directory tree by copying source files to | |
| 132 corresponding locations inside 'dirtarget'. 'dirsrcs' specifies the list of | |
| 133 mappings from source file/directory to the target location. It's formatted | |
| 134 like: | |
| 135 (<target file or dir>, <list of source files>) | |
| 136 | |
| 137 Note: source files that come from an output directory must be explicitly | |
| 138 specified relative to the toplevel dir '#'. | |
| 139 Note: as shorthand, if the target ends with a '/', then the sources will | |
| 140 be placed into that dir. Otherwise, source is renamed into the target. | |
| 141 """ | |
| 142 | |
| 143 srcs = [] | |
| 144 actions = [Delete('${TARGET.base}')] | |
| 145 for target, sources in dirsrcs: | |
| 146 target_is_dir = target.endswith('/') | |
| 147 if target_is_dir: | |
| 148 actions.append(SafeMkdir('${TARGET.base}/' + target)) | |
| 149 else: | |
| 150 actions.append(SafeMkdir('${TARGET.base}/' + os.path.dirname(target))) | |
| 151 for source in env.Flatten(sources): | |
| 152 source = env.subst(source, conv=lambda x:x) | |
| 153 srcs.append(source) | |
| 154 | |
| 155 # Special-case for Nodes and Node lists: use their absolute paths for | |
| 156 # the Copy() action, otherwise it will be relative to our variant dir | |
| 157 # (not what Copy expects). | |
| 158 if isinstance(source, list): source = source[0] | |
| 159 if isinstance(source, SCons.Node.Node): source = source.abspath | |
| 160 | |
| 161 # HACK: Compensate for the workaround below. We want the .dir file | |
| 162 # to be the dependency to the Command() builder, but we want to copy | |
| 163 # the actual directory - so strip the extension here. | |
| 164 if source.endswith('.dir'): | |
| 165 source = source[:-4] | |
| 166 | |
| 167 if target_is_dir: | |
| 168 actions.append( | |
| 169 Copy('${TARGET.base}/' + target + os.path.basename(source), | |
| 170 source)) | |
| 171 else: | |
| 172 actions.append(Copy('${TARGET.base}/' + target, source)) | |
| 173 | |
| 174 # Remove any .svn directories that were copied. | |
| 175 actions.append(RecursiveDelete('*/.svn')) | |
| 176 | |
| 177 # HACK: Workaround for bug in scons where directories aren't checked for | |
| 178 # dependency changes. Instead, we make a temp file the target, and ensure | |
| 179 # that that file changes everytime we execute these actions. | |
| 180 # See http://scons.tigris.org/issues/show_bug.cgi?id=2261 | |
| 181 actions += ['$DATE > ${TARGET}'] | |
| 182 return env.Command(env.subst(dirtarget) + '.dir', srcs, actions) | |
| 183 env.AddMethod(DirBuilder) | |
| 184 | |
| 185 def FirefoxInstaller(): | |
| 186 dirsrcs = [ | |
| 187 ('/', ['$FF3_OUTDIR/genfiles/install.rdf', | |
| 188 '$FF3_OUTDIR/genfiles/chrome.manifest']), | |
| 189 ('lib/', ['$OPEN_DIR/base/firefox/static_files/lib/updater.js']), | |
| 190 ('chrome/chromeFiles/content/', | |
| 191 GetInputs('$FF3_RESOURCES $COMMON_RESOURCES')), | |
| 192 ('chrome/chromeFiles/locale', ['$FF3_OUTDIR/genfiles/i18n']), | |
| 193 ('components/', | |
| 194 ['$FF3_MODULE_TYPELIB', | |
| 195 '$OPEN_DIR/base/firefox/static_files/components/bootstrap.js']), | |
| 196 ('components/${SHLIBPREFIX}gears${SHLIBSUFFIX}', ['$FF2_MODULE']), | |
| 197 ('components/${SHLIBPREFIX}gears_ff2${SHLIBSUFFIX}', ['$FF3_MODULE']), | |
| 198 ] | |
| 199 | |
| 200 if env['USING_CCTESTS']: | |
| 201 dirsrcs += [ | |
| 202 ('components/', ['$IPC_TEST_EXE']), | |
| 203 ] | |
| 204 if env['OS'] != 'win32': | |
| 205 # TODO(playmobil): Inspector should be located in extensions dir on win32. | |
| 206 dirsrcs += [ | |
| 207 ('resources/inspector', [env.Dir('#/$OPEN_DIR/inspector')]), | |
| 208 ('resources/inspector/common/', ['$OPEN_DIR/sdk/gears_init.js', | |
| 209 '$OPEN_DIR/sdk/samples/sample.js']), | |
| 210 ] | |
| 211 if env['MODE'] == 'dbg' and env['OS'] in ['win32', 'wince']: | |
| 212 dirsrcs += [ | |
| 213 ('components/gears_ff2.pdb', ['$FF2_MODULE_PDB']), | |
| 214 ('components/gears.pdb', ['$FF3_MODULE_PDB']), | |
| 215 ] | |
| 216 if env['OS'] == 'osx': | |
| 217 dirsrcs += [ | |
| 218 ('resources/', ['$OSX_LAUNCHURL_EXE']), | |
| 219 ] | |
| 220 | |
| 221 dir = env.DirBuilder('$INSTALLER_OUTDIR/$INSTALLER_BASENAME', dirsrcs) | |
| 222 actions = [ | |
| 223 # Mark files writeable to allow .xpi rebuilds | |
| 224 'chmod -R 777 ${SOURCE.base}', | |
| 225 '(cd ${SOURCE.base} && zip -r ../${TARGET.file} .)' | |
| 226 ] | |
| 227 | |
| 228 return env.Command('$FF_XPI', dir, actions) | |
| 229 firefox_installer = FirefoxInstaller() | |
| 230 | |
| 231 def Win32Installer(): | |
| 232 wxiobj = env.Command( | |
| 233 '$COMMON_GENFILES_DIR/win32_msi.wxiobj', | |
| 234 '$COMMON_GENFILES_DIR/win32_msi.wxs', | |
| 235 '$CANDLECOM') | |
| 236 # TODO(mpcomplete): remove this if/when the notifier goes away. This | |
| 237 # creates fake targets to satisfy the installer build. | |
| 238 notifier = env.Command( | |
| 239 [ | |
| 240 '$COMMON_OUTDIR/notifier.exe', | |
| 241 '$COMMON_OUTDIR/notifier.dll', | |
| 242 '$COMMON_OUTDIR/notifier_test.exe' | |
| 243 ], [], | |
| 244 'touch $TARGETS') | |
| 245 # light.exe must be run from $OPEN_DIR | |
| 246 msi = env.Command( | |
| 247 '$WIN32_INSTALLER_MSI', | |
| 248 [wxiobj, notifier, firefox_installer, '$IE_MODULE', '$NPAPI_MODULE'], | |
| 249 'cd $OPEN_DIR && light.exe -out ${TARGET.abspath} ${SOURCES[0].abspath}') | |
| 250 return msi | |
| 251 win32_installer = Win32Installer() | |
| 252 | |
| 253 def WinCEInstaller(): | |
| 254 env['ToUnixPath'] = ToUnixPath | |
| 255 inf_outdir = ToUnixPath(env.subst('$IE_OUTDIR')) | |
| 256 inf = env.Command( | |
| 257 '$COMMON_GENFILES_DIR/wince_cab_fixed.inf', | |
| 258 '$COMMON_GENFILES_DIR/wince_cab_ie.inf', | |
| 259 'sed -e "s#bin-....wince-arm.ie.#' + inf_outdir + '#g" $SOURCE > $TARGET') | |
| 260 cab = env.Command( | |
| 261 '$WINCE_INSTALLER_CAB', | |
| 262 [inf, '$IE_MODULE', '$IE_WINCE_SETUP_DLL'], | |
| 263 ['cabwiz ${ToUnixPath(str(SOURCE))} /compress' | |
| 264 ' /err ${SOURCES[0].base}.log', | |
| 265 Copy('$TARGET', '${SOURCE.base}.CAB')]) | |
| 266 return cab | |
| 267 wince_installer = WinCEInstaller() | |
| 268 | |
| 269 def SafariPluginBundle(): | |
| 270 """This is the actual gears plugin bundle for Safari.""" | |
| 271 dirsrcs = [ | |
| 272 ('Contents/', ['$SF_OUTDIR/genfiles/Info.plist']), | |
| 273 ('Contents/Resources/English.lproj/InfoPlist.strings', | |
| 274 ['$OPEN_DIR/tools/osx/English.lproj/InfoPlist.strings']), | |
| 275 ('Contents/Resources/', env.Glob('#/$OPEN_DIR/ui/safari/*.nib')), | |
| 276 ('Contents/Resources/', ['$CRASH_SENDER_EXE']), | |
| 277 ('Contents/Resources/', ['$OSX_CRASH_INSPECTOR_EXE']), | |
| 278 ('Contents/Resources/', ['$OSX_LAUNCHURL_EXE']), | |
| 279 ('Contents/MacOS/', ['$SF_MODULE']), | |
| 280 ] | |
| 281 | |
| 282 if env['USING_CCTESTS']: | |
| 283 dirsrcs += [ | |
| 284 ('Contents/Resources/', ['$IPC_TEST_EXE']), | |
| 285 ] | |
| 286 | |
| 287 return env.DirBuilder('$SF_PLUGIN_BUNDLE', dirsrcs) | |
| 288 safari_plugin_bundle = SafariPluginBundle() | |
| 289 | |
| 290 def SafariPluginProxyBundle(): | |
| 291 """This is a proxy plugin which simply loads gears into Safari and keeps | |
| 292 it in memory. It exists so that gears doesn't unload when Safari wants us | |
| 293 to, since that causes crashes.""" | |
| 294 dirsrcs = [ | |
| 295 ('Contents/', ['$SF_OUTDIR/genfiles/Info.plist']), | |
| 296 ('Contents/MacOS/${SHLIBPREFIX}gears${SHLIBSUFFIX}', ['$SF_PROXY_DLL']), | |
| 297 ('Contents/Resources/', [safari_plugin_bundle]), | |
| 298 ('Contents/Resources/', ['$OPEN_DIR/tools/osx/uninstall.command']), | |
| 299 ] | |
| 300 | |
| 301 return env.DirBuilder('$SF_PLUGIN_PROXY_BUNDLE', dirsrcs) | |
| 302 safari_plugin_proxy_bundle = SafariPluginProxyBundle() | |
| 303 | |
| 304 def SafariInstallerPluginBundle(): | |
| 305 dirsrcs = [ | |
| 306 ('Contents/Info.plist', | |
| 307 ['$OPEN_DIR/base/safari/advanced_stats_sheet.plist']), | |
| 308 ('Contents/MacOS/InstallerPlugin', ['$SF_INSTALLER_PLUGIN_EXE']), | |
| 309 ('Contents/Resources/AdvancedStatsSheet.nib', | |
| 310 [env.Dir('#/$OPEN_DIR/base/safari/advanced_stats_sheet.nib')]), | |
| 311 ] | |
| 312 | |
| 313 return env.DirBuilder('$SF_INSTALLER_PLUGIN_BUNDLE', dirsrcs) | |
| 314 safari_installer_plugin_bundle = SafariInstallerPluginBundle() | |
| 315 | |
| 316 def SafariInputManagerBundle(): | |
| 317 info = env.Command('$SF_OUTDIR/genfiles/Enabler-Info.plist', | |
| 318 '$OPEN_DIR/tools/osx/Enabler-Info.plist', | |
| 319 'cat $SOURCE |' | |
| 320 'sed \'s/$${EXECUTABLE_NAME}/GearsEnabler/\' |' | |
| 321 'sed \'s/$${PRODUCT_NAME}/GearsEnabler/\' > $TARGET') | |
| 322 dirsrcs = [ | |
| 323 ('GearsEnabler.bundle/Contents/Info.plist', [info]), | |
| 324 ('GearsEnabler.bundle/Contents/MacOS/', ['$SF_INPUTMANAGER_EXE']), | |
| 325 ('GearsEnabler.bundle/Contents/Resources/English.lproj/', | |
| 326 ['$OPEN_DIR/tools/osx/English.lproj/InfoPlist.strings']), | |
| 327 ('Info', ['$OPEN_DIR/tools/osx/Info']), | |
| 328 ] | |
| 329 | |
| 330 return env.DirBuilder('$SF_INPUTMANAGER_BUNDLE', dirsrcs) | |
| 331 safari_input_manager_bundle = SafariInputManagerBundle() | |
| 332 | |
| 333 def SafariInstallerPackage(): | |
| 334 pkg = env.Iceberg(env.Dir('${SF_INSTALLER_PKG}'), | |
| 335 [ | |
| 336 '$SF_OUTDIR/genfiles/installer.packproj', | |
| 337 safari_plugin_proxy_bundle, | |
| 338 safari_input_manager_bundle, | |
| 339 ]) | |
| 340 return pkg | |
| 341 safari_installer_package = SafariInstallerPackage() | |
| 342 | |
| 343 def SafariKeystoneInstaller(): | |
| 344 if not os.path.exists(env.Dir('#/$PRIVATE_DIR').abspath): | |
| 345 print 'Skipping Safari Keystone installer. Required sources are not public.' | |
| 346 return [] | |
| 347 | |
| 348 env.Append(CREATE_DISK_IMAGE = | |
| 349 "/usr/bin/hdiutil create -ov -imagekey zlib-level=9 -fs HFS+" | |
| 350 " -format UDZO -volname '$FRIENDLY_NAME ${VERSION}'" | |
| 351 " -srcfolder '${INSTALLER_OUTDIR}/Safari/dmg/' -scrub" | |
| 352 " -nocrossdev '${SF_KEYSTONE_INSTALLER_DMG}'" | |
| 353 ) | |
| 354 | |
| 355 pkg = env.Iceberg(env.Dir('${SF_KEYSTONE_INSTALLER_MPKG}'), | |
| 356 ['$SF_OUTDIR/genfiles/keystone_installer.packproj']) | |
| 357 env.Depends(pkg, GetInputs('$SF_M4S')) | |
| 358 env.Depends(pkg, safari_installer_package) | |
| 359 | |
| 360 dirsrcs = [ | |
| 361 ('/', [pkg]), | |
| 362 ('/.keystone_install', | |
| 363 ['$PRIVATE_DIR/tools/osx/installer/keystone_install']), | |
| 364 ] | |
| 365 dmg = env.DirBuilder('$INSTALLER_OUTDIR/Safari/dmg', dirsrcs) | |
| 366 env.AddPostAction(dmg, 'chmod +x ${TARGET.base}/.keystone_install') | |
| 367 # hdiutil is crashy under leopard, so try twice. | |
| 368 env.AddPostAction(dmg, '$CREATE_DISK_IMAGE || $CREATE_DISK_IMAGE') | |
| 369 | |
| 370 return dmg | |
| 371 safari_keystone_installer = SafariKeystoneInstaller() | |
| 372 | |
| 373 installers = [] | |
| 374 if 'FF3' in env['VALID_BROWSERS']: | |
| 375 installers += firefox_installer | |
| 376 if 'SF' in env['VALID_BROWSERS']: | |
| 377 installers += [ | |
| 378 safari_input_manager_bundle, | |
| 379 safari_plugin_bundle, | |
| 380 safari_plugin_proxy_bundle, | |
| 381 safari_installer_plugin_bundle, | |
| 382 safari_installer_package, | |
| 383 safari_input_manager_bundle, | |
| 384 safari_keystone_installer, | |
| 385 ] | |
| 386 if env['OS'] == 'win32': | |
| 387 installers += win32_installer | |
| 388 if env['OS'] == 'wince': | |
| 389 installers += wince_installer | |
| 390 | |
| 391 env.Alias('gears-installers', installers) | |
| OLD | NEW |