Chromium Code Reviews| Index: pylib/gyp/MSVSUtil.py |
| diff --git a/pylib/gyp/MSVSUtil.py b/pylib/gyp/MSVSUtil.py |
| index 41d7ab28907e1747d9a6409c8f9c57b787c677fc..b1f0cf75bf1eec150b48e1694f98ca37cf0c8c74 100644 |
| --- a/pylib/gyp/MSVSUtil.py |
| +++ b/pylib/gyp/MSVSUtil.py |
| @@ -5,6 +5,46 @@ |
| """Utility functions shared amongst the Windows generators.""" |
| import copy |
| +import os |
| + |
| + |
| +_TARGET_TYPE_EXT = { |
| + 'executable': '.exe', |
| + 'shared_library': '.dll' |
| +} |
| + |
| + |
| +def _GetLargePdbShimCcPath(): |
| + """Returns the path of the large_pdb_shim.cc file.""" |
| + this_dir = os.path.abspath(os.path.dirname(__file__)) |
| + src_dir = os.path.abspath(os.path.join(this_dir, '..', '..')) |
| + win_data_dir = os.path.join(src_dir, 'data', 'win') |
| + large_pdb_shim_cc = os.path.join(win_data_dir, 'large-pdb-shim.cc') |
| + return large_pdb_shim_cc |
| + |
| + |
| +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.
|
| + d = {} |
| + for key in keys: |
| + if key not in dict: |
| + continue |
| + d[key] = copy.deepcopy(dict[key]) |
| + return d |
| + |
| + |
| +def _SuffixName(name, suffix): |
| + """Add a suffix to the end of a target. |
| + |
| + Arguments: |
| + name: name of the target (foo#target) |
| + suffix: the suffix to be added |
| + Returns: |
| + Target name with suffix added (foo_suffix#target) |
| + """ |
| + parts = name.rsplit('#', 1) |
| + parts[0] = '%s_%s' % (parts[0], suffix) |
| + return '#'.join(parts) |
| + |
| def _ShardName(name, number): |
| """Add a shard number to the end of a target. |
| @@ -15,9 +55,7 @@ def _ShardName(name, number): |
| Returns: |
| Target name with shard added (foo_1#target) |
| """ |
| - parts = name.rsplit('#', 1) |
| - parts[0] = '%s_%d' % (parts[0], number) |
| - return '#'.join(parts) |
| + return _SuffixName(name, str(number)) |
| def ShardTargets(target_list, target_dicts): |
| @@ -72,3 +110,94 @@ def ShardTargets(target_list, target_dicts): |
| new_target_dicts[t]['dependencies'] = new_dependencies |
| return (new_target_list, new_target_dicts) |
| + |
| + |
| +def InsertLargePdbShims(target_list, target_dicts, vars): |
| + """Insert a shim target that forces the linker to use 4KB pagesize PDBs. |
| + |
| + This is a workaround for targets with PDBs greater than 1GB in size, the |
| + limit for the 1KB pagesize PDBs created by the linker by default. |
| + |
| + Arguments: |
| + target_list: List of target pairs: 'base/base.gyp:base'. |
| + target_dicts: Dict of target properties keyed on target pair. |
| + vars: A dictionary of common GYP variables with generator-specific values. |
| + Returns: |
| + Tuple of the shimmed version of the inputs. |
| + """ |
| + # Determine which targets need shimming. |
| + targets_to_shim = [] |
| + for t in target_dicts: |
| + target_dict = target_dicts[t] |
| + # We only want to shim targets that have msvs_large_pdb enabled. |
| + 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.
|
| + continue |
| + # This is intended for executable, shared_library and loadable_module |
| + # targets where every configuration is set up to produce a PDB output. |
| + # If any of these conditions is not true then the shim logic will fail |
| + # below. |
| + targets_to_shim.append(t) |
| + |
| + large_pdb_shim_cc = _GetLargePdbShimCcPath() |
| + |
| + for t in targets_to_shim: |
| + target_dict = target_dicts[t] |
| + target_name = target_dict.get('target_name') |
| + |
| + base_dict = _PartiallyDeepCopyDict(target_dict, |
| + ['configurations', 'default_configuration', 'toolset']) |
| + |
| + # This is the dict for copying the source file (part of the GYP tree) |
| + # to the intermediate directory of the project. This is necessary because |
| + # we can't always build a relative path to the shim source file (on Windows |
| + # GYP and the project may be on different drives), and Ninja hates absolute |
| + # paths (it ends up generating the .obj and .obj.d alongside the source |
| + # file, polluting GYPs tree). |
| + copy_suffix = '_large_pdb_copy' |
| + copy_target_name = target_name + '_' + copy_suffix |
| + full_copy_target_name = _SuffixName(t, copy_suffix) |
| + shim_cc_basename = os.path.basename(large_pdb_shim_cc) |
| + shim_cc_dir = vars['SHARED_INTERMEDIATE_DIR'] + '/' + copy_target_name |
| + shim_cc_path = shim_cc_dir + '/' + shim_cc_basename |
| + copy_dict = copy.deepcopy(base_dict) |
| + copy_dict['target_name'] = copy_target_name |
| + copy_dict['type'] = 'none' |
| + copy_dict['sources'] = [ large_pdb_shim_cc ] |
| + copy_dict['copies'] = [{ |
| + 'destination': shim_cc_dir, |
| + 'files': [ large_pdb_shim_cc ] |
| + }] |
| + |
| + # This is the dict for the PDB generating shim target. It depends on the |
| + # copy target. |
| + shim_suffix = '_large_pdb_shim' |
| + shim_target_name = target_name + '_' + shim_suffix |
| + full_shim_target_name = _SuffixName(t, shim_suffix) |
| + shim_dict = copy.deepcopy(base_dict) |
| + shim_dict['target_name'] = shim_target_name |
| + shim_dict['type'] = 'static_library' |
| + shim_dict['sources'] = [ shim_cc_path ] |
| + shim_dict['dependencies'] = [ full_copy_target_name ] |
| + |
| + # Set up the shim to output its PDB to the same location as the final linker |
| + # target. |
| + for config in shim_dict.get('configurations').itervalues(): |
| + msvs = config.setdefault('msvs_settings') |
| + |
| + linker = msvs.pop('VCLinkerTool') # We want to clear this dict. |
| + pdb_path = linker.get('ProgramDatabaseFile') |
| + |
| + compiler = msvs.setdefault('VCCLCompilerTool', {}) |
| + compiler.setdefault('DebugInformationFormat', '3') |
| + compiler.setdefault('ProgramDataBaseFileName', pdb_path) |
| + |
| + # Add the new targets. |
| + target_list.append(full_copy_target_name) |
| + target_list.append(full_shim_target_name) |
| + target_dicts[full_copy_target_name] = copy_dict |
| + target_dicts[full_shim_target_name] = shim_dict |
| + |
| + # Update the original target to depend on the shim target. |
| + target_dict.setdefault('dependencies', []).append(full_shim_target_name) |
| + |
| + return (target_list, target_dicts) |