1 """SCons.Platform.win32
2
3 Platform-specific initialization for Win32 systems.
4
5 There normally shouldn't be any need to import this module directly. It
6 will usually be imported through the generic SCons.Platform.Platform()
7 selection method.
8 """
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 __revision__ = "src/engine/SCons/Platform/win32.py bee7caf9defd6e108fc2998a2520ddb36a967691 2019-12-17 02:07:09 bdeegan"
34
35 import os
36 import os.path
37 import sys
38 import tempfile
39
40 from SCons.Platform.posix import exitvalmap
41 from SCons.Platform import TempFileMunge
42 from SCons.Platform.virtualenv import ImportVirtualenv
43 from SCons.Platform.virtualenv import ignore_virtualenv, enable_virtualenv
44 import SCons.Util
45
46 CHOCO_DEFAULT_PATH = [
47 r'C:\ProgramData\chocolatey\bin'
48 ]
49
50 try:
51 import msvcrt
52 import win32api
53 import win32con
54 except ImportError:
55 parallel_msg = \
56 "you do not seem to have the pywin32 extensions installed;\n" + \
57 "\tparallel (-j) builds may not work reliably with open Python files."
58 except AttributeError:
59 parallel_msg = \
60 "your pywin32 extensions do not support file handle operations;\n" + \
61 "\tparallel (-j) builds may not work reliably with open Python files."
62 else:
63 parallel_msg = None
64
65 if sys.version_info.major == 2:
66 import __builtin__
67
68 _builtin_file = __builtin__.file
69 _builtin_open = __builtin__.open
70
72 """Adjust 'mode' to mark handle as non-inheritable.
73
74 SCons is multithreaded, so allowing handles to be inherited by
75 children opens us up to races, where (e.g.) processes spawned by
76 the Taskmaster may inherit and retain references to files opened
77 by other threads. This may lead to sharing violations and,
78 ultimately, build failures.
79
80 By including 'N' as part of fopen's 'mode' parameter, all file
81 handles returned from these functions are atomically marked as
82 non-inheritable.
83 """
84 if not mode:
85
86
87 mode = 'rN'
88 elif 'N' not in mode:
89 mode += 'N'
90 return mode
91
93 - def __init__(self, name, mode=None, *args, **kwargs):
96
100
101 __builtin__.file = _scons_file
102 __builtin__.open = _scons_open
103
104
105
106 if False:
107
108 try:
109 from ctypes import windll
110 import shutil
111
112 CopyFile = windll.kernel32.CopyFileA
113 SetFileTime = windll.kernel32.SetFileTime
114
115 _shutil_copy = shutil.copy
116 _shutil_copy2 = shutil.copy2
117
118 shutil.copy2 = CopyFile
119
123
124 shutil.copy = win_api_copyfile
125
126 except AttributeError:
127 parallel_msg = \
128 "Couldn't override shutil.copy or shutil.copy2 falling back to shutil defaults"
129
130
131
132
133
134
135
136 try:
137 import threading
138 spawn_lock = threading.Lock()
139
140
141
142
143
144
145
146 - def spawnve(mode, file, args, env):
147 spawn_lock.acquire()
148 try:
149 if mode == os.P_WAIT:
150 ret = os.spawnve(os.P_NOWAIT, file, args, env)
151 else:
152 ret = os.spawnve(mode, file, args, env)
153 finally:
154 spawn_lock.release()
155 if mode == os.P_WAIT:
156 pid, status = os.waitpid(ret, 0)
157 ret = status >> 8
158 return ret
159 except ImportError:
160
161
162
163
164
165
166 - def spawnve(mode, file, args, env):
168
169
170
171
172
173
174 -def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
175
176
177
178
179
180
181 if not sh:
182 sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?\n")
183 return 127
184 else:
185
186 tmpFileStdout = os.path.normpath(tempfile.mktemp())
187 tmpFileStderr = os.path.normpath(tempfile.mktemp())
188
189
190 stdoutRedirected = 0
191 stderrRedirected = 0
192 for arg in args:
193
194 if arg.find( ">", 0, 1 ) != -1 or arg.find( "1>", 0, 2 ) != -1:
195 stdoutRedirected = 1
196
197 if arg.find( "2>", 0, 2 ) != -1:
198 stderrRedirected = 1
199
200
201 if stdoutRedirected == 0:
202 args.append(">" + str(tmpFileStdout))
203 if stderrRedirected == 0:
204 args.append("2>" + str(tmpFileStderr))
205
206
207 try:
208 args = [sh, '/C', escape(' '.join(args))]
209 ret = spawnve(os.P_WAIT, sh, args, env)
210 except OSError as e:
211
212 try:
213 ret = exitvalmap[e.errno]
214 except KeyError:
215 sys.stderr.write("scons: unknown OSError exception code %d - %s: %s\n" % (e.errno, cmd, e.strerror))
216 if stderr is not None:
217 stderr.write("scons: %s: %s\n" % (cmd, e.strerror))
218
219
220 if stdout is not None and stdoutRedirected == 0:
221 try:
222 with open(tmpFileStdout, "r" ) as tmp:
223 stdout.write(tmp.read())
224 os.remove(tmpFileStdout)
225 except (IOError, OSError):
226 pass
227
228 if stderr is not None and stderrRedirected == 0:
229 try:
230 with open(tmpFileStderr, "r" ) as tmp:
231 stderr.write(tmp.read())
232 os.remove(tmpFileStderr)
233 except (IOError, OSError):
234 pass
235 return ret
236
237
239 try:
240 result = spawnve(os.P_WAIT, l[0], l, env)
241 except (OSError, EnvironmentError) as e:
242 try:
243 result = exitvalmap[e.errno]
244 sys.stderr.write("scons: %s: %s\n" % (l[0], e.strerror))
245 except KeyError:
246 result = 127
247 if len(l) > 2:
248 if len(l[2]) < 1000:
249 command = ' '.join(l[0:3])
250 else:
251 command = l[0]
252 else:
253 command = l[0]
254 sys.stderr.write("scons: unknown OSError exception code %d - '%s': %s\n" % (e.errno, command, e.strerror))
255 return result
256
257
258 -def spawn(sh, escape, cmd, args, env):
259 if not sh:
260 sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?\n")
261 return 127
262 return exec_spawn([sh, '/C', escape(' '.join(args))], env)
263
264
265
266
267
268
270 if x[-1] == '\\':
271 x = x + '\\'
272 return '"' + x + '"'
273
274
275 _system_root = None
276
277
308
309
335
336
338 """
339 Determine which windows CPU were running on.
340 A class for defining architecture-specific settings and logic.
341 """
345
346 SupportedArchitectureList = [
347 ArchDefinition(
348 'x86',
349 ['i386', 'i486', 'i586', 'i686'],
350 ),
351
352 ArchDefinition(
353 'x86_64',
354 ['AMD64', 'amd64', 'em64t', 'EM64T', 'x86_64'],
355 ),
356
357 ArchDefinition(
358 'ia64',
359 ['IA64'],
360 ),
361 ]
362
363 SupportedArchitectureMap = {}
364 for a in SupportedArchitectureList:
365 SupportedArchitectureMap[a.arch] = a
366 for s in a.synonyms:
367 SupportedArchitectureMap[s] = a
368
369
371 """Returns the definition for the specified architecture string.
372
373 If no string is specified, the system default is returned (as defined
374 by the PROCESSOR_ARCHITEW6432 or PROCESSOR_ARCHITECTURE environment
375 variables).
376 """
377 if arch is None:
378 arch = os.environ.get('PROCESSOR_ARCHITEW6432')
379 if not arch:
380 arch = os.environ.get('PROCESSOR_ARCHITECTURE')
381 return SupportedArchitectureMap.get(arch, ArchDefinition('', ['']))
382
383
385
386
387 cmd_interp = ''
388
389 if SCons.Util.can_read_reg:
390 try:
391
392 k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE,
393 'Software\\Microsoft\\Windows NT\\CurrentVersion')
394 val, tok = SCons.Util.RegQueryValueEx(k, 'SystemRoot')
395 cmd_interp = os.path.join(val, 'System32\\cmd.exe')
396 except SCons.Util.RegError:
397 try:
398
399 k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE,
400 'Software\\Microsoft\\Windows\\CurrentVersion')
401 val, tok = SCons.Util.RegQueryValueEx(k, 'SystemRoot')
402 cmd_interp = os.path.join(val, 'command.com')
403 except KeyboardInterrupt:
404 raise
405 except:
406 pass
407
408
409
410
411
412
413 if not cmd_interp:
414 systemroot = get_system_root()
415 tmp_path = systemroot + os.pathsep + \
416 os.path.join(systemroot,'System32')
417 tmp_pathext = '.com;.exe;.bat;.cmd'
418 if 'PATHEXT' in os.environ:
419 tmp_pathext = os.environ['PATHEXT']
420 cmd_interp = SCons.Util.WhereIs('cmd', tmp_path, tmp_pathext)
421 if not cmd_interp:
422 cmd_interp = SCons.Util.WhereIs('command', tmp_path, tmp_pathext)
423
424 if not cmd_interp:
425 cmd_interp = env.Detect('cmd')
426 if not cmd_interp:
427 cmd_interp = env.Detect('command')
428
429 if 'ENV' not in env:
430 env['ENV'] = {}
431
432
433
434
435
436
437
438
439
440 import_env = ['SystemDrive', 'SystemRoot', 'TEMP', 'TMP' ]
441 for var in import_env:
442 v = os.environ.get(var)
443 if v:
444 env['ENV'][var] = v
445
446 if 'COMSPEC' not in env['ENV']:
447 v = os.environ.get("COMSPEC")
448 if v:
449 env['ENV']['COMSPEC'] = v
450
451 env.AppendENVPath('PATH', get_system_root() + '\\System32')
452
453 env['ENV']['PATHEXT'] = '.COM;.EXE;.BAT;.CMD'
454 env['OBJPREFIX'] = ''
455 env['OBJSUFFIX'] = '.obj'
456 env['SHOBJPREFIX'] = '$OBJPREFIX'
457 env['SHOBJSUFFIX'] = '$OBJSUFFIX'
458 env['PROGPREFIX'] = ''
459 env['PROGSUFFIX'] = '.exe'
460 env['LIBPREFIX'] = ''
461 env['LIBSUFFIX'] = '.lib'
462 env['SHLIBPREFIX'] = ''
463 env['SHLIBSUFFIX'] = '.dll'
464 env['LIBPREFIXES'] = [ '$LIBPREFIX' ]
465 env['LIBSUFFIXES'] = [ '$LIBSUFFIX' ]
466 env['PSPAWN'] = piped_spawn
467 env['SPAWN'] = spawn
468 env['SHELL'] = cmd_interp
469 env['TEMPFILE'] = TempFileMunge
470 env['TEMPFILEPREFIX'] = '@'
471 env['MAXLINELENGTH'] = 2048
472 env['ESCAPE'] = escape
473
474 env['HOST_OS'] = 'win32'
475 env['HOST_ARCH'] = get_architecture().arch
476
477 if enable_virtualenv and not ignore_virtualenv:
478 ImportVirtualenv(env)
479
480
481
482
483
484
485
486