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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pylib/gyp/generator/ninja.py ('k') | test/win/compiler-flags/character-set.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 Google Inc. All rights reserved. 1 # Copyright (c) 2012 Google Inc. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """ 5 """
6 This module helps emulate Visual Studio 2008 behavior on top of other 6 This module helps emulate Visual Studio 2008 behavior on top of other
7 build systems, primarily ninja. 7 build systems, primarily ninja.
8 """ 8 """
9 9
10 import re 10 import re
11 import sys
11 12
12 windows_quoter_regex = re.compile(r'(\\*)"') 13 windows_quoter_regex = re.compile(r'(\\*)"')
13 14
14 def QuoteCmdExeArgument(arg): 15 def QuoteCmdExeArgument(arg):
15 """Quote a command line argument so that it appears as one argument when 16 """Quote a command line argument so that it appears as one argument when
16 processed via cmd.exe and parsed by CommandLineToArgvW (as is typical for 17 processed via cmd.exe and parsed by CommandLineToArgvW (as is typical for
17 Windows programs).""" 18 Windows programs)."""
18 # See http://goo.gl/cuFbX and http://goo.gl/dhPnp including the comment 19 # See http://goo.gl/cuFbX and http://goo.gl/dhPnp including the comment
19 # threads. This is actually the quoting rules for CommandLineToArgvW, not 20 # threads. This is actually the quoting rules for CommandLineToArgvW, not
20 # for the shell, because the shell doesn't do anything in Windows. This 21 # for the shell, because the shell doesn't do anything in Windows. This
(...skipping 13 matching lines...) Expand all
34 # positional arguments. Also make sure to escape the % so that they're 35 # positional arguments. Also make sure to escape the % so that they're
35 # passed literally through escaping so they can be singled to just the 36 # passed literally through escaping so they can be singled to just the
36 # original %. Otherwise, trying to pass the literal representation that 37 # original %. Otherwise, trying to pass the literal representation that
37 # looks like an environment variable to the shell (e.g. %PATH%) would fail. 38 # looks like an environment variable to the shell (e.g. %PATH%) would fail.
38 tmp = tmp.replace('%', '^%^%') 39 tmp = tmp.replace('%', '^%^%')
39 40
40 # Finally, wrap the whole thing in quotes so that the above quote rule 41 # Finally, wrap the whole thing in quotes so that the above quote rule
41 # applies and whitespace isn't a word break. 42 # applies and whitespace isn't a word break.
42 return '"' + tmp + '"' 43 return '"' + tmp + '"'
43 44
45
44 def EncodeCmdExeList(args): 46 def EncodeCmdExeList(args):
45 """Process a list of arguments using QuoteCmdExeArgument.""" 47 """Process a list of arguments using QuoteCmdExeArgument."""
46 return ' '.join(QuoteCmdExeArgument(arg) for arg in args) 48 return ' '.join(QuoteCmdExeArgument(arg) for arg in args)
49
50
51 def _GenericRetrieve(root, default, path):
52 """Given a list of dictionary keys |path| and a tree of dicts |root|, find
53 value at path, or return |default| if any of the path doesn't exist."""
54 if not root:
55 return default
56 if not path:
57 return root
58 return _GenericRetrieve(root.get(path[0]), default, path[1:])
59
60
61 def _AddPrefix(element, prefix):
62 """Add |prefix| to |element| or each subelement if element is iterable."""
63 if element is None:
64 return element
65 # Note, not Iterable because we don't want to handle strings like that.
66 if isinstance(element, list) or isinstance(element, tuple):
67 return [prefix + e for e in element]
68 else:
69 return prefix + element
70
71
72 def _DoRemapping(element, map):
73 """If |element| then remap it through |map|. If |element| is iterable then
74 each item will be remapped. Any elements not found will be removed."""
75 if map is not None and element is not None:
76 if isinstance(element, list) or isinstance(element, tuple):
77 element = filter(None, [map.get(elem) for elem in element])
78 else:
79 element = map.get(element)
80 return element
81
82
83 def _AppendOrReturn(append, element):
84 """If |append| is None, simply return |element|. If |append| is not None,
85 then add |element| to it, adding each item in |element| if it's a list or
86 tuple."""
87 if append is not None and element is not None:
88 if isinstance(element, list) or isinstance(element, tuple):
89 append.extend(element)
90 else:
91 append.append(element)
92 else:
93 return element
94
95
96 class MsvsSettings(object):
97 """A class that understands the gyp 'msvs_...' values (especially the
98 msvs_settings field). They largely correpond to the VS2008 IDE DOM. This
99 class helps map those settings to command line options."""
100
101 def __init__(self, spec):
102 self.spec = spec
103 self.configname = None
104
105 supported_fields = [
106 'msvs_configuration_attributes',
107 'msvs_settings',
108 'msvs_system_include_dirs',
109 'msvs_disabled_warnings',
110 ]
111 configs = spec['configurations']
112 for field in supported_fields:
113 setattr(self, field, {})
114 for configname, config in configs.iteritems():
115 getattr(self, field)[configname] = config.get(field, {})
116
117 def _ConvertVSMacros(self, s):
118 """Convert from VS macro names to something equivalent."""
119 if '$' in s:
120 replacements = {
121 # TODO(scottmg): obviously
122 '$(VSInstallDir)':
123 r'C:\Program Files (x86)\Microsoft Visual Studio 9.0\\',
124 }
125 for old, new in replacements.iteritems():
126 s = s.replace(old, new)
127 return s
128
129 def _GetAndMunge(self, field, path, default, prefix, append, map):
130 """Retrieve a value from |field| at |path| or return |default|. If
131 |append| is specified, and the item is found, it will be appended to that
132 object instead of returned. If |map| is specified, results will be
133 remapped through |map| before being returned or appended."""
134 result = _GenericRetrieve(field, default, path)
135 result = _DoRemapping(result, map)
136 result = _AddPrefix(result, prefix)
137 return _AppendOrReturn(append, result)
138
139 class _GetWrapper(object):
140 def __init__(self, parent, field, base_path, append=None):
141 self.parent = parent
142 self.field = field
143 self.base_path = [base_path]
144 self.append = append
145 def __call__(self, name, map=None, prefix=''):
146 return self.parent._GetAndMunge(self.field, self.base_path + [name],
147 default=None, prefix=prefix, append=self.append, map=map)
148
149 def Setting(self, path, default=None, prefix='', append=None, map=None):
150 """_GetAndMunge for msvs_settings."""
151 return self._GetAndMunge(
152 self.msvs_settings[self.configname], path, default, prefix, append, map)
153
154 def ConfigAttrib(self, path, default=None, prefix='', append=None, map=None):
155 """_GetAndMunge for msvs_configuration_attributes."""
156 return self._GetAndMunge(
157 self.msvs_configuration_attributes[self.configname],
158 path, default, prefix, append, map)
159
160 def GetSystemIncludes(self, config):
161 """Returns the extra set of include paths that are used for the Windows
162 SDK and similar."""
163 return [self._ConvertVSMacros(p)
164 for p in self.msvs_system_include_dirs[config]]
165
166 def GetComputedDefines(self, config):
167 """Returns the set of defines that are injected to the defines list based
168 on other VS settings."""
169 self.configname = config
170 defines = []
171 if self.ConfigAttrib(['CharacterSet']) == '1':
172 defines.extend(('_UNICODE', 'UNICODE'))
173 if self.ConfigAttrib(['CharacterSet']) == '2':
174 defines.append('_MBCS')
175 defines.extend(self.Setting(('VCCLCompilerTool', 'PreprocessorDefinitions'),
176 default=[]))
177 self.configname = None
178 return defines
179
180 def GetCflags(self, config):
181 """Returns the flags that need to be added to .c and .cc compilations."""
182 cflags = []
183 cflags.extend(['/wd' + w for w in self.msvs_disabled_warnings[config]])
184 cl = self._GetWrapper(self, self.msvs_settings[config],
185 'VCCLCompilerTool', append=cflags)
186 cl('Optimization', map={'0': 'd', '2': 's'}, prefix='/O')
187 cl('InlineFunctionExpansion', prefix='/Ob')
188 cl('OmitFramePointers', map={'false': '-', 'true': ''}, prefix='/Oy')
189 cl('FavorSizeOrSpeed', map={'1': 's', '2': 't'}, prefix='/O')
190 cl('WholeProgramOptimization', map={'true': '/GL'})
191 cl('WarningLevel', prefix='/W')
192 cl('WarnAsError', map={'true': '/WX'})
193 cl('DebugInformationFormat',
194 map={'1': '7', '3': 'i', '4': 'I'}, prefix='/Z')
195 cl('RuntimeTypeInfo', map={'true': '/GR', 'false': '/GR-'})
196 cl('EnableFunctionLevelLinking', map={'true': '/Gy', 'false': '/Gy-'})
197 cl('MinimalRebuild', map={'true': '/Gm'})
198 cl('BufferSecurityCheck', map={'true': '/GS', 'false': '/GS-'})
199 cl('BasicRuntimeChecks', map={'1': 's', '2': 'u', '3': '1'}, prefix='/RTC')
200 cl('RuntimeLibrary',
201 map={'0': 'T', '1': 'Td', '2': 'D', '3': 'Dd'}, prefix='/M')
202 cl('ExceptionHandling', map={'1': 'sc','2': 'a'}, prefix='/EH')
203 cl('AdditionalOptions', prefix='')
204 return cflags
205
206 def GetCflagsC(self, config):
207 """Returns the flags that need to be added to .c compilations."""
208 return []
209
210 def GetCflagsCC(self, config):
211 """Returns the flags that need to be added to .cc compilations."""
212 return ['/TP']
213
214 def GetLdflags(self, config, product_dir, gyp_to_build_path):
215 """Returns the flags that need to be added to link and lib commands."""
216 ldflags = []
217 ld = self._GetWrapper(self, self.msvs_settings[config],
218 'VCLinkerTool', append=ldflags)
219 ld('GenerateDebugInformation', map={'true': '/DEBUG'})
220 ld('TargetMachine', map={'1': 'X86', '17': 'X64'}, prefix='/MACHINE:')
221 ld('AdditionalLibraryDirectories', prefix='/LIBPATH:')
222 ld('DelayLoadDLLs', prefix='/DELAYLOAD:')
223 ld('AdditionalOptions', prefix='')
224 ld('SubSystem', map={'1': 'CONSOLE', '2': 'WINDOWS'}, prefix='/SUBSYSTEM:')
225 ld('LinkIncremental', map={'1': ':NO', '2': ''}, prefix='/INCREMENTAL')
226 ld('FixedBaseAddress', map={'1': ':NO', '2': ''}, prefix='/FIXED')
227 ld('RandomizedBaseAddress',
228 map={'1': ':NO', '2': ''}, prefix='/DYNAMICBASE')
229 ld('DataExecutionPrevention',
230 map={'1': ':NO', '2': ''}, prefix='/NXCOMPAT')
231 ld('OptimizeReferences', map={'1': 'NOREF', '2': 'REF'}, prefix='/OPT:')
232 ld('EnableCOMDATFolding', map={'1': 'NOICF', '2': 'ICF'}, prefix='/OPT:')
233 ld('LinkTimeCodeGeneration', map={'1': '/LTCG'})
234 # TODO(scottmg): This should sort of be somewhere else (not really a flag).
235 ld('AdditionalDependencies', prefix='')
236 # TODO(scottmg): These too.
237 ldflags.extend(('kernel32.lib', 'user32.lib', 'gdi32.lib', 'winspool.lib',
238 'comdlg32.lib', 'advapi32.lib', 'shell32.lib', 'ole32.lib',
239 'oleaut32.lib', 'uuid.lib', 'odbc32.lib', 'odbccp32.lib',
240 'DelayImp.lib'))
241 return ldflags
OLDNEW
« 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