1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
14 script_dir
= os
.path
.dirname(os
.path
.realpath(__file__
))
15 chrome_src
= os
.path
.abspath(os
.path
.join(script_dir
, os
.pardir
))
16 SRC_DIR
= os
.path
.dirname(os
.path
.dirname(os
.path
.abspath(__file__
)))
17 sys
.path
.insert(1, os
.path
.join(chrome_src
, 'tools'))
18 sys
.path
.insert(0, os
.path
.join(chrome_src
, 'tools', 'gyp', 'pylib'))
24 def GetDesiredVsToolchainHashes():
25 """Load a list of SHA1s corresponding to the toolchains that we want installed
27 sha1path
= os
.path
.join(script_dir
, 'toolchain_vs2013.hash')
28 with
open(sha1path
, 'rb') as f
:
29 return f
.read().strip().splitlines()
32 def DownloadVsToolchain():
33 """Download the Visual Studio toolchain on Windows.
35 If on Windows, request that depot_tools install/update the automatic
36 toolchain, and then use it (unless opted-out) and return a tuple containing
37 the x64 and x86 paths. Otherwise return None.
39 vs2013_runtime_dll_dirs
= None
40 depot_tools_win_toolchain
= \
41 bool(int(os
.environ
.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
42 if sys
.platform
in ('win32', 'cygwin') and depot_tools_win_toolchain
:
43 import find_depot_tools
44 depot_tools_path
= find_depot_tools
.add_depot_tools_to_path()
45 temp_handle
, data_file
= tempfile
.mkstemp(suffix
='.json')
47 get_toolchain_args
= [
49 os
.path
.join(depot_tools_path
,
51 'get_toolchain_if_necessary.py'),
52 '--output-json', data_file
,
53 ] + GetDesiredVsToolchainHashes()
54 subprocess
.check_call(get_toolchain_args
)
56 with
open(data_file
, 'r') as tempf
:
57 toolchain_data
= json
.load(tempf
)
60 toolchain
= toolchain_data
['path']
61 version
= toolchain_data
['version']
62 version_is_pro
= version
[-1] != 'e'
63 win8sdk
= toolchain_data
['win8sdk']
64 wdk
= toolchain_data
['wdk']
65 # TODO(scottmg): The order unfortunately matters in these. They should be
66 # split into separate keys for x86 and x64. (See CopyVsRuntimeDlls call
67 # below). http://crbug.com/345992
68 vs2013_runtime_dll_dirs
= toolchain_data
['runtime_dirs']
70 os
.environ
['GYP_MSVS_OVERRIDE_PATH'] = toolchain
71 os
.environ
['GYP_MSVS_VERSION'] = version
72 # We need to make sure windows_sdk_path is set to the automated
73 # toolchain values in GYP_DEFINES, but don't want to override any
74 # otheroptions.express
76 gyp_defines_dict
= gyp
.NameValueListToDict(gyp
.ShlexEnv('GYP_DEFINES'))
77 gyp_defines_dict
['windows_sdk_path'] = win8sdk
78 os
.environ
['GYP_DEFINES'] = ' '.join('%s=%s' % (k
, pipes
.quote(str(v
)))
79 for k
, v
in gyp_defines_dict
.iteritems())
80 os
.environ
['WINDOWSSDKDIR'] = win8sdk
81 os
.environ
['WDK_DIR'] = wdk
82 # Include the VS runtime in the PATH in case it's not machine-installed.
83 runtime_path
= ';'.join(vs2013_runtime_dll_dirs
)
84 os
.environ
['PATH'] = runtime_path
+ ';' + os
.environ
['PATH']
85 return vs2013_runtime_dll_dirs
88 def CopyVsRuntimeDlls(output_dir
, runtime_dirs
):
89 """Copies the VS runtime DLLs from the given |runtime_dirs| to the output
90 directory so that even if not system-installed, built binaries are likely to
93 This needs to be run after gyp has been run so that the expected target
94 output directories are already created.
96 assert sys
.platform
.startswith(('win32', 'cygwin'))
98 def copy_runtime(target_dir
, source_dir
, dll_pattern
):
99 """Copy both the msvcr and msvcp runtime DLLs, only if the target doesn't
100 exist, but the target directory does exist."""
101 for which
in ('p', 'r'):
102 dll
= dll_pattern
% which
103 target
= os
.path
.join(target_dir
, dll
)
104 source
= os
.path
.join(source_dir
, dll
)
105 # If gyp generated to that output dir, and the runtime isn't already
106 # there, then copy it over.
107 if (os
.path
.isdir(target_dir
) and
108 (not os
.path
.isfile(target
) or
109 os
.stat(target
).st_mtime
!= os
.stat(source
).st_mtime
)):
110 print 'Copying %s to %s...' % (source
, target
)
111 if os
.path
.exists(target
):
113 shutil
.copy2(source
, target
)
115 x86
, x64
= runtime_dirs
116 out_debug
= os
.path
.join(output_dir
, 'Debug')
117 out_debug_nacl64
= os
.path
.join(output_dir
, 'Debug', 'x64')
118 out_release
= os
.path
.join(output_dir
, 'Release')
119 out_release_nacl64
= os
.path
.join(output_dir
, 'Release', 'x64')
120 out_debug_x64
= os
.path
.join(output_dir
, 'Debug_x64')
121 out_release_x64
= os
.path
.join(output_dir
, 'Release_x64')
123 if os
.path
.exists(out_debug
) and not os
.path
.exists(out_debug_nacl64
):
124 os
.makedirs(out_debug_nacl64
)
125 if os
.path
.exists(out_release
) and not os
.path
.exists(out_release_nacl64
):
126 os
.makedirs(out_release_nacl64
)
127 copy_runtime(out_debug
, x86
, 'msvc%s120d.dll')
128 copy_runtime(out_release
, x86
, 'msvc%s120.dll')
129 copy_runtime(out_debug_x64
, x64
, 'msvc%s120d.dll')
130 copy_runtime(out_release_x64
, x64
, 'msvc%s120.dll')
131 copy_runtime(out_debug_nacl64
, x64
, 'msvc%s120d.dll')
132 copy_runtime(out_release_nacl64
, x64
, 'msvc%s120.dll')
136 if len(sys
.argv
) < 2:
137 print >>sys
.stderr
, 'Expected either "get_toolchain_dir" or "copy_dlls"'
139 if sys
.argv
[1] == 'get_toolchain_dir':
140 DownloadVsToolchain()
141 print '["%s", "%s"]' % (
142 os
.environ
['GYP_MSVS_OVERRIDE_PATH'], os
.environ
['WINDOWSSDKDIR'])
144 print >>sys
.stderr
, 'TODO: not implemented "%s"' % sys
.argv
[1]
149 if __name__
== '__main__':