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 _TARGET_TYPE_EXT = { | |
12 'executable': '.exe', | |
13 'shared_library': '.dll' | |
14 } | |
15 | |
16 | |
17 def _GetLargePdbShimCcPath(): | |
18 """Returns the path of the large_pdb_shim.cc file.""" | |
19 this_dir = os.path.abspath(os.path.dirname(__file__)) | |
20 src_dir = os.path.abspath(os.path.join(this_dir, '..', '..')) | |
21 win_data_dir = os.path.join(src_dir, 'data', 'win') | |
22 large_pdb_shim_cc = os.path.join(win_data_dir, 'large-pdb-shim.cc') | |
23 return large_pdb_shim_cc | |
24 | |
25 | |
26 def _PartiallyDeepCopyDict(dict, keys): | |
scottmg
2013/03/14 17:37:08
docstring
(trying to think of a better name too,
chrisha
2013/03/15 00:02:44
Done.
| |
27 d = {} | |
28 for key in keys: | |
29 if key not in dict: | |
30 continue | |
31 d[key] = copy.deepcopy(dict[key]) | |
32 return d | |
33 | |
34 | |
35 def _SuffixName(name, suffix): | |
36 """Add a suffix to the end of a target. | |
37 | |
38 Arguments: | |
39 name: name of the target (foo#target) | |
40 suffix: the suffix to be added | |
41 Returns: | |
42 Target name with suffix added (foo_suffix#target) | |
43 """ | |
44 parts = name.rsplit('#', 1) | |
45 parts[0] = '%s_%s' % (parts[0], suffix) | |
46 return '#'.join(parts) | |
47 | |
8 | 48 |
9 def _ShardName(name, number): | 49 def _ShardName(name, number): |
10 """Add a shard number to the end of a target. | 50 """Add a shard number to the end of a target. |
11 | 51 |
12 Arguments: | 52 Arguments: |
13 name: name of the target (foo#target) | 53 name: name of the target (foo#target) |
14 number: shard number | 54 number: shard number |
15 Returns: | 55 Returns: |
16 Target name with shard added (foo_1#target) | 56 Target name with shard added (foo_1#target) |
17 """ | 57 """ |
18 parts = name.rsplit('#', 1) | 58 return _SuffixName(name, str(number)) |
19 parts[0] = '%s_%d' % (parts[0], number) | |
20 return '#'.join(parts) | |
21 | 59 |
22 | 60 |
23 def ShardTargets(target_list, target_dicts): | 61 def ShardTargets(target_list, target_dicts): |
24 """Shard some targets apart to work around the linkers limits. | 62 """Shard some targets apart to work around the linkers limits. |
25 | 63 |
26 Arguments: | 64 Arguments: |
27 target_list: List of target pairs: 'base/base.gyp:base'. | 65 target_list: List of target pairs: 'base/base.gyp:base'. |
28 target_dicts: Dict of target properties keyed on target pair. | 66 target_dicts: Dict of target properties keyed on target pair. |
29 Returns: | 67 Returns: |
30 Tuple of the new sharded versions of the inputs. | 68 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 = [] | 103 new_dependencies = [] |
66 for d in dependencies: | 104 for d in dependencies: |
67 if d in targets_to_shard: | 105 if d in targets_to_shard: |
68 for i in range(targets_to_shard[d]): | 106 for i in range(targets_to_shard[d]): |
69 new_dependencies.append(_ShardName(d, i)) | 107 new_dependencies.append(_ShardName(d, i)) |
70 else: | 108 else: |
71 new_dependencies.append(d) | 109 new_dependencies.append(d) |
72 new_target_dicts[t]['dependencies'] = new_dependencies | 110 new_target_dicts[t]['dependencies'] = new_dependencies |
73 | 111 |
74 return (new_target_list, new_target_dicts) | 112 return (new_target_list, new_target_dicts) |
113 | |
114 | |
115 def InsertLargePdbShims(target_list, target_dicts, vars): | |
116 """Insert a shim target that forces the linker to use 4KB pagesize PDBs. | |
117 | |
118 This is a workaround for targets with PDBs greater than 1GB in size, the | |
119 limit for the 1KB pagesize PDBs created by the linker by default. | |
120 | |
121 Arguments: | |
122 target_list: List of target pairs: 'base/base.gyp:base'. | |
123 target_dicts: Dict of target properties keyed on target pair. | |
124 vars: A dictionary of common GYP variables with generator-specific values. | |
125 Returns: | |
126 Tuple of the shimmed version of the inputs. | |
127 """ | |
128 # Determine which targets need shimming. | |
129 targets_to_shim = [] | |
130 for t in target_dicts: | |
131 target_dict = target_dicts[t] | |
132 # We only want to shim targets that have msvs_large_pdb enabled. | |
133 if target_dict.get('msvs_large_pdb', '0') != '1': | |
scottmg
2013/03/14 17:37:08
nit, most gyp code is: if target_dict.get('msvs_la
chrisha
2013/03/15 00:02:44
Done.
| |
134 continue | |
135 # This is intended for executable, shared_library and loadable_module | |
136 # targets where every configuration is set up to produce a PDB output. | |
137 # If any of these conditions is not true then the shim logic will fail | |
138 # below. | |
139 targets_to_shim.append(t) | |
140 | |
141 large_pdb_shim_cc = _GetLargePdbShimCcPath() | |
142 | |
143 for t in targets_to_shim: | |
144 target_dict = target_dicts[t] | |
145 target_name = target_dict.get('target_name') | |
146 | |
147 base_dict = _PartiallyDeepCopyDict(target_dict, | |
148 ['configurations', 'default_configuration', 'toolset']) | |
149 | |
150 # This is the dict for copying the source file (part of the GYP tree) | |
151 # to the intermediate directory of the project. This is necessary because | |
152 # we can't always build a relative path to the shim source file (on Windows | |
153 # GYP and the project may be on different drives), and Ninja hates absolute | |
154 # paths (it ends up generating the .obj and .obj.d alongside the source | |
155 # file, polluting GYPs tree). | |
156 copy_suffix = '_large_pdb_copy' | |
157 copy_target_name = target_name + '_' + copy_suffix | |
158 full_copy_target_name = _SuffixName(t, copy_suffix) | |
159 shim_cc_basename = os.path.basename(large_pdb_shim_cc) | |
160 shim_cc_dir = vars['SHARED_INTERMEDIATE_DIR'] + '/' + copy_target_name | |
161 shim_cc_path = shim_cc_dir + '/' + shim_cc_basename | |
162 copy_dict = copy.deepcopy(base_dict) | |
163 copy_dict['target_name'] = copy_target_name | |
164 copy_dict['type'] = 'none' | |
165 copy_dict['sources'] = [ large_pdb_shim_cc ] | |
166 copy_dict['copies'] = [{ | |
167 'destination': shim_cc_dir, | |
168 'files': [ large_pdb_shim_cc ] | |
169 }] | |
170 | |
171 # This is the dict for the PDB generating shim target. It depends on the | |
172 # copy target. | |
173 shim_suffix = '_large_pdb_shim' | |
174 shim_target_name = target_name + '_' + shim_suffix | |
175 full_shim_target_name = _SuffixName(t, shim_suffix) | |
176 shim_dict = copy.deepcopy(base_dict) | |
177 shim_dict['target_name'] = shim_target_name | |
178 shim_dict['type'] = 'static_library' | |
179 shim_dict['sources'] = [ shim_cc_path ] | |
180 shim_dict['dependencies'] = [ full_copy_target_name ] | |
181 | |
182 # Set up the shim to output its PDB to the same location as the final linker | |
183 # target. | |
184 for config in shim_dict.get('configurations').itervalues(): | |
185 msvs = config.setdefault('msvs_settings') | |
186 | |
187 linker = msvs.pop('VCLinkerTool') # We want to clear this dict. | |
188 pdb_path = linker.get('ProgramDatabaseFile') | |
189 | |
190 compiler = msvs.setdefault('VCCLCompilerTool', {}) | |
191 compiler.setdefault('DebugInformationFormat', '3') | |
192 compiler.setdefault('ProgramDataBaseFileName', pdb_path) | |
193 | |
194 # Add the new targets. | |
195 target_list.append(full_copy_target_name) | |
196 target_list.append(full_shim_target_name) | |
197 target_dicts[full_copy_target_name] = copy_dict | |
198 target_dicts[full_shim_target_name] = shim_dict | |
199 | |
200 # Update the original target to depend on the shim target. | |
201 target_dict.setdefault('dependencies', []).append(full_shim_target_name) | |
202 | |
203 return (target_list, target_dicts) | |
OLD | NEW |