@@ -25,6 +25,8 @@ import { Readable } from 'stream';
25
25
import * as nls from 'vscode-nls' ;
26
26
import { CppBuildTaskProvider } from './cppBuildTaskProvider' ;
27
27
import { UpdateInsidersAccess } from '../main' ;
28
+ import { PlatformInformation } from '../platform' ;
29
+ import * as semver from 'semver' ;
28
30
29
31
nls . config ( { messageFormat : nls . MessageFormat . bundle , bundleFormat : nls . BundleFormat . standalone } ) ( ) ;
30
32
const localize : nls . LocalizeFunc = nls . loadMessageBundle ( ) ;
@@ -155,11 +157,85 @@ function sendActivationTelemetry(): void {
155
157
telemetry . logLanguageServerEvent ( "Activate" , activateEvent ) ;
156
158
}
157
159
160
+ async function checkVsixCompatibility ( ) : Promise < void > {
161
+ // Check to ensure the correct platform-specific VSIX was installed.
162
+ const vsixManifestPath : string = path . join ( util . extensionPath , ".vsixmanifest" ) ;
163
+ // Skip the check if the file does not exist, such as when debugging cpptools.
164
+ if ( await util . checkFileExists ( vsixManifestPath ) ) {
165
+ const content : string = await util . readFileText ( vsixManifestPath ) ;
166
+ const matches : RegExpMatchArray | null = content . match ( / T a r g e t P l a t f o r m = " (?< platform > [ ^ " ] * ) " / ) ;
167
+ if ( matches && matches . length > 0 && matches . groups ) {
168
+ const vsixTargetPlatform : string = matches . groups [ 'platform' ] ;
169
+ const platformInfo : PlatformInformation = await PlatformInformation . GetPlatformInformation ( ) ;
170
+ let isPlatformCompatible : boolean = true ;
171
+ let isPlatformMatching : boolean = true ;
172
+ switch ( vsixTargetPlatform ) {
173
+ case "win32-x64" :
174
+ isPlatformMatching = platformInfo . platform === "win32" && platformInfo . architecture === "x64" ;
175
+ // x64 binaries can also be run on arm64 Windows 11.
176
+ isPlatformCompatible = platformInfo . platform === "win32" && ( platformInfo . architecture === "x64" || ( platformInfo . architecture === "arm64" && semver . gte ( os . release ( ) , "10.0.22000" ) ) ) ;
177
+ break ;
178
+ case "win32-ia32" :
179
+ isPlatformMatching = platformInfo . platform === "win32" && platformInfo . architecture === "x86" ;
180
+ // x86 binaries can also be run on x64 and arm64 Windows.
181
+ isPlatformCompatible = platformInfo . platform === "win32" && ( platformInfo . architecture === "x86" || platformInfo . architecture === "x64" || platformInfo . architecture === "arm64" ) ;
182
+ break ;
183
+ case "win32-arm64" :
184
+ isPlatformMatching = platformInfo . platform === "win32" && platformInfo . architecture === "arm64" ;
185
+ isPlatformCompatible = isPlatformMatching ;
186
+ break ;
187
+ case "linux-x64" :
188
+ isPlatformMatching = platformInfo . platform === "linux" && platformInfo . architecture === "x64" && platformInfo . distribution ?. name !== "alpine" ;
189
+ isPlatformCompatible = isPlatformMatching ;
190
+ break ;
191
+ case "linux-arm64" :
192
+ isPlatformMatching = platformInfo . platform === "linux" && platformInfo . architecture === "arm64" && platformInfo . distribution ?. name !== "alpine" ;
193
+ isPlatformCompatible = isPlatformMatching ;
194
+ break ;
195
+ case "linux-armhf" :
196
+ isPlatformMatching = platformInfo . platform === "linux" && platformInfo . architecture === "arm" && platformInfo . distribution ?. name !== "alpine" ;
197
+ // armhf binaries can also be run on aarch64 linux.
198
+ isPlatformCompatible = platformInfo . platform === "linux" && ( platformInfo . architecture === "arm" || platformInfo . architecture === "arm64" ) && platformInfo . distribution ?. name !== "alpine" ;
199
+ break ;
200
+ case "alpine-x64" :
201
+ isPlatformMatching = platformInfo . platform === "linux" && platformInfo . architecture === "x64" && platformInfo . distribution ?. name === "alpine" ;
202
+ isPlatformCompatible = isPlatformMatching ;
203
+ break ;
204
+ case "alpine-arm64" :
205
+ isPlatformMatching = platformInfo . platform === "linux" && platformInfo . architecture === "arm64" && platformInfo . distribution ?. name === "alpine" ;
206
+ isPlatformCompatible = isPlatformMatching ;
207
+ break ;
208
+ case "darwin-x64" :
209
+ isPlatformMatching = platformInfo . platform === "darwin" && platformInfo . architecture === "x64" ;
210
+ isPlatformCompatible = isPlatformMatching ;
211
+ break ;
212
+ case "darwin-arm64" :
213
+ isPlatformMatching = platformInfo . platform === "darwin" && platformInfo . architecture === "arm64" ;
214
+ // x64 binaries can also be run on arm64 macOS.
215
+ isPlatformCompatible = platformInfo . platform === "darwin" && ( platformInfo . architecture === "x64" || platformInfo . architecture === "arm64" ) ;
216
+ break ;
217
+ default :
218
+ console . log ( "Unrecognized TargetPlatform in .vsixmanifest" ) ;
219
+ break ;
220
+ }
221
+ if ( ! isPlatformCompatible ) {
222
+ vscode . window . showErrorMessage ( localize ( "vsix.platform.incompatible" , "The target platform {0} specifed in the C/C++ Extension VSIX is not compatible with your system." , vsixTargetPlatform ) ) ;
223
+ } else if ( ! isPlatformMatching ) {
224
+ vscode . window . showWarningMessage ( localize ( "vsix.platform.mismatching" , "The target platform {0} specifed in the C/C++ Extension VSIX does not match VS Code." , vsixTargetPlatform ) ) ;
225
+ }
226
+ } else {
227
+ console . log ( "Unable to find TargetPlatform in .vsixmanifest" ) ;
228
+ }
229
+ }
230
+ }
231
+
158
232
/**
159
233
* activate: set up the extension for language services
160
234
*/
161
235
export async function activate ( ) : Promise < void > {
162
236
237
+ await checkVsixCompatibility ( ) ;
238
+
163
239
if ( vscode . workspace . workspaceFolders && vscode . workspace . workspaceFolders . length > 0 ) {
164
240
for ( let i : number = 0 ; i < vscode . workspace . workspaceFolders . length ; ++ i ) {
165
241
const config : string = path . join ( vscode . workspace . workspaceFolders [ i ] . uri . fsPath , ".vscode/c_cpp_properties.json" ) ;
0 commit comments