cell: keep track of num_vertex_attribs/buffers for shorter loops
[mesa.git] / winddk.py
1 """winddk
2
3 Tool-specific initialization for Microsoft Windows DDK.
4
5 Based on engine.SCons.Tool.msvc.
6
7 There normally shouldn't be any need to import this module directly.
8 It will usually be imported through the generic SCons.Tool.Tool()
9 selection method.
10
11 """
12
13 #
14 # Copyright (c) 2001-2007 The SCons Foundation
15 # Copyright (c) 2008 Tungsten Graphics, Inc.
16 #
17 # Permission is hereby granted, free of charge, to any person obtaining
18 # a copy of this software and associated documentation files (the
19 # "Software"), to deal in the Software without restriction, including
20 # without limitation the rights to use, copy, modify, merge, publish,
21 # distribute, sublicense, and/or sell copies of the Software, and to
22 # permit persons to whom the Software is furnished to do so, subject to
23 # the following conditions:
24 #
25 # The above copyright notice and this permission notice shall be included
26 # in all copies or substantial portions of the Software.
27 #
28 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
29 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
30 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 #
36
37 import os.path
38 import re
39 import string
40
41 import SCons.Action
42 import SCons.Builder
43 import SCons.Errors
44 import SCons.Platform.win32
45 import SCons.Tool
46 import SCons.Tool.mslib
47 import SCons.Tool.mslink
48 import SCons.Util
49 import SCons.Warnings
50
51 CSuffixes = ['.c', '.C']
52 CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
53
54 def get_winddk_paths(env, version=None):
55 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values
56 of those three environment variables that should be set
57 in order to execute the MSVC tools properly."""
58
59 WINDDKdir = None
60 exe_paths = []
61 lib_paths = []
62 include_paths = []
63
64 if 'BASEDIR' in os.environ:
65 WINDDKdir = os.environ['BASEDIR']
66 else:
67 WINDDKdir = "C:\\WINDDK\\3790.1830"
68
69 exe_paths.append( os.path.join(WINDDKdir, 'bin') )
70 exe_paths.append( os.path.join(WINDDKdir, 'bin', 'x86') )
71 include_paths.append( os.path.join(WINDDKdir, 'inc', 'wxp') )
72 lib_paths.append( os.path.join(WINDDKdir, 'lib') )
73
74 target_os = 'wxp'
75 target_cpu = 'i386'
76
77 env['SDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc', target_os)
78 env['CRT_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'crt')
79 env['DDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'ddk', target_os)
80 env['WDM_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'ddk', 'wdm', target_os)
81
82 env['SDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu)
83 env['CRT_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', 'crt', target_cpu)
84 env['DDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu)
85 env['WDM_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu)
86
87 include_path = string.join( include_paths, os.pathsep )
88 lib_path = string.join(lib_paths, os.pathsep )
89 exe_path = string.join(exe_paths, os.pathsep )
90 return (include_path, lib_path, exe_path)
91
92 def set_winddk_flags(env):
93 """Mimic WINDDK's builtin flags.
94
95 See also:
96 - WINDDK's bin/makefile.new i386mk.inc for more info.
97 - buildchk_wxp_x86.log files, generated by the WINDDK's build
98 - http://alter.org.ua/docs/nt_kernel/vc8_proj/
99 """
100
101 cppdefines = [
102 ('_X86_', '1'),
103 ('i386', '1'),
104 'STD_CALL',
105 ('CONDITION_HANDLING', '1'),
106 ('NT_INST', '0'),
107 ('WIN32', '100'),
108 ('_NT1X_', '100'),
109 ('WINNT', '1'),
110 ('_WIN32_WINNT', '0x0501'), # minimum required OS version
111 ('WINVER', '0x0501'),
112 ('_WIN32_IE', '0x0603'),
113 ('WIN32_LEAN_AND_MEAN', '1'),
114 ('DEVL', '1'),
115 ('__BUILDMACHINE__', 'WinDDK'),
116 ('FPO', '0'),
117 ]
118 if env.get('DEBUG', False):
119 cppdefines += [
120 ('DBG', 1),
121 ]
122 env.Append(CPPDEFINES = cppdefines)
123
124 # See also:
125 # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx
126 # - cl /?
127 cflags = [
128 '/Zl', # omit default library name in .OBJ
129 '/Zp8', # 8bytes struct member alignment
130 '/Gy', # separate functions for linker
131 '/Gm-', # disable minimal rebuild
132 '/W3', # warning level
133 '/WX', # treat warnings as errors
134 '/Gz', # __stdcall Calling convention
135 '/GX-', # disable C++ EH
136 '/GR-', # disable C++ RTTI
137 '/GF', # enable read-only string pooling
138 '/GS', # enable security checks
139 '/G6', # optimize for PPro, P-II, P-III
140 '/Ze', # enable extensions
141 #'/Gi-', # ???
142 '/QIfdiv-', # disable Pentium FDIV fix
143 #'/hotpatch', # ???
144 #'/Z7', #enable old-style debug info
145 ]
146 if env.get('debug', False):
147 cflags += [
148 '/Od', # disable optimizations
149 '/Oi', # enable intrinsic functions
150 '/Oy-', # disable frame pointer omission
151 ]
152 else:
153 cflags += [
154 '/Ox', # maximum optimizations
155 '/Oi', # enable intrinsic functions
156 '/Os', # favor code space
157 ]
158 env.Append(CFLAGS = cflags)
159 env.Append(CXXFLAGS = cflags)
160
161 # See also:
162 # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx
163 env.Append(LINKFLAGS = [
164 '/merge:_PAGE=PAGE',
165 '/merge:_TEXT=.text',
166 '/section:INIT,d',
167 '/opt:ref',
168 '/opt:icf',
169 '/ignore:4198,4010,4037,4039,4065,4070,4078,4087,4089,4221',
170 '/incremental:no',
171 '/fullbuild',
172 '/release',
173 '/nodefaultlib',
174 '/wx',
175 '/debug',
176 '/debugtype:cv',
177 '/version:5.1',
178 '/osversion:5.1',
179 '/functionpadmin:5',
180 '/safeseh',
181 '/pdbcompress',
182 '/stack:0x40000,0x1000',
183 '/driver',
184 '/align:0x80',
185 '/subsystem:native,5.01',
186 '/base:0x10000',
187
188 '/entry:DrvEnableDriver',
189 ])
190
191 def validate_vars(env):
192 """Validate the PCH and PCHSTOP construction variables."""
193 if env.has_key('PCH') and env['PCH']:
194 if not env.has_key('PCHSTOP'):
195 raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined."
196 if not SCons.Util.is_String(env['PCHSTOP']):
197 raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP']
198
199 def pch_emitter(target, source, env):
200 """Adds the object file target."""
201
202 validate_vars(env)
203
204 pch = None
205 obj = None
206
207 for t in target:
208 if SCons.Util.splitext(str(t))[1] == '.pch':
209 pch = t
210 if SCons.Util.splitext(str(t))[1] == '.obj':
211 obj = t
212
213 if not obj:
214 obj = SCons.Util.splitext(str(pch))[0]+'.obj'
215
216 target = [pch, obj] # pch must be first, and obj second for the PCHCOM to work
217
218 return (target, source)
219
220 def object_emitter(target, source, env, parent_emitter):
221 """Sets up the PCH dependencies for an object file."""
222
223 validate_vars(env)
224
225 parent_emitter(target, source, env)
226
227 if env.has_key('PCH') and env['PCH']:
228 env.Depends(target, env['PCH'])
229
230 return (target, source)
231
232 def static_object_emitter(target, source, env):
233 return object_emitter(target, source, env,
234 SCons.Defaults.StaticObjectEmitter)
235
236 def shared_object_emitter(target, source, env):
237 return object_emitter(target, source, env,
238 SCons.Defaults.SharedObjectEmitter)
239
240 pch_action = SCons.Action.Action('$PCHCOM', '$PCHCOMSTR')
241 pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch',
242 emitter=pch_emitter,
243 source_scanner=SCons.Tool.SourceFileScanner)
244 res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR')
245 res_builder = SCons.Builder.Builder(action=res_action,
246 src_suffix='.rc',
247 suffix='.res',
248 src_builder=[],
249 source_scanner=SCons.Tool.SourceFileScanner)
250 SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan)
251
252 def generate(env):
253 """Add Builders and construction variables for MSVC++ to an Environment."""
254 static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
255
256 for suffix in CSuffixes:
257 static_obj.add_action(suffix, SCons.Defaults.CAction)
258 shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
259 static_obj.add_emitter(suffix, static_object_emitter)
260 shared_obj.add_emitter(suffix, shared_object_emitter)
261
262 for suffix in CXXSuffixes:
263 static_obj.add_action(suffix, SCons.Defaults.CXXAction)
264 shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction)
265 static_obj.add_emitter(suffix, static_object_emitter)
266 shared_obj.add_emitter(suffix, shared_object_emitter)
267
268 env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}'])
269 env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'])
270 env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS'
271 env['CC'] = 'cl'
272 env['CCFLAGS'] = SCons.Util.CLVar('/nologo')
273 env['CFLAGS'] = SCons.Util.CLVar('')
274 env['CCCOM'] = '$CC $CFLAGS $CCFLAGS $CCCOMFLAGS'
275 env['SHCC'] = '$CC'
276 env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
277 env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS')
278 env['SHCCCOM'] = '$SHCC $SHCFLAGS $SHCCFLAGS $CCCOMFLAGS'
279 env['CXX'] = '$CC'
280 env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS $( /TP $)')
281 env['CXXCOM'] = '$CXX $CXXFLAGS $CCCOMFLAGS'
282 env['SHCXX'] = '$CXX'
283 env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
284 env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CCCOMFLAGS'
285 env['CPPDEFPREFIX'] = '/D'
286 env['CPPDEFSUFFIX'] = ''
287 env['INCPREFIX'] = '/I'
288 env['INCSUFFIX'] = ''
289 # env.Append(OBJEMITTER = [static_object_emitter])
290 # env.Append(SHOBJEMITTER = [shared_object_emitter])
291 env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
292
293 env['RC'] = 'rc'
294 env['RCFLAGS'] = SCons.Util.CLVar('')
295 env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES'
296 env['BUILDERS']['RES'] = res_builder
297 env['OBJPREFIX'] = ''
298 env['OBJSUFFIX'] = '.obj'
299 env['SHOBJPREFIX'] = '$OBJPREFIX'
300 env['SHOBJSUFFIX'] = '$OBJSUFFIX'
301
302 env['CFILESUFFIX'] = '.c'
303 env['CXXFILESUFFIX'] = '.cc'
304
305 env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}'])
306 env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
307 env['BUILDERS']['PCH'] = pch_builder
308
309 env['AR'] = 'lib'
310 env['ARFLAGS'] = SCons.Util.CLVar('/nologo')
311 env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}"
312 env['LIBPREFIX'] = ''
313 env['LIBSUFFIX'] = '.lib'
314
315 SCons.Tool.mslink.generate(env)
316
317 set_winddk_flags(env)
318
319 if not env.has_key('ENV'):
320 env['ENV'] = {}
321
322 try:
323 include_path, lib_path, exe_path = get_winddk_paths(env)
324
325 # since other tools can set these, we just make sure that the
326 # relevant stuff from WINDDK is in there somewhere.
327 env.PrependENVPath('INCLUDE', include_path)
328 env.PrependENVPath('LIB', lib_path)
329 env.PrependENVPath('PATH', exe_path)
330 except (SCons.Util.RegError, SCons.Errors.InternalError):
331 pass
332
333
334 def exists(env):
335 return env.Detect('cl')
336
337 # vim:set sw=4 et: