~ubuntu-branches/ubuntu/trusty/blender/trusty-proposed

« back to all changes in this revision

Viewing changes to scons/scons-local/SCons/Tool/MSCommon/vc.py

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2013-08-14 10:43:49 UTC
  • mfrom: (14.2.19 sid)
  • Revision ID: package-import@ubuntu.com-20130814104349-t1d5mtwkphp12dyj
Tags: 2.68a-3
* Upload to unstable
* debian/: python3.3 Depends simplified
  - debian/control: python3.3 Depends dropped
    for blender-data package
  - 0001-blender_thumbnailer.patch refreshed
* debian/control: libavcodec b-dep versioning dropped

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 The SCons Foundation
 
3
#
 
4
# Permission is hereby granted, free of charge, to any person obtaining
 
5
# a copy of this software and associated documentation files (the
 
6
# "Software"), to deal in the Software without restriction, including
 
7
# without limitation the rights to use, copy, modify, merge, publish,
 
8
# distribute, sublicense, and/or sell copies of the Software, and to
 
9
# permit persons to whom the Software is furnished to do so, subject to
 
10
# the following conditions:
 
11
#
 
12
# The above copyright notice and this permission notice shall be included
 
13
# in all copies or substantial portions of the Software.
 
14
#
 
15
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
 
16
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 
17
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
18
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 
19
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
20
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
21
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
22
#
 
23
 
 
24
# TODO:
 
25
#   * supported arch for versions: for old versions of batch file without
 
26
#     argument, giving bogus argument cannot be detected, so we have to hardcode
 
27
#     this here
 
28
#   * print warning when msvc version specified but not found
 
29
#   * find out why warning do not print
 
30
#   * test on 64 bits XP +  VS 2005 (and VS 6 if possible)
 
31
#   * SDK
 
32
#   * Assembly
 
33
__revision__ = "src/engine/SCons/Tool/MSCommon/vc.py  2013/03/03 09:48:35 garyo"
 
34
 
 
35
__doc__ = """Module for Visual C/C++ detection and configuration.
 
36
"""
 
37
import SCons.compat
 
38
 
 
39
import os
 
40
import platform
 
41
from string import digits as string_digits
 
42
 
 
43
import SCons.Warnings
 
44
 
 
45
import common
 
46
 
 
47
debug = common.debug
 
48
 
 
49
import sdk
 
50
 
 
51
get_installed_sdks = sdk.get_installed_sdks
 
52
 
 
53
 
 
54
class VisualCException(Exception):
 
55
    pass
 
56
 
 
57
class UnsupportedVersion(VisualCException):
 
58
    pass
 
59
 
 
60
class UnsupportedArch(VisualCException):
 
61
    pass
 
62
 
 
63
class MissingConfiguration(VisualCException):
 
64
    pass
 
65
 
 
66
class NoVersionFound(VisualCException):
 
67
    pass
 
68
 
 
69
class BatchFileExecutionError(VisualCException):
 
70
    pass
 
71
 
 
72
# Dict to 'canonalize' the arch
 
73
_ARCH_TO_CANONICAL = {
 
74
    "amd64"     : "amd64",
 
75
    "emt64"     : "amd64",
 
76
    "i386"      : "x86",
 
77
    "i486"      : "x86",
 
78
    "i586"      : "x86",
 
79
    "i686"      : "x86",
 
80
    "ia64"      : "ia64",
 
81
    "itanium"   : "ia64",
 
82
    "x86"       : "x86",
 
83
    "x86_64"    : "amd64",
 
84
}
 
85
 
 
86
# Given a (host, target) tuple, return the argument for the bat file. Both host
 
87
# and targets should be canonalized.
 
88
_HOST_TARGET_ARCH_TO_BAT_ARCH = {
 
89
    ("x86", "x86"): "x86",
 
90
    ("x86", "amd64"): "x86_amd64",
 
91
    ("amd64", "amd64"): "amd64",
 
92
    ("amd64", "x86"): "x86",
 
93
    ("x86", "ia64"): "x86_ia64"
 
94
}
 
95
 
 
96
def get_host_target(env):
 
97
    debug('vc.py:get_host_target()')
 
98
 
 
99
    host_platform = env.get('HOST_ARCH')
 
100
    if not host_platform:
 
101
        host_platform = platform.machine()
 
102
        # TODO(2.5):  the native Python platform.machine() function returns
 
