Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
{
"$id": "https://dl.espressif.com/schemas/esp-idf-cmakepresets-schema-v1.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "ESP-IDF CMakePresets Extension v1.0",
"description": "Extends the official CMakePresets schema (v3) with strict ESP-IDF vendor fields; requires CMake >= 3.21.",
"allOf": [
{
"$ref": "https://raw.githubusercontent.com/Kitware/CMake/master/Help/manual/presets/schema.json"
},
{
"type": "object",
"properties": {
"version": {
"const": 3,
"description": "CMake Presets format version. Must be 3."
},
"cmakeMinimumRequired": {
"type": "object",
"properties": {
"major": { "type": "integer", "const": 3 },
"minor": { "type": "integer", "minimum": 21 },
"patch": { "type": "integer", "minimum": 0 }
},
"required": ["major", "minor"]
},
"configurePresets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"vendor": {
"type": "object",
"properties": {
"espressif/vscode-esp-idf": {
"type": "object",
"properties": {
"schemaVersion": {
"type": "integer",
"enum": [1],
"description": "ESP-IDF vendor schema version."
},
"settings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"compileArgs",
"ninjaArgs",
"flashBaudRate",
"monitorBaudRate",
"openOCD",
"tasks"
]
},
"value": {}
},
"required": ["type", "value"],
"additionalProperties": false,
"allOf": [
{
"if": { "properties": { "type": { "enum": ["compileArgs", "ninjaArgs"] } } },
"then": { "properties": { "value": { "type": "array", "items": { "type": "string" } } } }
},
{
"if": { "properties": { "type": { "enum": ["flashBaudRate", "monitorBaudRate"] } } },
"then": { "properties": { "value": { "type": "string" } } }
},
{
"if": { "properties": { "type": { "const": "openOCD" } } },
"then": {
"properties": {
"value": {
"type": "object",
"properties": {
"debugLevel": { "type": "integer" },
"configs": { "type": "array", "items": { "type": "string" } },
"args": { "type": "array", "items": { "type": "string" } }
},
"required": ["debugLevel", "configs", "args"],
"additionalProperties": false
}
}
}
},
{
"if": { "properties": { "type": { "const": "tasks" } } },
"then": {
"properties": {
"value": {
"type": "object",
"properties": {
"preBuild": { "type": "string" },
"preFlash": { "type": "string" },
"postBuild": { "type": "string" },
"postFlash": { "type": "string" }
},
"additionalProperties": false
}
}
}
}
]
}
}
},
"required": ["schemaVersion", "settings"],
"additionalProperties": false
}
},
"additionalProperties": true
}
}
}
}
},
"required": ["version", "cmakeMinimumRequired", "configurePresets"]
}
]
}
21 changes: 21 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,15 @@
"main": "./dist/extension",
"l10n": "./l10n",
"contributes": {
"jsonValidation": [
{
"fileMatch": [
"CMakePresets.json",
"CMakeUserPresets.json"
],
"url": "./internal/com.espressif.idf.uploads/cmakepresets/esp-idf-cmakepresets-schema-v1.json"
}
],
"walkthroughs": [
{
"id": "espIdf.walkthrough.basic-usage",
Expand Down Expand Up @@ -753,6 +762,12 @@
"description": "%param.buildPath%",
"scope": "resource"
},
"idf.useCMakePresets": {
"type": "boolean",
"default": false,
"description": "Use idf.py --preset <name> build instead of direct CMake calls. Requires ESP-IDF with CMakePresets support.",
"scope": "resource"
},
"idf.buildPathWin": {
"type": "string",
"default": "${workspaceFolder}\\build",
Expand Down Expand Up @@ -1295,6 +1310,12 @@
"default": 60,
"scope": "resource",
"description": "%param.serialPortDetectionTimeout%"
},
"idf.saveLastProjectConfiguration": {
"type": "boolean",
"default": true,
"scope": "resource",
"description": "%param.saveLastProjectConfiguration%"
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -212,5 +212,6 @@
"command.errorHints.clearAll.title": "Clear All Error Hints",
"command.errorHints.clearBuild.title": "Clear Build Error Hints",
"command.errorHints.clearOpenOCD.title": "Clear OpenOCD Error Hints",
"Launch Debug": "Launch Debug"
"Launch Debug": "Launch Debug",
"param.saveLastProjectConfiguration": "Save and restore the last selected project configuration when reopening a workspace. When enabled, the extension will restore the last used configuration if it exists, otherwise no configuration will be selected. When disabled, no configuration will be selected by default."
}
102 changes: 102 additions & 0 deletions src/build/buildTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,22 @@ export class BuildTask {
throw new Error("ALREADY_BUILDING");
}
this.building(true);

// Check if CMakePresets build mode is enabled
const useCMakePresets = idfConf.readParameter(
"idf.useCMakePresets",
this.currentWorkspace
) as boolean;

if (useCMakePresets) {
return await this.buildWithPresets(buildType);
}

// Continue with traditional CMake build
return await this.buildWithCMake(buildType);
}

private async buildWithCMake(buildType?: ESP.BuildType) {
await ensureDir(this.buildDirPath);
const modifiedEnv = await appendIdfAndToolsToPath(this.currentWorkspace);
const processOptions = {
Expand Down Expand Up @@ -290,4 +306,90 @@ export class BuildTask {
buildPresentationOptions
);
}

private async buildWithPresets(buildType?: ESP.BuildType) {
await ensureDir(this.buildDirPath);
const modifiedEnv = await appendIdfAndToolsToPath(this.currentWorkspace);

// Get the selected project configuration preset name
const selectedConfig = ESP.ProjectConfiguration.store.get<string>(
ESP.ProjectConfiguration.SELECTED_CONFIG
);

if (!selectedConfig) {
throw new Error(
"No project configuration selected. Please select a CMakePresets configuration first."
);
}

const currentWorkspaceFolder = vscode.workspace.workspaceFolders.find(
(w) => w.uri === this.currentWorkspace
);

const notificationMode = idfConf.readParameter(
"idf.notificationMode",
this.currentWorkspace
) as string;
const showTaskOutput =
notificationMode === idfConf.NotificationMode.All ||
notificationMode === idfConf.NotificationMode.Output
? vscode.TaskRevealKind.Always
: vscode.TaskRevealKind.Silent;

// Build idf.py command with preset
const pythonBinPath = await getVirtualEnvPythonPath(this.currentWorkspace);
const idfPy = join(this.idfPathDir, "tools", "idf.py");

let args = [idfPy, "--preset", selectedConfig];

// Add build type specific arguments if needed
if (buildType) {
switch (buildType) {
case ESP.BuildType.Bootloader:
args.push("bootloader");
break;
case ESP.BuildType.PartitionTable:
args.push("partition-table");
break;
default:
args.push("build");
break;
}
} else {
args.push("build");
}

Logger.info(`Building with CMakePresets using: ${pythonBinPath} ${args.join(" ")}`);

const processOptions = {
cwd: this.currentWorkspace.fsPath,
env: modifiedEnv,
};

const buildExecution = new vscode.ProcessExecution(
pythonBinPath,
args,
processOptions
);

const buildPresentationOptions = {
reveal: showTaskOutput,
showReuseMessage: false,
clear: false,
panel: vscode.TaskPanelKind.Shared,
} as vscode.TaskPresentationOptions;

TaskManager.addTask(
{
type: "esp-idf",
command: `ESP-IDF Build (CMakePresets: ${selectedConfig})`,
taskId: "idf-build-presets-task",
},
currentWorkspaceFolder || vscode.TaskScope.Workspace,
`ESP-IDF Build (CMakePresets: ${selectedConfig})`,
buildExecution,
["espIdf"],
buildPresentationOptions
);
}
}
4 changes: 2 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ export namespace ESP {
export namespace ProjectConfiguration {
export let store: ProjectConfigStore;
export const SELECTED_CONFIG = "SELECTED_PROJECT_CONFIG";
export const PROJECT_CONFIGURATION_FILENAME =
"esp_idf_project_configuration.json";
export const PROJECT_CONFIGURATION_FILENAME = "CMakePresets.json";
export const USER_CONFIGURATION_FILENAME = "CMakeUserPresets.json";
}

export enum BuildType {
Expand Down
5 changes: 5 additions & 0 deletions src/espIdf/openOcd/boardConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { commands, ConfigurationTarget, l10n, Uri, window } from "vscode";
import { defaultBoards } from "./defaultBoards";
import { IdfToolsManager } from "../../idfToolsManager";
import { getIdfTargetFromSdkconfig } from "../../workspaceConfig";
import { updateCurrentProfileOpenOcdConfigs } from "../../project-conf";

export interface IdfBoard {
name: string;
Expand Down Expand Up @@ -199,6 +200,10 @@ export async function selectOpenOcdConfigFiles(
ConfigurationTarget.WorkspaceFolder,
workspaceFolder
);

// Update project configuration with OpenOCD configs if a configuration is selected
await updateCurrentProfileOpenOcdConfigs(selectedBoard.target.configFiles, workspaceFolder);

Logger.infoNotify(
l10n.t(`OpenOCD Board configuration files set to {boards}.`, {
boards: selectedBoard.target.configFiles.join(","),
Expand Down
Loading