Update some msvc compiler flags.
[profile/ivi/mesa.git] / winddk.py
1 """engine.SCons.Tool.msvc
2
3 Tool-specific initialization for Microsoft Visual C/C++.
4
5 There normally shouldn't be any need to import this module directly.
6 It will usually be imported through the generic SCons.Tool.Tool()
7 selection method.
8
9 """
10
11 #
12 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
13 #
14 # Permission is hereby granted, free of charge, to any person obtaining
15 # a copy of this software and associated documentation files (the
16 # "Software"), to deal in the Software without restriction, including
17 # without limitation the rights to use, copy, modify, merge, publish,
18 # distribute, sublicense, and/or sell copies of the Software, and to
19 # permit persons to whom the Software is furnished to do so, subject to
20 # the following conditions:
21 #
22 # The above copyright notice and this permission notice shall be included
23 # in all copies or substantial portions of the Software.
24 #
25 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
26 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
27 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 #
33
34 __revision__ = "src/engine/SCons/Tool/msvc.py 2523 2007/12/12 09:37:41 knight"
35
36 import os.path
37 import re
38 import string
39
40 import SCons.Action
41 import SCons.Builder
42 import SCons.Errors
43 import SCons.Platform.win32
44 import SCons.Tool
45 import SCons.Tool.mslib
46 import SCons.Tool.mslink
47 import SCons.Util
48 import SCons.Warnings
49
50 CSuffixes = ['.c', '.C']
51 CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
52
53 def get_winddk_paths(env, version=None):
54     """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values
55     of those three environment variables that should be set
56     in order to execute the MSVC tools properly."""
57     
58     WINDDKdir = None
59     exe_paths = []
60     lib_paths = []
61     include_paths = []
62
63     if 'BASEDIR' in os.environ:
64         WINDDKdir = os.environ['BASEDIR']
65     else:
66         WINDDKdir = "C:\\WINDDK\\3790.1830"
67
68     exe_paths.append( os.path.join(WINDDKdir, 'bin') )
69     exe_paths.append( os.path.join(WINDDKdir, 'bin\\x86') )
70     include_paths.append( os.path.join(WINDDKdir, 'inc\\wxp') )
71     lib_paths.append( os.path.join(WINDDKdir, 'lib') )
72
73     include_path = string.join( include_paths, os.pathsep )
74     lib_path = string.join(lib_paths, os.pathsep )
75     exe_path = string.join(exe_paths, os.pathsep )
76     return (include_path, lib_path, exe_path)
77
78 def validate_vars(env):
79     """Validate the PCH and PCHSTOP construction variables."""
80     if env.has_key('PCH') and env['PCH']:
81         if not env.has_key('PCHSTOP'):
82             raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined."
83         if not SCons.Util.is_String(env['PCHSTOP']):
84             raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP']
85
86 def pch_emitter(target, source, env):
87     """Adds the object file target."""
88
89     validate_vars(env)
90
91     pch = None
92     obj = None
93
94     for t in target:
95         if SCons.Util.splitext(str(t))[1] == '.pch':
96             pch = t
97         if SCons.Util.splitext(str(t))[1] == '.obj':
98             obj = t
99
100     if not obj:
101         obj = SCons.Util.splitext(str(pch))[0]+'.obj'
102
103     target = [pch, obj] # pch must be first, and obj second for the PCHCOM to work
104
105     return (target, source)
106
107 def object_emitter(target, source, env, parent_emitter):
108     """Sets up the PCH dependencies for an object file."""
109
110     validate_vars(env)
111
112     parent_emitter(target, source, env)
113
114     if env.has_key('PCH') and env['PCH']:
115         env.Depends(target, env['PCH'])
116
117     return (target, source)
118
119 def static_object_emitter(target, source, env):
120     return object_emitter(target, source, env,
121                           SCons.Defaults.StaticObjectEmitter)
122
123 def shared_object_emitter(target, source, env):
124     return object_emitter(target, source, env,
125                           SCons.Defaults.SharedObjectEmitter)
126
127 pch_action = SCons.Action.Action('$PCHCOM', '$PCHCOMSTR')
128 pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch',
129                                     emitter=pch_emitter,
130                                     source_scanner=SCons.Tool.SourceFileScanner)
131 res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR')
132 res_builder = SCons.Builder.Builder(action=res_action,
133                                     src_suffix='.rc',
134                                     suffix='.res',
135                                     src_builder=[],
136                                     source_scanner=SCons.Tool.SourceFileScanner)
137 SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan)
138
139 def generate(env):
140     """Add Builders and construction variables for MSVC++ to an Environment."""
141     static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
142
143     for suffix in CSuffixes:
144         static_obj.add_action(suffix, SCons.Defaults.CAction)
145         shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
146         static_obj.add_emitter(suffix, static_object_emitter)
147         shared_obj.add_emitter(suffix, shared_object_emitter)
148
149     for suffix in CXXSuffixes:
150         static_obj.add_action(suffix, SCons.Defaults.CXXAction)
151         shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction)
152         static_obj.add_emitter(suffix, static_object_emitter)
153         shared_obj.add_emitter(suffix, shared_object_emitter)
154
155     env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}'])
156     env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'])
157     env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS'
158     env['CC']         = 'cl'
159     env['CCFLAGS']    = SCons.Util.CLVar('/nologo')
160     env['CFLAGS']     = SCons.Util.CLVar('')
161     env['CCCOM']      = '$CC $CFLAGS $CCFLAGS $CCCOMFLAGS'
162     env['SHCC']       = '$CC'
163     env['SHCCFLAGS']  = SCons.Util.CLVar('$CCFLAGS')
164     env['SHCFLAGS']   = SCons.Util.CLVar('$CFLAGS')
165     env['SHCCCOM']    = '$SHCC $SHCFLAGS $SHCCFLAGS $CCCOMFLAGS'
166     env['CXX']        = '$CC'
167     env['CXXFLAGS']   = SCons.Util.CLVar('$CCFLAGS $( /TP $)')
168     env['CXXCOM']     = '$CXX $CXXFLAGS $CCCOMFLAGS'
169     env['SHCXX']      = '$CXX'
170     env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
171     env['SHCXXCOM']   = '$SHCXX $SHCXXFLAGS $CCCOMFLAGS'
172     env['CPPDEFPREFIX']  = '/D'
173     env['CPPDEFSUFFIX']  = ''
174     env['INCPREFIX']  = '/I'
175     env['INCSUFFIX']  = ''
176 #    env.Append(OBJEMITTER = [static_object_emitter])
177 #    env.Append(SHOBJEMITTER = [shared_object_emitter])
178     env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
179
180     env['RC'] = 'rc'
181     env['RCFLAGS'] = SCons.Util.CLVar('')
182     env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES'
183     env['BUILDERS']['RES'] = res_builder
184     env['OBJPREFIX']      = ''
185     env['OBJSUFFIX']      = '.obj'
186     env['SHOBJPREFIX']    = '$OBJPREFIX'
187     env['SHOBJSUFFIX']    = '$OBJSUFFIX'
188
189     try:
190         include_path, lib_path, exe_path = get_winddk_paths(env)
191
192         # since other tools can set these, we just make sure that the
193         # relevant stuff from MSVS is in there somewhere.
194         env.PrependENVPath('INCLUDE', include_path)
195         env.PrependENVPath('LIB', lib_path)
196         env.PrependENVPath('PATH', exe_path)
197     except (SCons.Util.RegError, SCons.Errors.InternalError):
198         pass
199
200     env['CFILESUFFIX'] = '.c'
201     env['CXXFILESUFFIX'] = '.cc'
202
203     env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}'])
204     env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
205     env['BUILDERS']['PCH'] = pch_builder
206
207     env['AR']          = 'lib'
208     env['ARFLAGS']     = SCons.Util.CLVar('/nologo')
209     env['ARCOM']       = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}"
210     env['LIBPREFIX']   = ''
211     env['LIBSUFFIX']   = '.lib'
212
213     SCons.Tool.mslink.generate(env)
214
215     # See also:
216     # - WINDDK's bin/makefile.new i386mk.inc for more info.
217     # - http://alter.org.ua/docs/nt_kernel/vc8_proj/
218     env.Append(CPPDEFINES = [
219         'WIN32', 
220         '_WINDOWS', 
221         ('i386', '1'), 
222         ('_X86_', '1'), 
223         'STD_CALL', 
224         ('CONDITION_HANDLING', '1'),
225         ('NT_INST', '0'), 
226         ('_NT1X_', '100'),
227         ('WINNT', '1'),
228         ('_WIN32_WINNT', '0x0500'), # minimum required OS version
229         ('WIN32_LEAN_AND_MEAN', '1'),
230         ('DEVL', '1'),
231         ('FPO', '1'),
232     ])
233     cflags = [
234         '/GF', # Enable String Pooling
235         '/GX-', # Disable C++ Exceptions
236         '/Zp8', # 8bytes struct member alignment
237         #'/GS-', # No Buffer Security Check
238         '/GR-', # Disable Run-Time Type Info
239         '/Gz', # __stdcall Calling convention
240     ]
241     env.Append(CFLAGS = cflags)
242     env.Append(CXXFLAGS = cflags)
243     
244     env.Append(LINKFLAGS = [
245         '/DEBUG',
246         '/NODEFAULTLIB',
247         '/SUBSYSTEM:NATIVE',
248         '/INCREMENTAL:NO',
249         #'/DRIVER', 
250     
251         #'-subsystem:native,4.00',
252         '-base:0x10000',
253         
254         '-entry:DrvEnableDriver',
255     ])
256     
257     if not env.has_key('ENV'):
258         env['ENV'] = {}
259     if not env['ENV'].has_key('SystemRoot'):    # required for dlls in the winsxs folders
260         env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root()
261
262 def exists(env):
263     return env.Detect('cl')
264