103
        # '' on all Python versions before 2.6, after which it also uses
 
104
        # PROCESSOR_ARCHITECTURE.
 
105
        if not host_platform:
 
106
            host_platform = os.environ.get('PROCESSOR_ARCHITECTURE', '')
 
107
            
 
108
    # Retain user requested TARGET_ARCH
 
109
    req_target_platform = env.get('TARGET_ARCH')
 
110
    debug('vc.py:get_host_target() req_target_platform:%s'%req_target_platform)
 
111
 
 
112
    if  req_target_platform:
 
113
        # If user requested a specific platform then only try that one.
 
114
        target_platform = req_target_platform
 
115
    else:
 
116
        target_platform = host_platform
 
117
        
 
118
    try:
 
119
        host = _ARCH_TO_CANONICAL[host_platform.lower()]
 
120
    except KeyError, e:
 
121
        msg = "Unrecognized host architecture %s"
 
122
        raise ValueError(msg % repr(host_platform))
 
123
 
 
124
    try:
 
125
        target = _ARCH_TO_CANONICAL[target_platform.lower()]
 
126
    except KeyError, e:
 
127
        all_archs = str(_ARCH_TO_CANONICAL.keys())
 
128
        raise ValueError("Unrecognized target architecture %s\n\tValid architectures: %s" % (target_platform, all_archs))
 
129
 
 
130
    return (host, target,req_target_platform)
 
131
 
 
132
_VCVER = ["11.0", "11.0Exp", "10.0", "10.0Exp", "9.0", "9.0Exp","8.0", "8.0Exp","7.1", "7.0", "6.0"]
 
