env.py 3.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# cerbero - a multi-platform build system for Open Source software
# Copyright (C) 2016 Nirbheek Chauhan <nirbheek@centricular.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

import os
import subprocess
21
from pathlib import Path
22
23
24
25
26
27

from cerbero.config import Architecture
from cerbero.errors import FatalError

# We only support Visual Studio 2015 as of now
vcvarsalls = {
28
29
30
    '14.0': [r'Microsoft Visual Studio 14.0\VC\vcvarsall.bat'],
    '15.0': [r'Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat',
             r'Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvarsall.bat'],
31
}
32
program_files = Path(os.environ['PROGRAMFILES(X86)'])
33
34

vcvarsall = None
35
36
37
38
39
for version in sorted(vcvarsalls.keys(), reverse=True):
    if vcvarsall:
        break
    for path in vcvarsalls[version]:
        path = program_files / path
40
        # Find the location of the Visual Studio installation
41
42
        if path.is_file():
            vcvarsall = path.as_posix()
43
44
45
            break
if not vcvarsall:
    versions = ', '.join(vcvarsalls.keys())
46
    raise FatalError('Microsoft Visual Studio not found, please file a bug. We looked for: ' + versions)
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

def append_path(var, path, sep=';'):
    if var and not var.endswith(sep):
        var += sep
    if path and not path.endswith(sep):
        path += sep
    var += path
    return var

def get_vcvarsall_arg(arch, target_arch):
    if target_arch == Architecture.X86:
        # If arch is x86_64, this will cause the WOW64 version of MSVC to be
        # used, which is how most people compile 32-bit apps on 64-bit.
        return 'x86'
    if arch == Architecture.X86:
        if target_arch == Architecture.X86_64:
            return 'x86_amd64'
        elif target_arch.is_arm():
            return 'x86_arm'
    elif arch == Architecture.X86_64:
        if target_arch == Architecture.X86_64:
            return 'amd64'
        elif target_arch.is_arm():
            return 'amd64_arm'
    elif arch.is_arm() and target_arch.is_arm():
            return 'arm'
    raise FatalError('Unsupported arch/target_arch: {0}/{1}'.format(arch, target_arch))

def run_and_get_env(cmd):
76
77
78
79
80
81
82
83
84
85
    env = os.environ.copy()
    env['VSCMD_ARG_no_logo'] = '1'
    env['VSCMD_DEBUG'] = ''
    output = subprocess.check_output(cmd, shell=True, env=env,
                                     universal_newlines=True)
    lines = []
    for line in output.split('\n'):
        if '=' in line:
            lines.append(line)
    return lines
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

def get_msvc_env(vcvarsall, arch, target_arch):
    ret_env = {}
    if not os.path.isfile(vcvarsall):
        raise FatalError("'{0}' not found".format(vcvarsall))

    without_msvc = run_and_get_env('set')
    arg = get_vcvarsall_arg(arch, target_arch)
    vcvars_env_cmd = '"{0}" {1} & {2}'.format(vcvarsall, arg, 'set')
    with_msvc = run_and_get_env(vcvars_env_cmd)

    for each in set(with_msvc) - set(without_msvc):
        (var, value) = each.split('=', 1)
        ret_env[var] = value
    return ret_env