Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2013 Google Inc. All rights reserved. | 1 # Copyright (c) 2013 Google Inc. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Utility functions shared amongst the Windows generators.""" | 5 """Utility functions shared amongst the Windows generators.""" |
| 6 | 6 |
| 7 import copy | 7 import copy |
| 8 import os | |
| 9 | |
| 10 | |
| 11 _THIS_DIR = os.path.abspath(os.path.dirname(__file__)) | |
| 12 _SRC_DIR = os.path.abspath(os.path.join(_THIS_DIR, '..', '..')) | |
| 13 _WIN_DATA_DIR = os.path.join(_SRC_DIR, 'data', 'win') | |
| 14 _LARGE_PDB_SHIM_CC = os.path.join(_WIN_DATA_DIR, 'large-pdb-shim.cc') | |
| 15 | |
|
Evan Martin
2013/03/06 20:43:39
Nit: rather than put all of these variables at mod
chrisha
2013/03/14 15:57:23
Done.
| |
| 16 | |
| 17 _TARGET_TYPE_EXT = { | |
| 18 'executable': '.exe', | |
| 19 'shared_library': '.dll' | |
| 20 } | |
| 21 | |
| 22 | |
| 23 def _SuffixName(name, suffix): | |
| 24 """Add a suffix to the end of a target. | |
| 25 | |
| 26 Arguments: | |
| 27 name: name of the target (foo#target) | |
| 28 suffix: the suffix to be added | |
| 29 Returns: | |
| 30 Target name with suffix added (foo_suffix#target) | |
| 31 """ | |
| 32 parts = name.rsplit('#', 1) | |
| 33 parts[0] = '%s_%s' % (parts[0], suffix) | |
| 34 return '#'.join(parts) | |
| 35 | |
| 8 | 36 |
| 9 def _ShardName(name, number): | 37 def _ShardName(name, number): |
| 10 """Add a shard number to the end of a target. | 38 """Add a shard number to the end of a target. |
| 11 | 39 |
| 12 Arguments: | 40 Arguments: |
| 13 name: name of the target (foo#target) | 41 name: name of the target (foo#target) |
| 14 number: shard number | 42 number: shard number |
| 15 Returns: | 43 Returns: |
| 16 Target name with shard added (foo_1#target) | 44 Target name with shard added (foo_1#target) |
| 17 """ | 45 """ |
| 18 parts = name.rsplit('#', 1) | 46 return _SuffixName(name, str(number)) |
| 19 parts[0] = '%s_%d' % (parts[0], number) | |
| 20 return '#'.join(parts) | |
| 21 | 47 |
| 22 | 48 |
| 23 def ShardTargets(target_list, target_dicts): | 49 def ShardTargets(target_list, target_dicts): |
| 24 """Shard some targets apart to work around the linkers limits. | 50 """Shard some targets apart to work around the linkers limits. |
| 25 | 51 |
| 26 Arguments: | 52 Arguments: |
| 27 target_list: List of target pairs: 'base/base.gyp:base'. | 53 target_list: List of target pairs: 'base/base.gyp:base'. |
| 28 target_dicts: Dict of target properties keyed on target pair. | 54 target_dicts: Dict of target properties keyed on target pair. |
| 29 Returns: | 55 Returns: |
| 30 Tuple of the new sharded versions of the inputs. | 56 Tuple of the new sharded versions of the inputs. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 65 new_dependencies = [] | 91 new_dependencies = [] |
| 66 for d in dependencies: | 92 for d in dependencies: |
| 67 if d in targets_to_shard: | 93 if d in targets_to_shard: |
| 68 for i in range(targets_to_shard[d]): | 94 for i in range(targets_to_shard[d]): |
| 69 new_dependencies.append(_ShardName(d, i)) | 95 new_dependencies.append(_ShardName(d, i)) |
| 70 else: | 96 else: |
| 71 new_dependencies.append(d) | 97 new_dependencies.append(d) |
| 72 new_target_dicts[t]['dependencies'] = new_dependencies | 98 new_target_dicts[t]['dependencies'] = new_dependencies |
| 73 | 99 |
| 74 return (new_target_list, new_target_dicts) | 100 return (new_target_list, new_target_dicts) |
| 101 | |
| 102 | |
| 103 def InsertLargePdbShims(target_list, target_dicts, vars): | |
| 104 """Insert a shim target that forces the linker to use 4KB pagesize PDBs. | |
| 105 | |
| 106 This is a workaround for targets with PDBs greater than 1GB in size, the | |
| 107 limit for the 1KB pagesize PDBs created by the linker by default. | |
| 108 | |
| 109 Arguments: | |
| 110 target_list: List of target pairs: 'base/base.gyp:base'. | |
| 111 target_dicts: Dict of target properties keyed on target pair. | |
| 112 vars: A dictionary of common GYP variables with generator-specific values. | |
| 113 Returns: | |
| 114 Tuple of the shimmed version of the inputs. | |
| 115 """ | |
| 116 # Determine which targets need shimming. | |
| 117 targets_to_shim = [] | |
| 118 for t in target_dicts: | |
| 119 d = target_dicts[t] | |
| 120 # We only want to shim targets that have msvs_large_pdb enabled. | |
| 121 if d.get('msvs_large_pdb', '0') != '1': | |
| 122 continue | |
| 123 # This is only intended for use by linker targets that are producing a | |
| 124 # PE file. | |
| 125 if d['type'] not in ['executable', 'shared_library']: | |
|
scottmg
2013/03/06 19:03:34
is all of this checking necessary? can't we just p
Evan Martin
2013/03/06 20:43:39
I think it's better to fail (or at least warn) lou
chrisha
2013/03/14 15:57:23
Done.
| |
| 126 continue | |
| 127 # This is only intended for use with targets that produce PDB output in | |
| 128 # all configurations. | |
| 129 has_pdb = True | |
| 130 for config in d['configurations'].itervalues(): | |
| 131 linker = config.get('msvs_settings', {}).get('VCLinkerTool', {}) | |
| 132 if linker.get('GenerateDebugInformation', 'false') != 'true': | |
| 133 has_pdb = False | |
| 134 continue | |
| 135 if len(linker.get('ProgramDatabaseFile', '')) == 0: | |
| 136 has_pdb = False | |
| 137 continue | |
| 138 if not has_pdb: | |
| 139 continue | |
| 140 | |
| 141 # This target is eligible for shimming. | |
| 142 targets_to_shim.append(t) | |
| 143 | |
| 144 for t in targets_to_shim: | |
| 145 d = target_dicts[t] | |
| 146 target_name = d.get('target_name') | |
| 147 | |
| 148 # This is the dict for copying the source file (part of the GYP tree) | |
| 149 # to the intermediate directory of the project. This is necessary otherwise | |
| 150 # we can't always build a relative path to the shim source file, and Ninja | |
|
scottmg
2013/03/06 19:03:34
sorry, why can't we build a relative path?
if it'
chrisha
2013/03/14 15:57:23
Because on windows your gyp install might be on a
| |
| 151 # hates absolute paths (it ends up generating the .obj and .obj.d alongside | |
| 152 # the source file, polluting GYPs tree). | |
| 153 copy_suffix = '_large_pdb_copy' | |
| 154 copy_target_name = target_name + '_' + copy_suffix | |
| 155 full_copy_target_name = _SuffixName(t, copy_suffix) | |
| 156 shim_cc_basename = os.path.basename(_LARGE_PDB_SHIM_CC) | |
| 157 shim_cc_dir = vars['SHARED_INTERMEDIATE_DIR'] + '/' + copy_target_name | |
| 158 shim_cc_path = shim_cc_dir + '/' + shim_cc_basename | |
| 159 copy_dict = copy.deepcopy(d) | |
| 160 copy_dict['target_name'] = copy_target_name | |
| 161 copy_dict['type'] = 'none' | |
| 162 copy_dict['sources'] = [ _LARGE_PDB_SHIM_CC ] | |
| 163 copy_dict['dependencies'] = [] | |
| 164 copy_dict['copies'] = [{ | |
| 165 'destination': shim_cc_dir, | |
| 166 'files': [ _LARGE_PDB_SHIM_CC ] | |
| 167 }] | |
| 168 | |
| 169 # This is the dict for the PDB generating shim target. It depends on the | |
| 170 # copy target. | |
| 171 shim_suffix = '_large_pdb_shim' | |
| 172 shim_target_name = target_name + '_' + shim_suffix | |
| 173 full_shim_target_name = _SuffixName(t, shim_suffix) | |
| 174 shim_dict = copy.deepcopy(d) | |
| 175 shim_dict['target_name'] = shim_target_name | |
| 176 shim_dict['type'] = 'static_library' | |
| 177 shim_dict['sources'] = [ shim_cc_path ] | |
| 178 shim_dict['dependencies'] = [ full_copy_target_name ] | |
| 179 shim_dict['libraries'] = [] | |
|
chrisha
2013/03/05 20:52:25
I'd love comments as to the sanity of the two deep
scottmg
2013/03/06 19:03:34
i'm afraid i don't know the answer to this questio
chrisha
2013/03/14 15:57:23
Done.
chrisha
2013/03/14 15:57:23
Went with a mix of the two. deepcopied what is abs
| |
| 180 | |
| 181 # Set up the shim to output its PDB to the same location as the final linker | |
| 182 # target. | |
| 183 for config in shim_dict.get('configurations').itervalues(): | |
| 184 msvs = config.setdefault('msvs_settings') | |
| 185 | |
| 186 linker = msvs.pop('VCLinkerTool') # We want to clear this dict. | |
| 187 pdb_path = linker.get('ProgramDatabaseFile') | |
| 188 | |
| 189 compiler = msvs.setdefault('VCCLCompilerTool', {}) | |
| 190 compiler.setdefault('DebugInformationFormat', '3') | |
| 191 compiler.setdefault('ProgramDataBaseFileName', pdb_path) | |
| 192 | |
| 193 # Add the new targets. | |
| 194 target_list.append(full_copy_target_name) | |
| 195 target_list.append(full_shim_target_name) | |
| 196 target_dicts[full_copy_target_name] = copy_dict | |
| 197 target_dicts[full_shim_target_name] = shim_dict | |
| 198 | |
| 199 # Update the original target to depend on the shim target. | |
| 200 d.setdefault('dependencies', []).append(full_shim_target_name) | |
| 201 | |
| 202 return (target_list, target_dicts) | |
| OLD | NEW |