133
 
 
134
_VCVER_TO_PRODUCT_DIR = {
 
135
        '11.0': [
 
136
            r'Microsoft\VisualStudio\11.0\Setup\VC\ProductDir'],
 
137
        '11.0Exp' : [
 
138
            r'Microsoft\VCExpress\11.0\Setup\VC\ProductDir'],
 
139
        '10.0': [
 
140
            r'Microsoft\VisualStudio\10.0\Setup\VC\ProductDir'],
 
141
        '10.0Exp' : [
 
142
            r'Microsoft\VCExpress\10.0\Setup\VC\ProductDir'],
 
143
        '9.0': [
 
144
            r'Microsoft\VisualStudio\9.0\Setup\VC\ProductDir'],
 
145
        '9.0Exp' : [
 
146
            r'Microsoft\VCExpress\9.0\Setup\VC\ProductDir'],
 
147
        '8.0': [
 
148
            r'Microsoft\VisualStudio\8.0\Setup\VC\ProductDir'],
 
149
        '8.0Exp': [
 
150
            r'Microsoft\VCExpress\8.0\Setup\VC\ProductDir'],
 
151
        '7.1': [
 
152
            r'Microsoft\VisualStudio\7.1\Setup\VC\ProductDir'],
 
153
        '7.0': [
 
154
            r'Microsoft\VisualStudio\7.0\Setup\VC\ProductDir'],
 
155
        '6.0': [
 
156
            r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir']
 
157
}
 
158
        
 
159
def msvc_version_to_maj_min(msvc_version):
 
160
   msvc_version_numeric = ''.join([x for  x in msvc_version if x in string_digits + '.'])
 
161
 
 
162
   t = msvc_version_numeric.split(".")
 
163
   if not len(t) == 2:
 
164
       raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
 
165
   try:
 
166
       maj = int(t[0])
 
167
       min = int(t[1])
 
168
       return maj, min
 
169
   except ValueError, e:
 
170
       raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
 
171
 
 
172
def is_host_target_supported(host_target, msvc_version):
 
173
    """Return True if the given (host, target) tuple is supported given the
 
174
    msvc version.
 
175
 
 
176
    Parameters
 
177
    ----------
 
178
    host_target: tuple
 
179
        tuple of (canonalized) host-target, e.g. ("x86", "amd64") for cross
 
180
        compilation from 32 bits windows to 64 bits.
 
181
    msvc_version: str
 
182
        msvc version (major.minor, e.g. 10.0)
 
183
 
 
184
    Note
 
185
    ----
 
186
    This only check whether a given version *may* support the given (host,
 
187
    target), not that the toolchain is actually present on the machine.
 
188
    """
 
189
    # We assume that any Visual Studio version supports x86 as a target
 
190
    if host_target[1] != "x86":
 
191
        maj, min = msvc_version_to_maj_min(msvc_version)
 
192
        if maj < 8:
 
193
            return False
 
194
 
 
195
    return True
 
196
 
 
197
def find_vc_pdir(msvc_version):
 
198
    """Try to find the product directory for the given
 
199
    version.
 
200
 
 
201
    Note
 
202
    ----
 
203
    If for some reason the requested version could not be found, an
 
204
    exception which inherits from VisualCException will be raised."""
 
205
    root = 'Software\\'
 
206
    if common.is_win64():
 
207
        root = root + 'Wow6432Node\\'
 
208
    try:
 
209
        hkeys = _VCVER_TO_PRODUCT_DIR[msvc_version]
 
210
    except KeyError:
 
211
        debug("Unknown version of MSVC: %s" % msvc_version)
 
212
        raise UnsupportedVersion("Unknown version %s" % msvc_version)
 
213
 
 
214
    for key in hkeys:
 
215
        key = root + key
 
216
        try:
 
217
            comps = common.read_reg(key)
 
218
        except WindowsError, e:
 
219
            debug('find_vc_dir(): no VC registry key %s' % repr(key))
 
220
        else:
 
221
            debug('find_vc_dir(): found VC in registry: %s' % comps)
 
222
            if os.path.exists(comps):
 
223
                return comps
 
224
            else:
 
225
                debug('find_vc_dir(): reg says dir is %s, but it does not exist. (ignoring)'\
 
226
                          % comps)
 
227
                raise MissingConfiguration("registry dir %s not found on the filesystem" % comps)
 
228
    return None
 
229
 
 
230
def find_batch_file(env,msvc_version,host_arch,target_arch):
 
231
    """
 
232
    Find the location of the batch script which should set up the compiler
 
233
    for any TARGET_ARCH whose compilers were installed by Visual Studio/VCExpress
 
234
    """
 
235
    pdir = find_vc_pdir(msvc_version)
 
236
    if pdir is None:
 
237
        raise NoVersionFound("No version of Visual Studio found")
 
238
        
 
239
    debug('vc.py: find_batch_file() pdir:%s'%pdir)
 
240
 
 
241
    # filter out e.g. "Exp" from the version name
 
242
    msvc_ver_numeric = ''.join([x for x in msvc_version if x in string_digits + "."])
 
243
    vernum = float(msvc_ver_numeric)
 
244
    if 7 <= vernum < 8:
 
245
        pdir = os.path.join(pdir, os.pardir, "Common7", "Tools")
 
246
        batfilename = os.path.join(pdir, "vsvars32.bat")
 
247
    elif vernum < 7:
 
248
        pdir = os.path.join(pdir, "Bin")
 
249
        batfilename = os.path.join(pdir, "vcvars32.bat")
 
250
    else: # >= 8
 
251
        batfilename = os.path.join(pdir, "vcvarsall.bat")
 
252
 
 
253
    if not os.path.exists(batfilename):
 
254
        debug("Not found: %s" % batfilename)
 
255
        batfilename = None
 
256
    
 
257
    installed_sdks=get_installed_sdks()
 
258
    for _sdk in installed_sdks:
 
259
        sdk_bat_file=_sdk.get_sdk_vc_script(host_arch,target_arch)
 
260
        sdk_bat_file_path=os.path.join(pdir,sdk_bat_file)
 
261
        debug('vc.py:find_batch_file() sdk_bat_file_path:%s'%sdk_bat_file_path)
 
262
        if os.path.exists(sdk_bat_file_path):
 
263
            return (batfilename,sdk_bat_file_path)
 
264
        else:
 
265
            debug("vc.py:find_batch_file() not found:%s"%sdk_bat_file_path)
 
266
    else:
 
267
        return (batfilename,None)
 
268
 
 
269
__INSTALLED_VCS_RUN = None
 
270
 
 
271
def cached_get_installed_vcs():
 
272
    global __INSTALLED_VCS_RUN
 
273
 
 
274
    if __INSTALLED_VCS_RUN is None:
 
275
        ret = get_installed_vcs()
 
276
        __INSTALLED_VCS_RUN = ret
 
277
 
 
278
    return __INSTALLED_VCS_RUN
 
279
 
 
280
def get_installed_vcs():
 
281
    installed_versions = []
 
282
    for ver in _VCVER:
 
283
        debug('trying to find VC %s' % ver)
 
284
        try:
 
285
            if find_vc_pdir(ver):
 
286
                debug('found VC %s' % ver)
 
287
                installed_versions.append(ver)
 
288
            else:
 
289
                debug('find_vc_pdir return None for ver %s' % ver)
 
290
        except VisualCException, e:
 
291
            debug('did not find VC %s: caught exception %s' % (ver, str(e)))
 
292
    return installed_versions
 
293
 
 
294
def reset_installed_vcs():
 
295
    """Make it try again to find VC.  This is just for the tests."""
 
296
    __INSTALLED_VCS_RUN = None
 
297
 
 
298
def script_env(script, args=None):
 
299
    stdout = common.get_output(script, args)
 
300
    # Stupid batch files do not set return code: we take a look at the
 
301
    # beginning of the output for an error message instead
 
302
    olines = stdout.splitlines()
 
303
    if olines[0].startswith("The specified configuration type is missing"):
 
304
        raise BatchFileExecutionError("\n".join(olines[:2]))
 
305
 
 
306
    return common.parse_output(stdout)
 
307
 
 
308
def get_default_version(env):
 
309
    debug('get_default_version()')
 
310
 
 
311
    msvc_version = env.get('MSVC_VERSION')
 
312
    msvs_version = env.get('MSVS_VERSION')
 
313
    
 
314
    debug('get_default_version(): msvc_version:%s msvs_version:%s'%(msvc_version,msvs_version))
 
315
 
 
316
    if msvs_version and not msvc_version:
 
317
        SCons.Warnings.warn(
 
318
                SCons.Warnings.DeprecatedWarning,
 
319
                "MSVS_VERSION is deprecated: please use MSVC_VERSION instead ")
 
320
        return msvs_version
 
321
    elif msvc_version and msvs_version:
 
322
        if not msvc_version == msvs_version:
 
323
            SCons.Warnings.warn(
 
324
                    SCons.Warnings.VisualVersionMismatch,
 
325
                    "Requested msvc version (%s) and msvs version (%s) do " \
 
326
                    "not match: please use MSVC_VERSION only to request a " \
 
327
                    "visual studio version, MSVS_VERSION is deprecated" \
 
328
                    % (msvc_version, msvs_version))
 
329
        return msvs_version
 
330
    if not msvc_version:
 
331
        installed_vcs = cached_get_installed_vcs()
 
332
        debug('installed_vcs:%s' % installed_vcs)
 
333
        if not installed_vcs:
 
334
            #msg = 'No installed VCs'
 
335
            #debug('msv %s\n' % repr(msg))
 
336
            #SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg)
 
337
            debug('msvc_setup_env: No installed VCs')
 
338
            return None
 
339
        msvc_version = installed_vcs[0]
 
340
        debug('msvc_setup_env: using default installed MSVC version %s\n' % repr(msvc_version))
 
341
 
 
342
    return msvc_version
 
343
 
 
344
def msvc_setup_env_once(env):
 
345
    try:
 
346
        has_run  = env["MSVC_SETUP_RUN"]
 
347
    except KeyError:
 
348
        has_run = False
 
349
 
 
350
    if not has_run:
 
351
        msvc_setup_env(env)
 
352
        env["MSVC_SETUP_RUN"] = True
 
353
 
 
354
def msvc_find_valid_batch_script(env,version):
 
355
    debug('vc.py:msvc_find_valid_batch_script()')
 
356
    # Find the host platform, target platform, and if present the requested
 
357
    # target platform
 
358
    (host_platform, target_platform,req_target_platform) = get_host_target(env)
 
359
 
 
360
    # If the user hasn't specifically requested a TARGET_ARCH, and
 
361
    # The TARGET_ARCH is amd64 then also try 32 bits if there are no viable
 
362
    # 64 bit tools installed
 
363
    try_target_archs = [target_platform]
 
364
    if not req_target_platform and target_platform in ('amd64','x86_64'):
 
365
        try_target_archs.append('x86')
 
366
 
 
367
    d = None
 
368
    for tp in try_target_archs:
 
369
        # Set to current arch.
 
370
        env['TARGET_ARCH']=tp
 
371
        
 
372
        debug("vc.py:msvc_find_valid_batch_script() trying target_platform:%s"%tp)
 
373
        host_target = (host_platform, tp)
 
374
        if not is_host_target_supported(host_target, version):
 
375
            warn_msg = "host, target = %s not supported for MSVC version %s" % \
 
376
                (host_target, version)
 
377
            SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
 
378
        arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[host_target]
 
379
        
 
380
        # Try to locate a batch file for this host/target platform combo
 
381
        try:
 
382
            (vc_script,sdk_script) = find_batch_file(env,version,host_platform,tp)
 
383
            debug('vc.py:msvc_find_valid_batch_script() vc_script:%s sdk_script:%s'%(vc_script,sdk_script))
 
384
        except VisualCException, e:
 
385
            msg = str(e)
 
386
            debug('Caught exception while looking for batch file (%s)' % msg)
 
387
            warn_msg = "VC version %s not installed.  " + \
 
388
                       "C/C++ compilers are most likely not set correctly.\n" + \
 
389
                       " Installed versions are: %s"
 
390
            warn_msg = warn_msg % (version, cached_get_installed_vcs())
 
391
            SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
 
392
            continue
 
393
        
 
394
        # Try to use the located batch file for this host/target platform combo
 
395
        debug('vc.py:msvc_find_valid_batch_script() use_script 2 %s, args:%s\n' % (repr(vc_script), arg))
 
396
        if vc_script:
 
397
            try:
 
398
                d = script_env(vc_script, args=arg)
 
399
            except BatchFileExecutionError, e:
 
400
                debug('vc.py:msvc_find_valid_batch_script() use_script 3: failed running VC script %s: %s: Error:%s'%(repr(vc_script),arg,e))
 
401
                vc_script=None
 
402
        if not vc_script and sdk_script:
 
403
            debug('vc.py:msvc_find_valid_batch_script() use_script 4: trying sdk script: %s'%(sdk_script))
 
404
            try:
 
405
                d = script_env(sdk_script,args=[])
 
406
            except BatchFileExecutionError,e:
 
407
                debug('vc.py:msvc_find_valid_batch_script() use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script),e))
 
408
                continue
 
409
        elif not vc_script and not sdk_script:
 
410
            debug('vc.py:msvc_find_valid_batch_script() use_script 6: Neither VC script nor SDK script found')
 
411
            continue
 
412
    
 
413
    # If we cannot find a viable installed compiler, reset the TARGET_ARCH
 
414
    # To it's initial value
 
415
    if not d:
 
416
        env['TARGET_ARCH']=req_target_platform
 
417
    
 
418
    return d
 
419
    
 
420
 
 
421
def msvc_setup_env(env):
 
422
    debug('msvc_setup_env()')
 
423
 
 
424
    version = get_default_version(env)
 
425
    if version is None:
 
426
        warn_msg = "No version of Visual Studio compiler found - C/C++ " \
 
427
                   "compilers most likely not set correctly"
 
428
        SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
 
429
        return None
 
430
    debug('msvc_setup_env: using specified MSVC version %s\n' % repr(version))
 
431
 
 
432
    # XXX: we set-up both MSVS version for backward
 
433
    # compatibility with the msvs tool
 
434
    env['MSVC_VERSION'] = version
 
435
    env['MSVS_VERSION'] = version
 
436
    env['MSVS'] = {}
 
437
 
 
438
    
 
439
    use_script = env.get('MSVC_USE_SCRIPT', True)
 
440
    if SCons.Util.is_String(use_script):
 
441
        debug('vc.py:msvc_setup_env() use_script 1 %s\n' % repr(use_script))
 
442
        d = script_env(use_script)
 
443
    elif use_script:      
 
444
        d = msvc_find_valid_batch_script(env,version)
 
445
        debug('vc.py:msvc_setup_env() use_script 2 %s\n' % d)
 
446
        if not d:
 
447
            return d
 
448
    else:
 
449
        debug('MSVC_USE_SCRIPT set to False')
 
450
        warn_msg = "MSVC_USE_SCRIPT set to False, assuming environment " \
 
451
                   "set correctly."
 
452
        SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
 
453
        return None
 
454
 
 
455
    for k, v in d.items():
 
456
        debug('vc.py:msvc_setup_env() env:%s -> %s'%(k,v))
 
457
        env.PrependENVPath(k, v, delete_existing=True)
 
458
 
 
459
def msvc_exists(version=None):
 
460
    vcs = cached_get_installed_vcs()
 
461
    if version is None:
 
462
        return len(vcs) > 0
 
463
    return version in vcs
 
464