Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Unified Diff: pylib/gyp/msvs_emulation.py

Issue 111373002: win ninja: Refactor manifest generate and embed to be 1-pass (Closed) Base URL: http://gyp.googlecode.com/svn/trunk
Patch Set: add some extra print in failure case, and rebase Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pylib/gyp/generator/ninja.py ('k') | pylib/gyp/win_tool.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pylib/gyp/msvs_emulation.py
diff --git a/pylib/gyp/msvs_emulation.py b/pylib/gyp/msvs_emulation.py
index 723201eb6a1ea0071672059c828cfe01aa312b4d..2a79da36de8e28b4fc77348ddc8c6b2a612a6b1f 100644
--- a/pylib/gyp/msvs_emulation.py
+++ b/pylib/gyp/msvs_emulation.py
@@ -62,6 +62,21 @@ def EncodeRspFileList(args):
return program + ' ' + ' '.join(QuoteForRspFile(arg) for arg in args[1:])
+def _WriteIfChanged(open_output, filename, contents):
+ """Writes the specified contents to the specified filename if the contents
+ are different than the current contents."""
+ try:
+ with open(filename, 'rb') as f:
+ old_contents = f.read()
+ except EnvironmentError:
+ pass
+ else:
+ if contents == old_contents:
+ return
+ with open_output(filename, 'wb') as f:
+ f.write(contents)
Nico 2013/12/12 17:45:54 (There's gyp.common.WriteOnDiff fwiw. It's a bit o
scottmg 2013/12/12 18:14:05 Thanks, done with a little rejiggering. That func
+
+
def _GenericRetrieve(root, default, path):
"""Given a list of dictionary keys |path| and a tree of dicts |root|, find
value at path, or return |default| if any of the path doesn't exist."""
@@ -454,7 +469,7 @@ class MsvsSettings(object):
return output_file
def GetLdflags(self, config, gyp_to_build_path, expand_special,
- manifest_base_name, is_executable):
+ manifest_base_name, is_executable, build_dir, open_output):
"""Returns the flags that need to be added to link commands, and the
manifest files."""
config = self._TargetConfig(config)
@@ -531,17 +546,22 @@ class MsvsSettings(object):
ldflags.append('/NXCOMPAT')
have_def_file = filter(lambda x: x.startswith('/DEF:'), ldflags)
- manifest_flags, manifest_files = self._GetLdManifestFlags(
- config, manifest_base_name, gyp_to_build_path,
- is_executable and not have_def_file)
+ manifest_flags, intermediate_manifest, manifest_files = \
+ self._GetLdManifestFlags(config, manifest_base_name, gyp_to_build_path,
+ is_executable and not have_def_file, build_dir,
+ open_output)
ldflags.extend(manifest_flags)
- return ldflags, manifest_files
+ return ldflags, intermediate_manifest, manifest_files
def _GetLdManifestFlags(self, config, name, gyp_to_build_path,
- allow_isolation):
- """Returns the set of flags that need to be added to the link to generate
- a default manifest, as well as the list of all the manifest files to be
- merged by the manifest tool."""
+ allow_isolation, build_dir, open_output):
+ """Returns a 3-tuple:
+ - the set of flags that need to be added to the link to generate
+ a default manifest
+ - the intermediate manifest that the linker will generate that should be
+ used to assert it doesn't add anything to the merged one.
+ - the list of all the manifest files to be merged by the manifest tool and
+ included into the link."""
generate_manifest = self._Setting(('VCLinkerTool', 'GenerateManifest'),
config,
default='true')
@@ -549,7 +569,7 @@ class MsvsSettings(object):
# This means not only that the linker should not generate the intermediate
# manifest but also that the manifest tool should do nothing even when
# additional manifests are specified.
- return ['/MANIFEST:NO'], []
+ return ['/MANIFEST:NO'], [], []
output_name = name + '.intermediate.manifest'
flags = [
@@ -557,9 +577,25 @@ class MsvsSettings(object):
'/ManifestFile:' + output_name,
]
+ # Instead of using the MANIFESTUAC flags, we generate a .manifest to
+ # include into the list of manifests. This allows us to avoid the need to
+ # do two passes during linking. The /MANIFEST flag and /ManifestFile are
+ # still used, and the intermediate manifest is used to assert that the
+ # final manifest we get from merging all the additional manifest files
+ # (plus the one we generate here) isn't modified by merging the
+ # intermediate into it.
+
+ # Always NO, because we generate a manifest file that has what we want.
+ flags.append('/MANIFESTUAC:NO')
+
config = self._TargetConfig(config)
enable_uac = self._Setting(('VCLinkerTool', 'EnableUAC'), config,
default='true')
+ manifest_files = []
+ generated_manifest_outer = \
+"<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" \
+"<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>%s" \
+"</assembly>"
if enable_uac == 'true':
execution_level = self._Setting(('VCLinkerTool', 'UACExecutionLevel'),
config, default='0')
@@ -571,18 +607,36 @@ class MsvsSettings(object):
ui_access = self._Setting(('VCLinkerTool', 'UACUIAccess'), config,
default='false')
- flags.append('''/MANIFESTUAC:"level='%s' uiAccess='%s'"''' %
- (execution_level_map[execution_level], ui_access))
+
+ inner = '''
+<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level='%s' uiAccess='%s' />
+ </requestedPrivileges>
+ </security>
+</trustInfo>''' % (execution_level_map[execution_level], ui_access)
else:
- flags.append('/MANIFESTUAC:NO')
+ inner = ''
+
+ generated_manifest_contents = generated_manifest_outer % inner
+ generated_name = name + '.generated.manifest'
+ # Need to join with the build_dir here as we're writing it during
+ # generation time, but we return the un-joined version because the build
+ # will occur in that directory. We only write the file if the contents
+ # have changed so that simply regenerating the project files doesn't
+ # cause a relink.
+ _WriteIfChanged(open_output,
+ os.path.join(build_dir, generated_name),
+ generated_manifest_contents)
+ manifest_files = [generated_name]
if allow_isolation:
flags.append('/ALLOWISOLATION')
- manifest_files = [output_name]
manifest_files += self._GetAdditionalManifestFiles(config,
gyp_to_build_path)
- return flags, manifest_files
+ return flags, output_name, manifest_files
def _GetAdditionalManifestFiles(self, config, gyp_to_build_path):
"""Gets additional manifest files that are added to the default one
« no previous file with comments | « pylib/gyp/generator/ninja.py ('k') | pylib/gyp/win_tool.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698