@@ -66,19 +66,22 @@ def get_clang_native_env():
6666 CACHED_CLANG_NATIVE_ENV = env
6767 return env
6868
69- # Guess where VS2015 is installed (VSINSTALLDIR env. var in VS2015 X64 Command Prompt)
69+ # VSINSTALLDIR is not in environment, so the user is not running in Visual Studio
70+ # Command Prompt. Attempt to autopopulate INCLUDE and LIB directives.
71+
72+ # Guess where Visual Studio is installed (VSINSTALLDIR env. var in VS X64 Command Prompt)
7073 if 'VSINSTALLDIR' in env :
7174 visual_studio_path = env ['VSINSTALLDIR' ]
72- elif 'VS140COMNTOOLS ' in env :
73- visual_studio_path = os .path .normpath (os .path .join (env ['VS140COMNTOOLS ' ], '../..' ))
75+ elif 'VS170COMNTOOLS ' in env :
76+ visual_studio_path = os .path .normpath (os .path .join (env ['VS170COMNTOOLS ' ], '../..' ))
7477 elif 'ProgramFiles(x86)' in env :
75- visual_studio_path = os .path .normpath (os .path .join (env ['ProgramFiles(x86)' ], 'Microsoft Visual Studio 14.0 ' ))
78+ visual_studio_path = os .path .normpath (os .path .join (env ['ProgramFiles(x86)' ], 'Microsoft Visual Studio' , '2022' , 'Community ' ))
7679 elif 'ProgramFiles' in env :
77- visual_studio_path = os .path .normpath (os .path .join (env ['ProgramFiles' ], 'Microsoft Visual Studio 14.0 ' ))
80+ visual_studio_path = os .path .normpath (os .path .join (env ['ProgramFiles' ], 'Microsoft Visual Studio' , '2022' , 'Community ' ))
7881 else :
79- visual_studio_path = 'C:\\ Program Files (x86) \\ Microsoft Visual Studio 14.0 '
82+ visual_studio_path = 'C:\\ Program Files\\ Microsoft Visual Studio\\ 2022 \\ Community '
8083 if not os .path .isdir (visual_studio_path ):
81- raise Exception ('Visual Studio 2015 was not found in "' + visual_studio_path + '"! Run in Visual Studio X64 command prompt to avoid the need to autoguess this location (or set VSINSTALLDIR env var).' )
84+ raise Exception ('Visual Studio was not found in "' + visual_studio_path + '"! Run in Visual Studio X64 command prompt to avoid the need to autoguess this location (or set VSINSTALLDIR env var).' )
8285
8386 # Guess where Program Files (x86) is located
8487 if 'ProgramFiles(x86)' in env :
@@ -92,53 +95,60 @@ def get_clang_native_env():
9295 else :
9396 raise Exception ('Unable to detect Program files directory for native Visual Studio build!' )
9497
95- # Guess where Windows 8.1 SDK is located
96- if 'WindowsSdkDir' in env :
97- windows8_sdk_dir = env ['WindowsSdkDir' ]
98- else :
99- windows8_sdk_dir = os .path .join (prog_files_x86 , 'Windows Kits' , '8.1' )
100- if not os .path .isdir (windows8_sdk_dir ):
101- raise Exception ('Windows 8.1 SDK was not found in "' + windows8_sdk_dir + '"! Run in Visual Studio command prompt to avoid the need to autoguess this location (or set WindowsSdkDir env var).' )
102-
103- # Guess where Windows 10 SDK is located
104- if os .path .isdir (os .path .join (prog_files_x86 , 'Windows Kits' , '10' )):
105- windows10_sdk_dir = os .path .join (prog_files_x86 , 'Windows Kits' , '10' )
106- if not os .path .isdir (windows10_sdk_dir ):
107- raise Exception ('Windows 10 SDK was not found in "' + windows10_sdk_dir + '"! Run in Visual Studio command prompt to avoid the need to autoguess this location.' )
98+ # Find include directory root
99+ def highest_version_subdir (path ):
100+ candidates = []
101+ for entry in os .listdir (path ):
102+ full = os .path .join (path , entry )
103+ if os .path .isdir (full ):
104+ try :
105+ candidates .append ((tuple (int (p ) for p in entry .split ('.' )), full ))
106+ except ValueError :
107+ continue
108+ if len (candidates ) == 0 :
109+ return None
110+ return max (candidates , key = lambda x : x [0 ])[1 ]
111+
112+ vc_root = os .path .join (visual_studio_path , 'VC' )
113+ vc_code_root = highest_version_subdir (os .path .join (vc_root , 'Tools' , 'MSVC' ))
114+ if not vc_code_root :
115+ raise Exception ('Unable to find Visual Studio INCLUDE root directory. Run in Visual Studio command prompt to avoid the need to autoguess this location.' )
116+
117+ windows_sdk_dir = highest_version_subdir (os .path .join (prog_files_x86 , 'Windows Kits' ))
118+ if not windows_sdk_dir :
119+ raise Exception ('Unable to find Windows SDK root directory. Run in Visual Studio command prompt to avoid the need to autoguess this location.' )
108120
109121 env .setdefault ('VSINSTALLDIR' , visual_studio_path )
110122 env .setdefault ('VCINSTALLDIR' , os .path .join (visual_studio_path , 'VC' ))
111123
112- windows10sdk_kits_include_dir = os .path .join (windows10_sdk_dir , 'Include' )
113- windows10sdk_kit_version_name = [x for x in os .listdir (windows10sdk_kits_include_dir ) if os .path .isdir (os .path .join (windows10sdk_kits_include_dir , x ))][0 ] # e.g. "10.0.10150.0" or "10.0.10240.0"
124+ windows_sdk_include_dir = highest_version_subdir (os .path .join (windows_sdk_dir , 'include' ))
125+ windows_sdk_lib_dir = highest_version_subdir (os .path .join (windows_sdk_dir , 'lib' ))
126+
127+ def append_path_item (key , path ):
128+ if not os .path .isdir (path ):
129+ logger .warning (f'VS path { path } does not exist' )
130+ return
114131
115- def append_item (key , item ):
116132 if key not in env or len (env [key ].strip ()) == 0 :
117- env [key ] = item
133+ env [key ] = path
118134 else :
119- env [key ] = env [key ] + ';' + item
120-
121- append_item ('INCLUDE' , os .path .join (env ['VCINSTALLDIR' ], 'INCLUDE' ))
122- append_item ('INCLUDE' , os .path .join (env ['VCINSTALLDIR' ], 'ATLMFC' , 'INCLUDE' ))
123- append_item ('INCLUDE' , os .path .join (windows10_sdk_dir , 'include' , windows10sdk_kit_version_name , 'ucrt' ))
124- # append_item('INCLUDE', 'C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.6.1\\include\\um') # VS2015 X64 command prompt has this, but not needed for Emscripten
125- append_item ('INCLUDE' , os .path .join (env ['VCINSTALLDIR' ], 'ATLMFC' , 'INCLUDE' ))
126- append_item ('INCLUDE' , os .path .join (windows8_sdk_dir , 'include' , 'shared' ))
127- append_item ('INCLUDE' , os .path .join (windows8_sdk_dir , 'include' , 'um' ))
128- append_item ('INCLUDE' , os .path .join (windows8_sdk_dir , 'include' , 'winrt' ))
129- logger .debug ('VS2015 native build INCLUDE: ' + env ['INCLUDE' ])
130-
131- append_item ('LIB' , os .path .join (env ['VCINSTALLDIR' ], 'LIB' , 'amd64' ))
132- append_item ('LIB' , os .path .join (env ['VCINSTALLDIR' ], 'ATLMFC' , 'LIB' , 'amd64' ))
133- append_item ('LIB' , os .path .join (windows10_sdk_dir , 'lib' , windows10sdk_kit_version_name , 'ucrt' , 'x64' ))
134- # append_item('LIB', 'C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.6.1\\lib\\um\\x64') # VS2015 X64 command prompt has this, but not needed for Emscripten
135- append_item ('LIB' , os .path .join (windows8_sdk_dir , 'lib' , 'winv6.3' , 'um' , 'x64' ))
136- logger .debug ('VS2015 native build LIB: ' + env ['LIB' ])
135+ env [key ] = env [key ] + ';' + path
137136
138- env ['PATH' ] = env ['PATH' ] + ';' + os .path .join (env ['VCINSTALLDIR' ], 'BIN' )
139- logger .debug ('VS2015 native build PATH: ' + env ['PATH' ])
137+ append_path_item ('INCLUDE' , os .path .join (vc_code_root , 'include' ))
138+ append_path_item ('INCLUDE' , os .path .join (vc_code_root , 'ATLMFC' , 'include' ))
139+ append_path_item ('INCLUDE' , os .path .join (vc_root , 'Auxiliary' , 'VS' , 'include' ))
140+ for d in ['ucrt' , 'um' , 'shared' , 'winrt' , 'cppwinrt' ]:
141+ append_path_item ('INCLUDE' , os .path .join (windows_sdk_include_dir , d ))
142+ logger .debug ('Visual Studio native build INCLUDE: ' + env ['INCLUDE' ])
143+
144+ append_path_item ('LIB' , os .path .join (vc_code_root , 'ATLMFC' , 'lib' , 'x64' ))
145+ append_path_item ('LIB' , os .path .join (vc_code_root , 'lib' , 'x64' ))
146+ append_path_item ('LIB' , os .path .join (windows_sdk_lib_dir , 'ucrt' , 'x64' ))
147+ append_path_item ('LIB' , os .path .join (windows_sdk_lib_dir , 'um' , 'x64' ))
148+ logger .debug ('Visual Studio native build LIB: ' + env ['LIB' ])
140149
141- # Current configuration above is all Visual Studio -specific, so on non-Windowses, no action needed.
150+ env ['PATH' ] = env ['PATH' ] + ';' + os .path .join (env ['VCINSTALLDIR' ], 'BIN' )
151+ logger .debug ('Visual Studio native build PATH: ' + env ['PATH' ])
142152
143153 CACHED_CLANG_NATIVE_ENV = env
144154 return env
0 commit comments