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

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: no pdb option for LIB 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..5f4f03a2a7cca75bf2ddfbf79d9a0a6cc87d223a 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,200 @@ 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(field, default, path):
Nico 2012/02/27 16:23:30 Functions that are private to a class / module sho
scottmg 2012/02/28 00:01:13 Done.
+ """Walk down a tree of dicts starting from |field|, returning |default| if
Nico 2012/02/27 16:23:30 s/field/root/? I found the comment confusing unti
scottmg 2012/02/28 00:01:13 Done.
+ any part of the path is not found along the way."""
+ cur = field
Nico 2012/02/27 16:23:30 I'd just assign to the parameter variable directly
scottmg 2012/02/28 00:01:13 Done.
+ for p in path:
+ if not cur:
+ return default
+ cur = cur.get(p)
+ if cur == None:
Nico 2012/02/27 16:23:30 http://jaredgrubb.blogspot.com/2009/04/python-is-n
scottmg 2012/02/28 00:01:13 Done.
+ return default
+ return cur
Nico 2012/02/27 16:23:30 …could this maybe be more compact recursively? i
scottmg 2012/02/28 00:01:13 Hmm, shrug? Sure. Done.
+
+
+def AddPrefix(element, prefix):
+ """Add prefix to element or each subelement if element is iterable."""
Nico 2012/02/27 16:23:30 s/prefix/|prefix|/ s/element/|element|/
scottmg 2012/02/28 00:01:13 Done.
+ if element == None:
Nico 2012/02/27 16:23:30 is None
scottmg 2012/02/28 00:01:13 Done.
+ return element
+ # Note, not Iterable because we don't want to handle strings like that.
+ if isinstance(element, list) or isinstance(element, tuple):
+ 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 != None and element != None:
Nico 2012/02/27 16:23:30 is not None
scottmg 2012/02/28 00:01:13 Done.
+ if isinstance(element, list) or isinstance(element, tuple):
+ element = [map.get(elem) for elem in element]
+ element = [elem for elem in element if elem != None]
+ else:
+ element = map.get(element)
+ return element
+
+
+def AppendOrReturn(append, element):
+ if append != None and element != 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):
+ """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\\',
Nico 2012/02/27 16:23:30 Does this intentionally have two trailing \?
scottmg 2012/02/28 00:01:13 Vim syntax-highlighting made me do it (I think \'
+ }
+ for old, new in replacements.iteritems():
+ s = s.replace(old, new)
+ return s
+
+ def GetAndMunge(self, field, path, default, prefix, append, map):
+ """Retrieve a value from |field| at |path| or return |default|.
+ Uses self.configname. If |append| is specified, and the item is found,
Nico 2012/02/27 16:23:30 Looks like this doesn't use self.configname
scottmg 2012/02/28 00:01:13 Done.
+ 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):
+ def __init__(self, parent, field, base_path, append=None):
Nico 2012/02/27 16:23:30 It looks like base_path is always 1 element long.
scottmg 2012/02/28 00:01:13 The __call__ retrieve uses root + passed-in as a 2
+ self.parent = parent
+ self.field = field
+ self.base_path = list(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',), cflags)
Nico 2012/02/27 16:23:30 Naming the last parameter ("append=cflags") might
scottmg 2012/02/28 00:01:13 Done.
+ 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',), 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
« pylib/gyp/generator/ninja.py ('K') | « pylib/gyp/input.py ('k') | pylib/gyp/win_tool.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698