3 # Copyright The SCons Foundation
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 Windows SDK functions for Microsoft Visual C/C++.
30 from ..common
import (
36 from . import Registry
38 from .Exceptions
import (
42 from . import Dispatcher
43 Dispatcher
.register_modulename(__name__
)
46 _DESKTOP
= Config
.MSVC_PLATFORM_INTERNAL
['Desktop']
47 _UWP
= Config
.MSVC_PLATFORM_INTERNAL
['UWP']
51 _DESKTOP
.vc_platform
: [],
56 def _sdk_10_layout(version
):
58 folder_prefix
= version
+ '.'
60 sdk_map
= _new_sdk_map()
62 sdk_roots
= Registry
.sdk_query_paths(version
)
64 sdk_version_platform_seen
= set()
65 sdk_roots_seen
= set()
67 for sdk_t
in sdk_roots
:
70 if sdk_root
in sdk_roots_seen
:
72 sdk_roots_seen
.add(sdk_root
)
74 if not os
.path
.exists(sdk_root
):
77 sdk_include_path
= os
.path
.join(sdk_root
, 'include')
78 if not os
.path
.exists(sdk_include_path
):
81 for version_nbr
, version_nbr_path
in Util
.listdir_dirs(sdk_include_path
):
83 if not version_nbr
.startswith(folder_prefix
):
86 sdk_inc_path
= Util
.normalize_path(os
.path
.join(version_nbr_path
, 'um'))
87 if not os
.path
.exists(sdk_inc_path
):
90 for vc_platform
, sdk_inc_file
in [
91 (_DESKTOP
.vc_platform
, 'winsdkver.h'),
92 (_UWP
.vc_platform
, 'windows.h'),
95 if not os
.path
.exists(os
.path
.join(sdk_inc_path
, sdk_inc_file
)):
98 key
= (version_nbr
, vc_platform
)
99 if key
in sdk_version_platform_seen
:
101 sdk_version_platform_seen
.add(key
)
103 sdk_map
[vc_platform
].append(version_nbr
)
105 for key
, val
in sdk_map
.items():
106 val
.sort(reverse
=True)
110 def _sdk_81_layout(version
):
112 version_nbr
= version
114 sdk_map
= _new_sdk_map()
116 sdk_roots
= Registry
.sdk_query_paths(version
)
118 sdk_version_platform_seen
= set()
119 sdk_roots_seen
= set()
121 for sdk_t
in sdk_roots
:
124 if sdk_root
in sdk_roots_seen
:
126 sdk_roots_seen
.add(sdk_root
)
128 # msvc does not check for existence of root or other files
130 sdk_inc_path
= Util
.normalize_path(os
.path
.join(sdk_root
, r
'include\um'))
131 if not os
.path
.exists(sdk_inc_path
):
134 for vc_platform
, sdk_inc_file
in [
135 (_DESKTOP
.vc_platform
, 'winsdkver.h'),
136 (_UWP
.vc_platform
, 'windows.h'),
139 if not os
.path
.exists(os
.path
.join(sdk_inc_path
, sdk_inc_file
)):
142 key
= (version_nbr
, vc_platform
)
143 if key
in sdk_version_platform_seen
:
145 sdk_version_platform_seen
.add(key
)
147 sdk_map
[vc_platform
].append(version_nbr
)
149 for key
, val
in sdk_map
.items():
150 val
.sort(reverse
=True)
157 def _reset_sdk_cache() -> None:
158 global _sdk_map_cache
164 def _sdk_10(key
, reg_version
):
165 if key
in _sdk_map_cache
:
166 sdk_map
= _sdk_map_cache
[key
]
168 sdk_map
= _sdk_10_layout(reg_version
)
169 _sdk_map_cache
[key
] = sdk_map
172 def _sdk_81(key
, reg_version
):
173 if key
in _sdk_map_cache
:
174 sdk_map
= _sdk_map_cache
[key
]
176 sdk_map
= _sdk_81_layout(reg_version
)
177 _sdk_map_cache
[key
] = sdk_map
180 def _combine_sdk_map_list(sdk_map_list
):
181 combined_sdk_map
= _new_sdk_map()
182 for sdk_map
in sdk_map_list
:
183 for key
, val
in sdk_map
.items():
184 combined_sdk_map
[key
].extend(val
)
185 return combined_sdk_map
187 _sdk_dispatch_map
= {
188 '10.0': (_sdk_10
, '10.0'),
189 '8.1': (_sdk_81
, '8.1'),
192 def _verify_sdk_dispatch_map():
194 for sdk_version
in Config
.MSVC_SDK_VERSIONS
:
195 if sdk_version
in _sdk_dispatch_map
:
197 err_msg
= f
'sdk version {sdk_version} not in sdk_dispatch_map'
198 raise MSVCInternalError(err_msg
)
201 def _version_list_sdk_map(version_list
):
203 for version
in version_list
:
204 func
, reg_version
= _sdk_dispatch_map
[version
]
205 sdk_map
= func(version
, reg_version
)
206 sdk_map_list
.append(sdk_map
)
208 combined_sdk_map
= _combine_sdk_map_list(sdk_map_list
)
209 return combined_sdk_map
211 def _sdk_map(version_list
):
212 key
= tuple(version_list
)
213 if key
in _sdk_cache
:
214 sdk_map
= _sdk_cache
[key
]
216 version_numlist
= [float(v
) for v
in version_list
]
217 version_numlist
.sort(reverse
=True)
218 key
= tuple([str(v
) for v
in version_numlist
])
219 sdk_map
= _version_list_sdk_map(key
)
220 _sdk_cache
[key
] = sdk_map
223 def get_msvc_platform(is_uwp
: bool=False):
224 platform_def
= _UWP
if is_uwp
else _DESKTOP
227 def get_sdk_version_list(vs_def
, platform_def
):
228 version_list
= vs_def
.vc_sdk_versions
if vs_def
.vc_sdk_versions
is not None else []
229 sdk_map
= _sdk_map(version_list
)
230 sdk_list
= sdk_map
.get(platform_def
.vc_platform
, [])
233 def get_msvc_sdk_version_list(msvc_version
, msvc_uwp_app
: bool=False):
234 debug('msvc_version=%s, msvc_uwp_app=%s', repr(msvc_version
), repr(msvc_uwp_app
))
238 verstr
= Util
.get_msvc_version_prefix(msvc_version
)
240 debug('msvc_version is not defined')
243 vs_def
= Config
.MSVC_VERSION_EXTERNAL
.get(verstr
, None)
245 debug('vs_def is not defined')
248 is_uwp
= True if msvc_uwp_app
in Config
.BOOLEAN_SYMBOLS
[True] else False
249 platform_def
= get_msvc_platform(is_uwp
)
250 sdk_list
= get_sdk_version_list(vs_def
, platform_def
)
252 sdk_versions
.extend(sdk_list
)
253 debug('sdk_versions=%s', repr(sdk_versions
))
261 def verify() -> None:
263 _verify_sdk_dispatch_map()