diff --git a/package.json b/package.json index b721c957..b3eb8d6f 100644 --- a/package.json +++ b/package.json @@ -187,6 +187,12 @@ "category": "Raspberry Pi Pico", "enablement": "raspberry-pi-pico.isPicoProject" }, + { + "command": "raspberry-pi-pico.switchBuildType", + "title": "Switch Build Type", + "category": "Raspberry Pi Pico", + "enablement": "raspberry-pi-pico.isPicoProject" + }, { "command": "raspberry-pi-pico.importProject", "title": "Import Pico Project", diff --git a/src/commands/configureCmake.mts b/src/commands/configureCmake.mts index 0c8b054c..e1b43dfc 100644 --- a/src/commands/configureCmake.mts +++ b/src/commands/configureCmake.mts @@ -1,11 +1,12 @@ import { Command } from "./command.mjs"; import Logger from "../logger.mjs"; import { window, workspace } from "vscode"; -import { configureCmakeNinja } from "../utils/cmakeUtil.mjs"; +import { cmakeGetPicoVar, configureCmakeNinja } from "../utils/cmakeUtil.mjs"; import Settings, { SettingsKey } from "../settings.mjs"; import { join } from "path"; import { rimraf } from "rimraf"; import { unknownErrorToString } from "../utils/errorHelper.mjs"; +import type UI from "../ui.mjs"; export default class ConfigureCmakeCommand extends Command { private _logger: Logger = new Logger("ConfigureCmakeCommand"); @@ -60,7 +61,7 @@ export class CleanCMakeCommand extends Command { public static readonly id = "cleanCmake"; - constructor() { + constructor(private readonly _ui: UI) { super(CleanCMakeCommand.id); } @@ -115,5 +116,71 @@ export class CleanCMakeCommand extends Command { "to get more information about the error." ); } + + const ws = workspaceFolder.uri.fsPath; + const cMakeCachePath = join(ws, "build","CMakeCache.txt"); + const newBuildType = cmakeGetPicoVar(cMakeCachePath, "CMAKE_BUILD_TYPE"); + this._ui.updateBuildType(newBuildType ?? "unknown"); + } +} + +export class SwitchBuildTypeCommand extends Command { + private _logger: Logger = new Logger("SwitchBuildTypeCommand"); + + public static readonly id = "switchBuildType"; + + constructor(private readonly _ui: UI) { + super(SwitchBuildTypeCommand.id); + } + + async execute(): Promise { + const workspaceFolder = workspace.workspaceFolders?.[0]; + + // check if is a pico project + if (workspaceFolder === undefined) { + this._logger.warn("No workspace folder found."); + void window.showWarningMessage("No workspace folder found."); + + return; + } + + const settings = Settings.getInstance(); + + if ( + settings !== undefined && + settings.getBoolean(SettingsKey.useCmakeTools) + ) { + void window.showErrorMessage( + "You must use the CMake Tools extension to configure your build. " + + "To use this extension instead, change the useCmakeTools setting." + ); + + return; + } + + const ws = workspaceFolder.uri.fsPath; + const cMakeCachePath = join(ws, "build","CMakeCache.txt"); + const oldBuildType = cmakeGetPicoVar(cMakeCachePath, "CMAKE_BUILD_TYPE"); + + // QuickPick for the build type + const quickPickItems = ["Debug", "Release", "MinSizeRel", "RelWithDebInfo"]; + const buildType = await window.showQuickPick(quickPickItems, { + placeHolder: `Current: ${oldBuildType}`, + }); + + if (await configureCmakeNinja(workspaceFolder.uri, buildType)) { + void window.showInformationMessage("CMake has configured your build."); + } else { + void window.showWarningMessage( + "CMake failed to configure your build. " + + "See the developer console for details " + + "(Help -> Toggle Developer Tools). " + + "You can also use the CMake Tools Extension Integration " + + "to get more information about the error." + ); + } + + const newBuildType = cmakeGetPicoVar(cMakeCachePath, "CMAKE_BUILD_TYPE"); + this._ui.updateBuildType(newBuildType ?? "unknown"); } } diff --git a/src/extension.mts b/src/extension.mts index 83f276e5..a4d97379 100644 --- a/src/extension.mts +++ b/src/extension.mts @@ -17,6 +17,7 @@ import Logger, { LoggerSource } from "./logger.mjs"; import { CMAKE_DO_NOT_EDIT_HEADER_PREFIX, CMAKE_DO_NOT_EDIT_HEADER_PREFIX_OLD, + cmakeGetPicoVar, cmakeGetSelectedBoard, cmakeGetSelectedToolchainAndSDKVersions, configureCmakeNinja, @@ -69,6 +70,7 @@ import DebugLayoutCommand from "./commands/debugLayout.mjs"; import OpenSdkDocumentationCommand from "./commands/openSdkDocumentation.mjs"; import ConfigureCmakeCommand, { CleanCMakeCommand, + SwitchBuildTypeCommand, } from "./commands/configureCmake.mjs"; import ImportProjectCommand from "./commands/importProject.mjs"; import { homedir } from "os"; @@ -123,10 +125,11 @@ export async function activate(context: ExtensionContext): Promise { new DebugLayoutCommand(), new OpenSdkDocumentationCommand(context.extensionUri), new ConfigureCmakeCommand(), + new SwitchBuildTypeCommand(ui), new ImportProjectCommand(context.extensionUri), new NewExampleProjectCommand(context.extensionUri), new UninstallPicoSDKCommand(), - new CleanCMakeCommand(), + new CleanCMakeCommand(ui), ]; // register all command handlers @@ -774,6 +777,11 @@ export async function activate(context: ExtensionContext): Promise { //run `cmake -G Ninja -B ./build ` in the root folder await configureCmakeNinja(workspaceFolder.uri); + const ws = workspaceFolder.uri.fsPath; + const cMakeCachePath = join(ws, "build","CMakeCache.txt"); + const newBuildType = cmakeGetPicoVar(cMakeCachePath, "CMAKE_BUILD_TYPE"); + ui.updateBuildType(newBuildType ?? "unknown"); + workspace.onDidChangeTextDocument(event => { // Check if the changed document is the file you are interested in if (basename(event.document.fileName) === "CMakeLists.txt") { diff --git a/src/ui.mts b/src/ui.mts index 6f647b89..5a8769fa 100644 --- a/src/ui.mts +++ b/src/ui.mts @@ -65,13 +65,18 @@ export default class UI { this._items[StatusBarItemKey.picoSDKQuickPick].text = STATUS_BAR_ITEMS[ StatusBarItemKey.picoSDKQuickPick ].text.replace("", version); - this._activityBarProvider.refresh(version); + this._activityBarProvider.refreshSDK(version); } public updateBoard(board: string): void { this._items[StatusBarItemKey.picoBoardQuickPick].text = STATUS_BAR_ITEMS[ StatusBarItemKey.picoBoardQuickPick ].text.replace("", board); + this._activityBarProvider.refreshBoard(board); + } + + public updateBuildType(buildType: string): void { + this._activityBarProvider.refreshBuildType(buildType); } /* diff --git a/src/utils/cmakeUtil.mts b/src/utils/cmakeUtil.mts index 0ee8b5cc..b3be0254 100644 --- a/src/utils/cmakeUtil.mts +++ b/src/utils/cmakeUtil.mts @@ -101,7 +101,10 @@ export async function getPath(): Promise { }`; } -export async function configureCmakeNinja(folder: Uri): Promise { +export async function configureCmakeNinja( + folder: Uri, + buildType?: string +): Promise { if (process.platform !== "win32" && folder.fsPath.includes("\\")) { const errorMsg = "CMake currently does not support folder names with backslashes."; @@ -200,7 +203,8 @@ export async function configureCmakeNinja(folder: Uri): Promise { pythonPath.includes("/") ? `-DPython3_EXECUTABLE="${pythonPath.replaceAll("\\", "/")}" ` : "" - }` + `-G Ninja -B ./build "${folder.fsPath}"`; + }` + `-G Ninja -B ./build "${folder.fsPath}"` + + (buildType ? ` -DCMAKE_BUILD_TYPE=${buildType}` : ""); await new Promise((resolve, reject) => { // use exec to be able to cancel the process diff --git a/src/webview/activityBar.mts b/src/webview/activityBar.mts index de33cf32..5edc283e 100644 --- a/src/webview/activityBar.mts +++ b/src/webview/activityBar.mts @@ -21,6 +21,7 @@ import OpenSdkDocumentationCommand, { } from "../commands/openSdkDocumentation.mjs"; import ConfigureCmakeCommand, { CleanCMakeCommand, + SwitchBuildTypeCommand, } from "../commands/configureCmake.mjs"; import ImportProjectCommand from "../commands/importProject.mjs"; import NewExampleProjectCommand from "../commands/newExampleProject.mjs"; @@ -52,6 +53,7 @@ const RUN_PROJECT_LABEL = "Run Project (USB)"; const FLASH_PROJECT_LABEL = "Flash Project (SWD)"; const CONFIGURE_CMAKE_PROJECT_LABEL = "Configure CMake"; const CLEAN_CMAKE_PROJECT_LABEL = "Clean CMake"; +const SWITCH_BUILD_TYPE_LABEL = "Switch Build Type"; const DEBUG_PROJECT_LABEL = "Debug Project"; const DEBUG_LAYOUT_PROJECT_LABEL = "Debug Layout"; @@ -60,6 +62,8 @@ export class PicoProjectActivityBar { public static readonly viewType = "raspberry-pi-pico-project-quick-access"; private _sdkVersion: string = "N/A"; + private _board: string = "N/A"; + private _buildType: string = "N/A"; private _onDidChangeTreeData = new EventEmitter< QuickAccessCommand | undefined | void @@ -71,13 +75,27 @@ export class PicoProjectActivityBar constructor() {} - public refresh(newPicoSDKVersion?: string): void { + public refreshSDK(newPicoSDKVersion?: string): void { if (newPicoSDKVersion) { this._sdkVersion = newPicoSDKVersion; } this._onDidChangeTreeData.fire(); } + public refreshBoard(newBoard?: string): void { + if (newBoard) { + this._board = newBoard; + } + this._onDidChangeTreeData.fire(); + } + + public refreshBuildType(newBuildType?: string): void { + if (newBuildType) { + this._buildType = newBuildType; + } + this._onDidChangeTreeData.fire(); + } + public getTreeItem( element: QuickAccessCommand ): TreeItem | Thenable { @@ -119,13 +137,18 @@ export class PicoProjectActivityBar // or "trash" or "sync" element.iconPath = new ThemeIcon("squirrel"); break; + case SWITCH_BUILD_TYPE_LABEL: + element.iconPath = new ThemeIcon("gear"); + element.description = `${this._buildType}`; + break; case SWITCH_SDK_LABEL: // repo-forked or extensions; alt. "replace-all" element.iconPath = new ThemeIcon("find-replace-all"); - element.description = `Current: ${this._sdkVersion}`; + element.description = `${this._sdkVersion}`; break; case SWITCH_BOARD_LABEL: element.iconPath = new ThemeIcon("circuit-board"); + element.description = `${this._board}`; break; case DEBUG_LAYOUT_PROJECT_LABEL: element.iconPath = new ThemeIcon("debug-console"); @@ -254,6 +277,14 @@ export class PicoProjectActivityBar title: CLEAN_CMAKE_PROJECT_LABEL, } ), + new QuickAccessCommand( + SWITCH_BUILD_TYPE_LABEL, + TreeItemCollapsibleState.None, + { + command: `${extensionName}.${SwitchBuildTypeCommand.id}`, + title: SWITCH_BUILD_TYPE_LABEL, + } + ), new QuickAccessCommand( SWITCH_SDK_LABEL, TreeItemCollapsibleState.None,