Skip to content

Commit bdd881b

Browse files
authored
Add check and message for x64 VSIX on M1 Mac (#7303)
1 parent 0b4f51b commit bdd881b

File tree

2 files changed

+72
-56
lines changed

2 files changed

+72
-56
lines changed

Extension/src/common.ts

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -417,21 +417,18 @@ export function getHttpsProxyAgent(): HttpsProxyAgent | undefined {
417417
return new HttpsProxyAgent(proxyOptions);
418418
}
419419

420-
/** Creates a file if it doesn't exist */
421-
function touchFile(file: string): Promise<void> {
422-
return new Promise<void>((resolve, reject) => {
423-
fs.writeFile(file, "", (err) => {
424-
if (err) {
425-
reject(err);
426-
}
427-
428-
resolve();
429-
});
430-
});
431-
}
420+
export interface InstallLockContents {
421+
platform: string;
422+
architecture: string;
423+
};
432424

433-
export function touchInstallLockFile(): Promise<void> {
434-
return touchFile(getInstallLockPath());
425+
export function touchInstallLockFile(info: PlatformInformation): Promise<void> {
426+
const installLockObject: InstallLockContents = {
427+
platform: info.platform,
428+
architecture: info.architecture
429+
};
430+
const content: string = JSON.stringify(installLockObject);
431+
return writeFileText(getInstallLockPath(), content);
435432
}
436433

437434
export function touchExtensionFolder(): Promise<void> {
@@ -503,20 +500,6 @@ export function checkInstallLockFile(): Promise<boolean> {
503500
return checkFileExists(getInstallLockPath());
504501
}
505502

506-
/** Get the platform that the installed binaries belong to.*/
507-
export function getInstalledBinaryPlatform(): string | undefined {
508-
// the LLVM/bin folder is utilized to identify the platform
509-
let installedPlatform: string | undefined;
510-
if (checkFileExistsSync(path.join(extensionPath, "LLVM/bin/clang-format.exe"))) {
511-
installedPlatform = "win32";
512-
} else if (checkFileExistsSync(path.join(extensionPath, "LLVM/bin/clang-format.darwin"))) {
513-
installedPlatform = "darwin";
514-
} else if (checkFileExistsSync(path.join(extensionPath, "LLVM/bin/clang-format"))) {
515-
installedPlatform = "linux";
516-
}
517-
return installedPlatform;
518-
}
519-
520503
/** Check if the core binaries exists in extension's installation folder */
521504
export async function checkInstallBinariesExist(): Promise<boolean> {
522505
if (!checkInstallLockFile()) {

Extension/src/main.ts

Lines changed: 61 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -75,38 +75,71 @@ export async function activate(context: vscode.ExtensionContext): Promise<CppToo
7575

7676
await processRuntimeDependencies();
7777

78-
const installedPlatform: string | undefined = util.getInstalledBinaryPlatform();
78+
const promptForMacArchictureMismatch: PersistentState<boolean> = new PersistentState<boolean>("CPP.promptForMacArchictureMismatch", true);
79+
80+
// Read archictures of binaries from install.lock
81+
const fileContents: string = await util.readFileText(util.getInstallLockPath());
82+
let installedPlatformAndArchitecture: util.InstallLockContents;
83+
// Just in case we're debugging with an existing install.lock that is empty, assume current platform if empty.
84+
if (fileContents.length === 0) {
85+
installedPlatformAndArchitecture = {
86+
platform: process.platform,
87+
architecture: arch
88+
};
89+
} else {
90+
installedPlatformAndArchitecture = <util.InstallLockContents>JSON.parse(fileContents);
91+
}
7992

8093
// Check the main binaries files to declare if the extension has been installed successfully.
81-
if (installedPlatform && process.platform !== installedPlatform) {
94+
if (process.platform !== installedPlatformAndArchitecture.platform
95+
|| (arch !== installedPlatformAndArchitecture.architecture && (arch !== "x64" || installedPlatformAndArchitecture.architecture !== 'x86' || process.platform !== "win32"))) {
8296
// Check if the correct offline/insiders vsix is installed on the correct platform.
8397
const platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation();
8498
const vsixName: string = vsixNameForPlatform(platformInfo);
85-
errMsg = localize("native.binaries.not.supported", "This {0} version of the extension is incompatible with your OS. Please download and install the \"{1}\" version of the extension.", GetOSName(installedPlatform), vsixName);
86-
const downloadLink: string = localize("download.button", "Go to Download Page");
87-
vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => {
88-
if (selection === downloadLink) {
89-
vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl));
90-
}
91-
});
92-
} else if (!(await util.checkInstallBinariesExist())) {
93-
errMsg = localize("extension.installation.failed", "The C/C++ extension failed to install successfully. You will need to repair or reinstall the extension for C/C++ language features to function properly.");
94-
const reload: string = localize("remove.extension", "Attempt to Repair");
95-
vscode.window.showErrorMessage(errMsg, reload).then(async (value?: string) => {
96-
if (value === reload) {
97-
await util.removeInstallLockFile();
98-
vscode.commands.executeCommand("workbench.action.reloadWindow");
99-
}
100-
});
101-
} else if (!(await util.checkInstallJsonsExist())) {
102-
// Check the Json files to declare if the extension has been installed successfully.
103-
errMsg = localize("jason.files.missing", "The C/C++ extension failed to install successfully. You will need to reinstall the extension for C/C++ language features to function properly.");
10499
const downloadLink: string = localize("download.button", "Go to Download Page");
105-
vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => {
106-
if (selection === downloadLink) {
107-
vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl));
100+
if (installedPlatformAndArchitecture.platform === 'darwin' && installedPlatformAndArchitecture.architecture === "x64" && arch === "arm64") {
101+
if (promptForMacArchictureMismatch.Value) {
102+
// Display a message specifically referring the user to the ARM64 Mac build on ARM64 Mac.
103+
errMsg = localize("native.binaries.mismatch.osx", "This Intel version of the extension has been installed. Since you are on an Apple Silicon Mac, we recommend installing the Apple Silicon version of the extension.");
104+
promptForMacArchictureMismatch.Value = false;
105+
vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => {
106+
if (selection === downloadLink) {
107+
vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl));
108+
}
109+
});
108110
}
109-
});
111+
} else {
112+
// Reset the persistent boolean tracking whether to warn the user of architecture mismatch on OSX.
113+
promptForMacArchictureMismatch.Value = true;
114+
errMsg = localize("native.binaries.not.supported", "This {0} version of the extension is incompatible with your OS. Please download and install the \"{1}\" version of the extension.", GetOSName(installedPlatformAndArchitecture.platform), vsixName);
115+
vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => {
116+
if (selection === downloadLink) {
117+
vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl));
118+
}
119+
});
120+
}
121+
} else {
122+
// Reset the persistent boolean tracking whether to warn the user of architecture mismatch on OSX.
123+
promptForMacArchictureMismatch.Value = true;
124+
if (!(await util.checkInstallBinariesExist())) {
125+
errMsg = localize("extension.installation.failed", "The C/C++ extension failed to install successfully. You will need to repair or reinstall the extension for C/C++ language features to function properly.");
126+
const reload: string = localize("remove.extension", "Attempt to Repair");
127+
vscode.window.showErrorMessage(errMsg, reload).then(async (value?: string) => {
128+
if (value === reload) {
129+
await util.removeInstallLockFile();
130+
vscode.commands.executeCommand("workbench.action.reloadWindow");
131+
}
132+
});
133+
} else if (!(await util.checkInstallJsonsExist())) {
134+
// Check the Json files to declare if the extension has been installed successfully.
135+
errMsg = localize("jason.files.missing", "The C/C++ extension failed to install successfully. You will need to reinstall the extension for C/C++ language features to function properly.");
136+
const downloadLink: string = localize("download.button", "Go to Download Page");
137+
vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => {
138+
if (selection === downloadLink) {
139+
vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl));
140+
}
141+
});
142+
}
110143
}
111144

112145
return cppTools;
@@ -219,7 +252,7 @@ async function onlineInstallation(info: PlatformInformation): Promise<void> {
219252
await rewriteManifest();
220253

221254
setInstallationStage('touchInstallLockFile');
222-
await touchInstallLockFile();
255+
await touchInstallLockFile(info);
223256

224257
setInstallationStage('postInstall');
225258
await postInstall(info);
@@ -311,8 +344,8 @@ function removeUnnecessaryFile(): Promise<void> {
311344
return Promise.resolve();
312345
}
313346

314-
function touchInstallLockFile(): Promise<void> {
315-
return util.touchInstallLockFile();
347+
function touchInstallLockFile(info: PlatformInformation): Promise<void> {
348+
return util.touchInstallLockFile(info);
316349
}
317350

318351
function handleError(error: any): void {

0 commit comments

Comments
 (0)