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

Unified Diff: pylib/gyp/msvs_emulation.py

Issue 9443044: Beginnings of some msvs_... emulation (windows ninja) (Closed) Base URL: https://gyp.googlecode.com/svn/trunk
Patch Set: comment fixes Created 8 years, 10 months 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
Index: pylib/gyp/msvs_emulation.py
diff --git a/pylib/gyp/msvs_emulation.py b/pylib/gyp/msvs_emulation.py
index 7d10b94132af5c77cf2f4c370fbe8ef8ad81a39e..ec7abade7ef641e3e4fde75d00ae1d607f2410b6 100644
--- a/pylib/gyp/msvs_emulation.py
+++ b/pylib/gyp/msvs_emulation.py
@@ -8,6 +8,7 @@ build systems, primarily ninja.
"""
import re
+import sys
windows_quoter_regex = re.compile(r'(\\*)"')
@@ -41,6 +42,196 @@ def QuoteCmdExeArgument(arg):
# applies and whitespace isn't a word break.
return '"' + tmp + '"'
+
def EncodeCmdExeList(args):
"""Process a list of arguments using QuoteCmdExeArgument."""
return ' '.join(QuoteCmdExeArgument(arg) for arg in args)
+
+
+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."""
+ if not root:
+ return default
+ if not path:
+ return root
+ return _GenericRetrieve(root.get(path[0]), default, path[1:])
+
+
+def _AddPrefix(element, prefix):
+ """Add |prefix| to |element| or each subelement if element is iterable."""
+ if element is None:
+ return element
+ # Note, not Iterable because we don't want to handle strings like that.
+ if isinstance(element, list) or isinstance(element, tuple):
Nico 2012/02/29 19:44:18 I think this would become simpler if you cribbed t
scottmg 2012/03/01 18:09:04 I tried that.. but it loses the listness-or-not of
+ return [prefix + e for e in element]
+ else:
+ return prefix + element
+
+
+def _DoRemapping(element, map):
+ """If |element| then remap it through |map|. If |element| is iterable then
+ each item will be remapped. Any elements not found will be removed."""
+ if map is not None and element is not None:
+ if isinstance(element, list) or isinstance(element, tuple):
+ element = [map.get(elem) for elem in element]
+ element = [elem for elem in element if elem is not None]
Nico 2012/02/29 19:44:18 element = filter(none, [map.get(elem) for elem in
scottmg 2012/03/01 18:09:04 Done.
+ else:
+ element = map.get(element)
+ return element
+
+
+def _AppendOrReturn(append, element):
Nico 2012/02/29 19:44:18 Docstring
scottmg 2012/03/01 18:09:04 Done.
+ if append is not None and element is not None:
+ if isinstance(element, list) or isinstance(element, tuple):
+ append.extend(element)
+ else:
+ append.append(element)
+ else:
+ return element
+
+
+class MsvsSettings(object):
+ """A class that understands the gyp 'msvs_...' values (especially the
+ msvs_settings field). They largely correpond to the VS2008 IDE DOM. This
+ class helps map those settings to command line options."""
+
+ def __init__(self, spec):
+ self.spec = spec
+ self.configname = None
+
+ supported_fields = [
+ 'msvs_configuration_attributes',
+ 'msvs_settings',
+ 'msvs_system_include_dirs',
+ 'msvs_disabled_warnings',
+ ]
+ configs = spec['configurations']
+ for field in supported_fields:
+ setattr(self, field, {})
+ for configname, config in configs.iteritems():
+ getattr(self, field)[configname] = config.get(field, {})
+
+ def ConvertVSMacros(self, s):
Nico 2012/02/29 19:44:18 Private function?
scottmg 2012/03/01 18:09:04 Done.
+ """Convert from VS macro names to something equivalent."""
+ if '$' in s:
+ replacements = {
+ # TODO(scottmg): obviously
+ '$(VSInstallDir)':
+ r'C:\Program Files (x86)\Microsoft Visual Studio 9.0\\',
+ }
+ for old, new in replacements.iteritems():
+ s = s.replace(old, new)
+ return s
+
+ def GetAndMunge(self, field, path, default, prefix, append, map):
Nico 2012/02/29 19:44:18 Private function?
scottmg 2012/03/01 18:09:04 Done.
+ """Retrieve a value from |field| at |path| or return |default|. If
+ |append| is specified, and the item is found, it will be appended to that
+ object instead of returned. If |map| is specified, results will be
+ remapped through |map| before being returned or appended."""
+ result = _GenericRetrieve(field, default, path)
+ result = _DoRemapping(result, map)
+ result = _AddPrefix(result, prefix)
+ return _AppendOrReturn(append, result)
+
+ class GetWrapper(object):
Nico 2012/02/29 19:44:18 Private nested class?
scottmg 2012/03/01 18:09:04 Done.
+ def __init__(self, parent, field, base_path, append=None):
+ self.parent = parent
+ self.field = field
+ self.base_path = [base_path]
+ self.append = append
+ def __call__(self, name, map=None, prefix=''):
+ return self.parent.GetAndMunge(self.field, self.base_path + [name],
+ default=None, prefix=prefix, append=self.append, map=map)
+
+ def Setting(self, path, default=None, prefix='', append=None, map=None):
+ return self.GetAndMunge(
+ self.msvs_settings[self.configname], path, default, prefix, append, map)
+
+ def ConfigAttrib(self, path, default=None, prefix='', append=None, map=None):
+ """GetAndMunge for msvs_configuration_attributes."""
+ return self.GetAndMunge(
+ self.msvs_configuration_attributes[self.configname],
+ path, default, prefix, append, map)
+
+ def GetSystemIncludes(self, config):
+ """Returns the extra set of include paths that are used for the Windows
+ SDK and similar."""
+ return [self.ConvertVSMacros(p)
+ for p in self.msvs_system_include_dirs[config]]
+
+ def GetComputedDefines(self, config):
+ """Returns the set of defines that are injected to the defines list based
+ on other VS settings."""
+ self.configname = config
+ defines = []
+ if self.ConfigAttrib(['CharacterSet']) == '1':
+ defines.extend(('_UNICODE', 'UNICODE'))
+ if self.ConfigAttrib(['CharacterSet']) == '2':
+ defines.append('_MBCS')
+ defines.extend(self.Setting(('VCCLCompilerTool', 'PreprocessorDefinitions'),
+ default=[]))
+ self.configname = None
+ return defines
+
+ def GetCflags(self, config):
+ """Returns the flags that need to be added to .c and .cc compilations."""
+ cflags = []
+ cflags.extend(['$!/wd' + w for w in self.msvs_disabled_warnings[config]])
+ cl = self.GetWrapper(self, self.msvs_settings[config],
+ 'VCCLCompilerTool', append=cflags)
+ cl('Optimization', map={'0':'d', '2':'s'}, prefix='$!/O')
+ cl('InlineFunctionExpansion', prefix='$!/Ob')
+ cl('OmitFramePointers', map={'false':'-', 'true':''}, prefix='$!/Oy')
+ cl('FavorSizeOrSpeed', map={'1':'s', '2':'t'}, prefix='$!/O')
+ cl('WholeProgramOptimization', map={'true':'$!/GL'})
+ cl('WarningLevel', prefix='$!/W')
+ cl('WarnAsError', map={'true':'$!/WX'})
+ cl('DebugInformationFormat', map={'1':'7', '3':'i', '4':'I'}, prefix='$!/Z')
+ cl('RuntimeTypeInfo', map={'true':'$!/GR', 'false':'$!/GR-'})
+ cl('EnableFunctionLevelLinking', map={'true':'$!/Gy', 'false':'$!/Gy-'})
+ cl('MinimalRebuild', map={'true':'$!/Gm'})
+ cl('BufferSecurityCheck', map={'true':'$!/GS', 'false':'$!/GS-'})
+ cl('BasicRuntimeChecks', map={'1':'s', '2':'u', '3':'1'}, prefix='$!/RTC')
+ cl('RuntimeLibrary',
+ map={'0':'T', '1':'Td', '2':'D', '3':'Dd'}, prefix='$!/M')
+ cl('ExceptionHandling', map={'1':'sc','2':'a'}, prefix='$!/EH')
+ cl('AdditionalOptions', prefix='$!')
+ return cflags
+
+ def GetCflagsC(self, config):
+ """Returns the flags that need to be added to .c compilations."""
+ return []
+
+ def GetCflagsCC(self, config):
+ """Returns the flags that need to be added to .cc compilations."""
+ return ['$!/TP']
+
+ def GetLdflags(self, config, product_dir, gyp_to_build_path):
+ """Returns the flags that need to be added to link and lib commands."""
+ ldflags = []
+ ld = self.GetWrapper(self, self.msvs_settings[config],
+ 'VCLinkerTool', append=ldflags)
+ ld('GenerateDebugInformation', map={'true':'$!/DEBUG'})
+ ld('TargetMachine', map={'1':'X86', '17':'X64'}, prefix='$!/MACHINE:')
+ ld('AdditionalLibraryDirectories', prefix='$!/LIBPATH:')
+ ld('DelayLoadDLLs', prefix='$!/DELAYLOAD:')
+ ld('AdditionalOptions', prefix='$!')
+ ld('SubSystem', map={'1':'CONSOLE', '2':'WINDOWS'}, prefix='$!/SUBSYSTEM:')
+ ld('LinkIncremental', map={'1':':NO', '2':''}, prefix='$!/INCREMENTAL')
+ ld('FixedBaseAddress', map={'1':':NO', '2':''}, prefix='$!/FIXED')
+ ld('RandomizedBaseAddress',
+ map={'1':':NO', '2':''}, prefix='$!/DYNAMICBASE')
+ ld('DataExecutionPrevention',
+ map={'1':':NO', '2':''}, prefix='$!/NXCOMPAT')
+ ld('OptimizeReferences', map={'1':'NOREF', '2':'REF'}, prefix='$!/OPT:')
+ ld('EnableCOMDATFolding', map={'1':'NOICF', '2':'ICF'}, prefix='$!/OPT:')
+ ld('LinkTimeCodeGeneration', map={'1':'$!/LTCG'})
+ # TODO(scottmg): This should sort of be somewhere else (not really a flag).
+ ld('AdditionalDependencies', prefix='$!')
+ # TODO(scottmg): These too.
+ ldflags.extend(('kernel32.lib', 'user32.lib', 'gdi32.lib', 'winspool.lib',
+ 'comdlg32.lib', 'advapi32.lib', 'shell32.lib', 'ole32.lib',
+ 'oleaut32.lib', 'uuid.lib', 'odbc32.lib', 'odbccp32.lib',
+ 'DelayImp.lib'))
+ return ldflags

Powered by Google App Engine
This is Rietveld 408576698