From 2ed6660b5a0a37b4a140a4dbd6c26a729b2e5f08 Mon Sep 17 00:00:00 2001 From: Colen Garoutte-Carson Date: Tue, 6 Apr 2021 14:11:55 -0700 Subject: [PATCH 1/6] Add check and message for x64 VSIX on M1 Mac --- Extension/src/main.ts | 68 ++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/Extension/src/main.ts b/Extension/src/main.ts index 9512f0f2c..1cbcd0949 100644 --- a/Extension/src/main.ts +++ b/Extension/src/main.ts @@ -76,37 +76,57 @@ export async function activate(context: vscode.ExtensionContext): Promise = new PersistentState("CPP.promptForMacArchictureMismatch", true); // Check the main binaries files to declare if the extension has been installed successfully. - if (installedPlatform && process.platform !== installedPlatform) { + if (installedPlatform && process.platform !== installedPlatform || arch !== process.arch) { // Check if the correct offline/insiders vsix is installed on the correct platform. const platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation(); const vsixName: string = vsixNameForPlatform(platformInfo); - 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); const downloadLink: string = localize("download.button", "Go to Download Page"); - vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => { - if (selection === downloadLink) { - vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl)); + if (installedPlatform === 'darwin' && process.arch === "x64" && arch === "arm64") { + if (promptForMacArchictureMismatch.Value) { + // Display a message specifically referring the user to the ARM64 Mac build on ARM64 Mac. + errMsg = localize("native.binaries.mismatch.osx", "This {0} version of the extension has been installed. Since you are on an Apple Silicon Mac, we recommend installing the \"{1}\" version of the extension."); + promptForMacArchictureMismatch.Value = false; + vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => { + if (selection === downloadLink) { + vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl)); + } + }); } - }); - } else if (!(await util.checkInstallBinariesExist())) { - 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."); - const reload: string = localize("remove.extension", "Attempt to Repair"); - vscode.window.showErrorMessage(errMsg, reload).then(async (value?: string) => { - if (value === reload) { - await util.removeInstallLockFile(); - vscode.commands.executeCommand("workbench.action.reloadWindow"); - } - }); - } else if (!(await util.checkInstallJsonsExist())) { - // Check the Json files to declare if the extension has been installed successfully. - 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."); - const downloadLink: string = localize("download.button", "Go to Download Page"); - vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => { - if (selection === downloadLink) { - vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl)); - } - }); + } else { + // Reset the persistent boolean tracking whether to warn the user of architecture mismatch on OSX. + promptForMacArchictureMismatch.Value = true; + 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); + vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => { + if (selection === downloadLink) { + vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl)); + } + }); + } + } else { + // Reset the persistent boolean tracking whether to warn the user of architecture mismatch on OSX. + promptForMacArchictureMismatch.Value = true; + if (!(await util.checkInstallBinariesExist())) { + 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."); + const reload: string = localize("remove.extension", "Attempt to Repair"); + vscode.window.showErrorMessage(errMsg, reload).then(async (value?: string) => { + if (value === reload) { + await util.removeInstallLockFile(); + vscode.commands.executeCommand("workbench.action.reloadWindow"); + } + }); + } else if (!(await util.checkInstallJsonsExist())) { + // Check the Json files to declare if the extension has been installed successfully. + 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."); + const downloadLink: string = localize("download.button", "Go to Download Page"); + vscode.window.showErrorMessage(errMsg, downloadLink).then(async (selection) => { + if (selection === downloadLink) { + vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl)); + } + }); + } } return cppTools; From 3e88cc2b294ec78c9cb0792b59ffa63a6573d55d Mon Sep 17 00:00:00 2001 From: Colen Garoutte-Carson Date: Tue, 6 Apr 2021 15:34:24 -0700 Subject: [PATCH 2/6] Switch to using install.lock for architecture --- Extension/src/common.ts | 39 +++++++++++---------------------------- Extension/src/main.ts | 17 ++++++++++------- 2 files changed, 21 insertions(+), 35 deletions(-) diff --git a/Extension/src/common.ts b/Extension/src/common.ts index f32502b91..f906154dc 100644 --- a/Extension/src/common.ts +++ b/Extension/src/common.ts @@ -417,21 +417,18 @@ export function getHttpsProxyAgent(): HttpsProxyAgent | undefined { return new HttpsProxyAgent(proxyOptions); } -/** Creates a file if it doesn't exist */ -function touchFile(file: string): Promise { - return new Promise((resolve, reject) => { - fs.writeFile(file, "", (err) => { - if (err) { - reject(err); - } - - resolve(); - }); - }); -} +export interface InstallLockContents { + platform: string; + architecture: string; +}; -export function touchInstallLockFile(): Promise { - return touchFile(getInstallLockPath()); +export function touchInstallLockFile(info: PlatformInformation): Promise { + const installLockObject: InstallLockContents = { + platform: info.platform, + architecture: info.architecture + }; + const content: string = JSON.stringify(installLockObject); + return writeFileText(getInstallLockPath(), content); } export function touchExtensionFolder(): Promise { @@ -503,20 +500,6 @@ export function checkInstallLockFile(): Promise { return checkFileExists(getInstallLockPath()); } -/** Get the platform that the installed binaries belong to.*/ -export function getInstalledBinaryPlatform(): string | undefined { - // the LLVM/bin folder is utilized to identify the platform - let installedPlatform: string | undefined; - if (checkFileExistsSync(path.join(extensionPath, "LLVM/bin/clang-format.exe"))) { - installedPlatform = "win32"; - } else if (checkFileExistsSync(path.join(extensionPath, "LLVM/bin/clang-format.darwin"))) { - installedPlatform = "darwin"; - } else if (checkFileExistsSync(path.join(extensionPath, "LLVM/bin/clang-format"))) { - installedPlatform = "linux"; - } - return installedPlatform; -} - /** Check if the core binaries exists in extension's installation folder */ export async function checkInstallBinariesExist(): Promise { if (!checkInstallLockFile()) { diff --git a/Extension/src/main.ts b/Extension/src/main.ts index 1cbcd0949..1c417151f 100644 --- a/Extension/src/main.ts +++ b/Extension/src/main.ts @@ -75,16 +75,19 @@ export async function activate(context: vscode.ExtensionContext): Promise = new PersistentState("CPP.promptForMacArchictureMismatch", true); + // Read archictures of binaries from install.lock + const fileContents: string = await util.readFileText(util.getInstallLockPath()); + const installedPlatformAndArchitecture: util.InstallLockContents = JSON.parse(fileContents); + // Check the main binaries files to declare if the extension has been installed successfully. - if (installedPlatform && process.platform !== installedPlatform || arch !== process.arch) { + if (process.platform !== installedPlatformAndArchitecture.platform || arch !== installedPlatformAndArchitecture.architecture) { // Check if the correct offline/insiders vsix is installed on the correct platform. const platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation(); const vsixName: string = vsixNameForPlatform(platformInfo); const downloadLink: string = localize("download.button", "Go to Download Page"); - if (installedPlatform === 'darwin' && process.arch === "x64" && arch === "arm64") { + if (installedPlatformAndArchitecture.platform === 'darwin' && installedPlatformAndArchitecture.architecture === "x64" && arch === "arm64") { if (promptForMacArchictureMismatch.Value) { // Display a message specifically referring the user to the ARM64 Mac build on ARM64 Mac. errMsg = localize("native.binaries.mismatch.osx", "This {0} version of the extension has been installed. Since you are on an Apple Silicon Mac, we recommend installing the \"{1}\" version of the extension."); @@ -98,7 +101,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { if (selection === downloadLink) { vscode.env.openExternal(vscode.Uri.parse(releaseDownloadUrl)); @@ -239,7 +242,7 @@ async function onlineInstallation(info: PlatformInformation): Promise { await rewriteManifest(); setInstallationStage('touchInstallLockFile'); - await touchInstallLockFile(); + await touchInstallLockFile(info); setInstallationStage('postInstall'); await postInstall(info); @@ -331,8 +334,8 @@ function removeUnnecessaryFile(): Promise { return Promise.resolve(); } -function touchInstallLockFile(): Promise { - return util.touchInstallLockFile(); +function touchInstallLockFile(info: PlatformInformation): Promise { + return util.touchInstallLockFile(info); } function handleError(error: any): void { From b1f9d11497b71996ef83d6c7931a169a1ae35b2e Mon Sep 17 00:00:00 2001 From: Colen Garoutte-Carson Date: Tue, 6 Apr 2021 15:38:55 -0700 Subject: [PATCH 3/6] Add handing of existing empty install.lock --- Extension/src/main.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Extension/src/main.ts b/Extension/src/main.ts index 1c417151f..9ebab46ae 100644 --- a/Extension/src/main.ts +++ b/Extension/src/main.ts @@ -79,7 +79,16 @@ export async function activate(context: vscode.ExtensionContext): PromiseJSON.parse(fileContents); + let installedPlatformAndArchitecture: util.InstallLockContents; + // Just in case we're debugging with an existing install.lock that is empty, assume current platform if empty. + if (fileContents.length === 0) { + installedPlatformAndArchitecture = { + platform: process.platform, + architecture: arch + }; + } else { + installedPlatformAndArchitecture = JSON.parse(fileContents); + } // Check the main binaries files to declare if the extension has been installed successfully. if (process.platform !== installedPlatformAndArchitecture.platform || arch !== installedPlatformAndArchitecture.architecture) { From 5ed963d804ef0ed8a6ad4edd201d4db39f202bd7 Mon Sep 17 00:00:00 2001 From: Colen Garoutte-Carson Date: Tue, 6 Apr 2021 15:57:23 -0700 Subject: [PATCH 4/6] Fix missing args --- Extension/src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/main.ts b/Extension/src/main.ts index 9ebab46ae..7fe0bfcfa 100644 --- a/Extension/src/main.ts +++ b/Extension/src/main.ts @@ -99,7 +99,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { if (selection === downloadLink) { From 25bb2cbdd6770a903242cdc6efdc48c89f5c1374 Mon Sep 17 00:00:00 2001 From: Colen Garoutte-Carson Date: Tue, 6 Apr 2021 16:14:01 -0700 Subject: [PATCH 5/6] Add check to avoid complaining about x86 win32 binaries on x64 system. Fix issues with the error message. --- Extension/src/main.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Extension/src/main.ts b/Extension/src/main.ts index 7fe0bfcfa..4768146bd 100644 --- a/Extension/src/main.ts +++ b/Extension/src/main.ts @@ -91,7 +91,8 @@ export async function activate(context: vscode.ExtensionContext): Promise { if (selection === downloadLink) { From 5879b009faddc102b4544ffcf44502d0f79edf45 Mon Sep 17 00:00:00 2001 From: Colen Garoutte-Carson Date: Tue, 6 Apr 2021 16:22:02 -0700 Subject: [PATCH 6/6] Fix arch check --- Extension/src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extension/src/main.ts b/Extension/src/main.ts index 4768146bd..611f98eb5 100644 --- a/Extension/src/main.ts +++ b/Extension/src/main.ts @@ -92,7 +92,7 @@ export async function activate(context: vscode.ExtensionContext): Promise