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

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: add missing test files and some _->- Created 8 years, 9 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
« no previous file with comments | « pylib/gyp/generator/ninja.py ('k') | test/win/compiler-flags/character-set.gyp » ('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 7d10b94132af5c77cf2f4c370fbe8ef8ad81a39e..7c652159322f124300ea258e390714d9c44d86ba 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(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):
+ 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 = filter(None, [map.get(elem) for elem in element])
+ else:
+ element = map.get(element)
+ return element
+
+
+def _AppendOrReturn(append, element):
+ """If |append| is None, simply return |element|. If |append| is not None,
+ then add |element| to it, adding each item in |element| if it's a list or
+ tuple."""
+ 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):
+ """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):
+ """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):
+ 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):
+ """_GetAndMunge for msvs_settings."""
+ 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
« no previous file with comments | « pylib/gyp/generator/ninja.py ('k') | test/win/compiler-flags/character-set.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698