From c706bc7a9481d2600bff8b9f9bb237cf7fbd6b33 Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Fri, 21 Jul 2023 13:12:28 -0400 Subject: [PATCH 01/22] storing initial thoughts --- package.json | 17 ++++++- ...AdapterNamedPipeServerDescriptorFactory.ts | 47 ++++++++++--------- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index 5565219f5..3ab51009c 100644 --- a/package.json +++ b/package.json @@ -741,7 +741,22 @@ "type": "string", "description": "%cmake-tools.debugger.dapLog.description%", "default": "" - } + }, + "script": { + "type": "string", + "descripttion": "The script to debug" + } + } + }, + "attach": { + "required": [ + "debuggerPipeName" + ], + "properties": { + "debuggerPipeName": { + "type": "string", + "description": "Name of the named piped that the debugger will communicate with CMake over" + } } } } diff --git a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts index 944eb9c37..812983040 100644 --- a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts +++ b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts @@ -15,33 +15,34 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu // undocumented configuration field that lets us know if the session is being invoked from a command // This should only be used from inside the extension from a command that invokes the debugger. if (!session.configuration.fromCommand) { - const promise = new Promise((resolve) => { - debuggerInformation.debuggerIsReady = resolve; - }); + if (session.configuration.request === "launch") { + const promise = new Promise((resolve) => { + debuggerInformation.debuggerIsReady = resolve; + }); - if (session.configuration.clean) { - if (session.configuration.configureAll) { - void extensionManager?.cleanConfigureAllWithDebuggerInternal( - debuggerInformation - ); + if (session.configuration.clean) { + if (session.configuration.configureAll) { + void extensionManager?.cleanConfigureAllWithDebuggerInternal( + debuggerInformation + ); + } else { + void extensionManager?.cleanConfigureWithDebuggerInternal( + debuggerInformation + ); + } } else { - void extensionManager?.cleanConfigureWithDebuggerInternal( - debuggerInformation - ); - } - } else { - if (session.configuration.configureAll) { - void extensionManager?.configureAllWithDebuggerInternal( - debuggerInformation - ); - } else { - void extensionManager?.configureWithDebuggerInternal( - debuggerInformation - ); + if (session.configuration.configureAll) { + void extensionManager?.configureAllWithDebuggerInternal( + debuggerInformation + ); + } else { + void extensionManager?.configureWithDebuggerInternal( + debuggerInformation + ); + } } + await promise; } - - await promise; } return new vscode.DebugAdapterNamedPipeServer(pipeName); From a61c8bcc53df1ede487633b1b5df00cc218d97b2 Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Mon, 24 Jul 2023 14:44:02 -0400 Subject: [PATCH 02/22] rough version of trying to work on new options for debugger configurations --- package.json | 142 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 128 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 3ab51009c..ba8925732 100644 --- a/package.json +++ b/package.json @@ -723,9 +723,15 @@ "configurationAttributes": { "launch": { "properties": { + "externalCMakeLaunch": { + "type": "boolean", + "description": "Whether the cmake debuggee was externally launched", + "default": false + }, "pipeName": { "type": "string", - "description": "%cmake-tools.debugger.pipeName.description%" + "description": "%cmake-tools.debugger.pipeName.description%", + "default": "" }, "clean": { "type": "boolean", @@ -742,22 +748,130 @@ "description": "%cmake-tools.debugger.dapLog.description%", "default": "" }, - "script": { + "scriptPath": { "type": "string", - "descripttion": "The script to debug" + "descripttion": "The path to the script to debug", + "default": "" + }, + "scriptArgs": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "string[]" + } + ], + "description": "Arguments for the script to debug" + }, + "scriptEnv": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "string[]" + } + ], + "description": "Env for the script to debug" } - } - }, - "attach": { - "required": [ - "debuggerPipeName" - ], - "properties": { - "debuggerPipeName": { - "type": "string", - "description": "Name of the named piped that the debugger will communicate with CMake over" + }, + "allOf": [ + { + "anyOf": [ + { "not": { + "properties": { + "externalCMakeLaunch": { "enum": [true]} + }, + "required": ["externalCMakeLaunch"] + }}, + { + "required": ["pipeName"], + "properties": { + "externalCMakeLaunch": { + "type": "boolean", + "description": "Whether the cmake debuggee was externally launched", + "default": false + }, + "pipeName": { + "type": "string", + "description": "%cmake-tools.debugger.pipeName.description%", + "default": "" + } + }, + "not": { + "anyOf": [ + { "required": ["configureAll"]}, + { "required": ["clean"]}, + { "required": ["scriptPath"]}, + { "required": ["scriptArgs"]}, + { "required": ["scriptEnv"]} + ] + } + } + ] + }, + { + "anyOf": [ + { + "not": { + "properties": { + "scriptPath": { "enum": [""]} + }, + "required": ["scriptPath"] + } + }, + { + "required": ["scriptPath"], + "properties": { + "scriptPath": { + "type": "string", + "descripttion": "The path to the script to debug", + "default": "" + }, + "scriptArgs": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "string[]" + } + ], + "description": "Arguments for the script to debug" + }, + "scriptEnv": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "string[]" + } + ], + "description": "Env for the script to debug" + }, + "pipeName": { + "type": "string", + "description": "%cmake-tools.debugger.pipeName.description%", + "default": "" + }, + "dapLog": { + "type": "string", + "description": "%cmake-tools.debugger.dapLog.description%", + "default": "" + } + }, + "not": { + "anyOf": [ + { "required": ["configureAll"]}, + { "required": ["clean"]} + ] + } + } + ] } - } + ] } } } From b517b8af3d75a780721a194be217074235f49618 Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Wed, 26 Jul 2023 16:51:25 -0400 Subject: [PATCH 03/22] made progress enabling script debugging from launch.json --- package.json | 37 +++++--------- package.nls.json | 4 ++ ...AdapterNamedPipeServerDescriptorFactory.ts | 50 ++++++++++++------- src/debug/debuggerScriptDriver.ts | 40 +++++++++++++++ 4 files changed, 87 insertions(+), 44 deletions(-) create mode 100644 src/debug/debuggerScriptDriver.ts diff --git a/package.json b/package.json index ba8925732..3f2ac7756 100644 --- a/package.json +++ b/package.json @@ -723,9 +723,9 @@ "configurationAttributes": { "launch": { "properties": { - "externalCMakeLaunch": { + "externalLaunch": { "type": "boolean", - "description": "Whether the cmake debuggee was externally launched", + "description": "%cmake-tools.debugger.externalLaunch.description", "default": false }, "pipeName": { @@ -750,30 +750,16 @@ }, "scriptPath": { "type": "string", - "descripttion": "The path to the script to debug", + "descripttion": "%cmake-tools.debugger.scriptPath.description", "default": "" }, "scriptArgs": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "string[]" - } - ], - "description": "Arguments for the script to debug" + "type": "string[]", + "description": "%cmake-tools.debugger.scriptArgs.description" }, "scriptEnv": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "string[]" - } - ], - "description": "Env for the script to debug" + "type": "string[]", + "description": "%cmake-tools.debugger.scriptEnv.description" } }, "allOf": [ @@ -781,14 +767,14 @@ "anyOf": [ { "not": { "properties": { - "externalCMakeLaunch": { "enum": [true]} + "externalLaunch": { "enum": [true]} }, - "required": ["externalCMakeLaunch"] + "required": ["externalLaunch"] }}, { "required": ["pipeName"], "properties": { - "externalCMakeLaunch": { + "externalLaunch": { "type": "boolean", "description": "Whether the cmake debuggee was externally launched", "default": false @@ -805,7 +791,8 @@ { "required": ["clean"]}, { "required": ["scriptPath"]}, { "required": ["scriptArgs"]}, - { "required": ["scriptEnv"]} + { "required": ["scriptEnv"]}, + { "required": ["dapLog"]} ] } } diff --git a/package.nls.json b/package.nls.json index 009741f8a..6336bb7d1 100644 --- a/package.nls.json +++ b/package.nls.json @@ -198,6 +198,10 @@ "cmake-tools.debugger.clean.description": "Clean prior to configuring.", "cmake-tools.debugger.configureAll.description": "Configure for all projects.", "cmake-tools.debugger.dapLog.description": "Where the debugger DAP log should be logged.", + "cmake-tools.debugger.externalLaunch.description": "Whether the cmake debuggee was externally launched.", + "cmake-tools.debugger.scriptPath.description": "The path to the script to debug", + "cmake-tools.debugger.scriptArgs.description": "Arguments for the script to debug", + "cmake-tools.debugger.scriptEnv.description": "Environment for the script to use", "cmake-tools.taskDefinitions.properties.label.description": "The name of the task", "cmake-tools.taskDefinitions.properties.command.description": "CMake command", "cmake-tools.taskDefinitions.properties.targets.description": "CMake build targets", diff --git a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts index 812983040..cddacc779 100644 --- a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts +++ b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts @@ -1,46 +1,58 @@ import { extensionManager } from "@cmt/extension"; import * as vscode from "vscode"; import { DebuggerInformation, getDebuggerPipeName } from "./debuggerConfigureDriver"; +import { executeScriptWithDebugger } from "./debuggerScriptDriver"; export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.DebugAdapterDescriptorFactory { async createDebugAdapterDescriptor(session: vscode.DebugSession, _executable: vscode.DebugAdapterExecutable | undefined): Promise> { // first invoke cmake // invoke internal methods that call into and maybe have a handler once we've got the debugger is ready const pipeName = session.configuration.pipeName ?? getDebuggerPipeName(); + + // we can only set up the dapLog from this end if it's not launched external const debuggerInformation: DebuggerInformation = { pipeName, - dapLog: session.configuration.dapLog, + dapLog: session.configuration.externalLaunch ? undefined : session.configuration.dapLog, debuggerIsReady: () => undefined }; // undocumented configuration field that lets us know if the session is being invoked from a command // This should only be used from inside the extension from a command that invokes the debugger. if (!session.configuration.fromCommand) { - if (session.configuration.request === "launch") { + if (session.configuration.request === "launch" && !session.configuration.externalLaunch) { const promise = new Promise((resolve) => { debuggerInformation.debuggerIsReady = resolve; }); - if (session.configuration.clean) { - if (session.configuration.configureAll) { - void extensionManager?.cleanConfigureAllWithDebuggerInternal( - debuggerInformation - ); - } else { - void extensionManager?.cleanConfigureWithDebuggerInternal( - debuggerInformation - ); - } + if (session.configuration.scriptPath) { + const script = session.configuration.scriptPath; + const args: string[] = session.configuration.scriptArgs; + const env = session.configuration.scriptEnv; + // TODO: Probably need to do some code that will show progress an stuff? + void executeScriptWithDebugger(script, args, env, debuggerInformation); } else { - if (session.configuration.configureAll) { - void extensionManager?.configureAllWithDebuggerInternal( - debuggerInformation - ); + if (session.configuration.clean) { + if (session.configuration.configureAll) { + void extensionManager?.cleanConfigureAllWithDebuggerInternal( + debuggerInformation + ); + } else { + void extensionManager?.cleanConfigureWithDebuggerInternal( + debuggerInformation + ); + } } else { - void extensionManager?.configureWithDebuggerInternal( - debuggerInformation - ); + if (session.configuration.configureAll) { + void extensionManager?.configureAllWithDebuggerInternal( + debuggerInformation + ); + } else { + void extensionManager?.configureWithDebuggerInternal( + debuggerInformation + ); + } } } + await promise; } } diff --git a/src/debug/debuggerScriptDriver.ts b/src/debug/debuggerScriptDriver.ts new file mode 100644 index 000000000..6c87c0fd7 --- /dev/null +++ b/src/debug/debuggerScriptDriver.ts @@ -0,0 +1,40 @@ +import { CMakeOutputConsumer, StateMessage } from '@cmt/diagnostics/cmake'; +import * as proc from '@cmt/proc'; +import { DebuggerInformation } from './debuggerConfigureDriver'; +import { getCMakeExecutableInformation } from '@cmt/cmake/cmakeExecutable'; +import { extensionManager } from '@cmt/extension'; + +export async function executeScriptWithDebugger(scriptPath: string, scriptArgs: string[], _scriptEnv: string[], debuggerInformation: DebuggerInformation): Promise { + const outputConsumer: CMakeOutputConsumer = new CMakeOutputConsumer(""); + + // TODO: Currently this is dependent on there being an active project. + const cmakePath = await extensionManager?.getActiveProject()?.getCMakePathofProject(); + if (cmakePath) { + const cmakeExe = await getCMakeExecutableInformation(cmakePath); + const concreteArgs = ["-P", scriptPath]; + concreteArgs.push("--debugger"); + concreteArgs.push("--debugger-pipe"); + concreteArgs.push(`${debuggerInformation.pipeName}`); + if (debuggerInformation.dapLog) { + concreteArgs.push("--debugger-dap-log"); + concreteArgs.push(debuggerInformation.dapLog); + } + // do some .then stuff to be able to show results? + const child = proc.execute(cmakeExe.path, concreteArgs.concat(scriptArgs), outputConsumer); + + while ( + !outputConsumer.stateMessages.includes( + StateMessage.WaitingForDebuggerClient + ) + ) { + await new Promise((resolve) => setTimeout(resolve, 50)); + } + + if (debuggerInformation.debuggerIsReady) { + debuggerInformation.debuggerIsReady(); + } + + const result = await child.result; + // TODO: some handling of the result. Maybe output the result? + } +} From bded1347aadcdf227b02f24ba7cebde5c5bf7f69 Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Wed, 2 Aug 2023 11:06:19 -0400 Subject: [PATCH 04/22] add some output messaging regarding the debugger and script --- package.json | 39 ++++++++++--------- ...AdapterNamedPipeServerDescriptorFactory.ts | 15 +++++-- src/debug/debuggerScriptDriver.ts | 20 ++++++++-- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index 3f2ac7756..29231fd7c 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "onCommand:cmake.executableTargets", "onCommand:cmake.buildKit", "onCommand:cmake.tasksBuildCommand", + "onDebugResolve:cmake", "workspaceContains:CMakeLists.txt", "workspaceContains:*/CMakeLists.txt", "workspaceContains:*/*/CMakeLists.txt", @@ -754,11 +755,19 @@ "default": "" }, "scriptArgs": { - "type": "string[]", + "type": "array", + "items": { + "type": "string" + }, + "default": [], "description": "%cmake-tools.debugger.scriptArgs.description" }, "scriptEnv": { - "type": "string[]", + "type": "array", + "items": { + "type": "string" + }, + "default": [], "description": "%cmake-tools.debugger.scriptEnv.description" } }, @@ -817,25 +826,19 @@ "default": "" }, "scriptArgs": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "string[]" - } - ], + "type": "array", + "items": { + "type": "string" + }, + "default": [], "description": "Arguments for the script to debug" }, "scriptEnv": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "string[]" - } - ], + "type": "array", + "items": { + "type": "string" + }, + "default": [], "description": "Env for the script to debug" }, "pipeName": { diff --git a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts index cddacc779..9d0bcea4e 100644 --- a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts +++ b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts @@ -2,6 +2,15 @@ import { extensionManager } from "@cmt/extension"; import * as vscode from "vscode"; import { DebuggerInformation, getDebuggerPipeName } from "./debuggerConfigureDriver"; import { executeScriptWithDebugger } from "./debuggerScriptDriver"; + +import * as logging from '../logging'; +import * as nls from "vscode-nls"; + +nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); +const localize: nls.LocalizeFunc = nls.loadMessageBundle(); + +const logger = logging.createLogger('debugger'); + export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.DebugAdapterDescriptorFactory { async createDebugAdapterDescriptor(session: vscode.DebugSession, _executable: vscode.DebugAdapterExecutable | undefined): Promise> { // first invoke cmake @@ -25,9 +34,8 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu if (session.configuration.scriptPath) { const script = session.configuration.scriptPath; - const args: string[] = session.configuration.scriptArgs; - const env = session.configuration.scriptEnv; - // TODO: Probably need to do some code that will show progress an stuff? + const args: string[] = session.configuration.scriptArgs ?? []; + const env = session.configuration.scriptEnv ?? []; void executeScriptWithDebugger(script, args, env, debuggerInformation); } else { if (session.configuration.clean) { @@ -57,6 +65,7 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu } } + logger.info(localize('debugger.create.descriptor', 'Connecting debugger on named pipe: \"{0}\"', pipeName)); return new vscode.DebugAdapterNamedPipeServer(pipeName); } } diff --git a/src/debug/debuggerScriptDriver.ts b/src/debug/debuggerScriptDriver.ts index 6c87c0fd7..4e4dbbb3d 100644 --- a/src/debug/debuggerScriptDriver.ts +++ b/src/debug/debuggerScriptDriver.ts @@ -3,11 +3,19 @@ import * as proc from '@cmt/proc'; import { DebuggerInformation } from './debuggerConfigureDriver'; import { getCMakeExecutableInformation } from '@cmt/cmake/cmakeExecutable'; import { extensionManager } from '@cmt/extension'; +import * as logging from '../logging'; +import * as nls from "vscode-nls"; + +nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); +const localize: nls.LocalizeFunc = nls.loadMessageBundle(); + +const cmakeLogger = logging.createLogger('cmake'); +const scriptLogger = logging.createLogger('cmake-script'); export async function executeScriptWithDebugger(scriptPath: string, scriptArgs: string[], _scriptEnv: string[], debuggerInformation: DebuggerInformation): Promise { - const outputConsumer: CMakeOutputConsumer = new CMakeOutputConsumer(""); + const outputConsumer: CMakeOutputConsumer = new CMakeOutputConsumer("", scriptLogger); - // TODO: Currently this is dependent on there being an active project. + // TODO: Currently this is dependent on there being an active project. We might need to grab directly from settings, but it might be fine. const cmakePath = await extensionManager?.getActiveProject()?.getCMakePathofProject(); if (cmakePath) { const cmakeExe = await getCMakeExecutableInformation(cmakePath); @@ -19,6 +27,8 @@ export async function executeScriptWithDebugger(scriptPath: string, scriptArgs: concreteArgs.push("--debugger-dap-log"); concreteArgs.push(debuggerInformation.dapLog); } + + cmakeLogger.info(localize('run.script', "Executing CMake script: \"{0}\"", scriptPath)); // do some .then stuff to be able to show results? const child = proc.execute(cmakeExe.path, concreteArgs.concat(scriptArgs), outputConsumer); @@ -35,6 +45,10 @@ export async function executeScriptWithDebugger(scriptPath: string, scriptArgs: } const result = await child.result; - // TODO: some handling of the result. Maybe output the result? + if (result.retc === 0) { + cmakeLogger.info(localize('run.script.successful', "CMake script: \"{0}\" completed successfully.", scriptPath)); + } else { + cmakeLogger.info(localize('run.script.failed', "CMake script: \"{0}\" completed unsuccessfully.", scriptPath)); + } } } From 2c7b854226f74d7e2b1196792c55af0112e95dc6 Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Wed, 2 Aug 2023 11:07:19 -0400 Subject: [PATCH 05/22] add TODO's in case I don't get to it today --- src/debug/debuggerScriptDriver.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/debug/debuggerScriptDriver.ts b/src/debug/debuggerScriptDriver.ts index 4e4dbbb3d..54c4cba4d 100644 --- a/src/debug/debuggerScriptDriver.ts +++ b/src/debug/debuggerScriptDriver.ts @@ -29,7 +29,9 @@ export async function executeScriptWithDebugger(scriptPath: string, scriptArgs: } cmakeLogger.info(localize('run.script', "Executing CMake script: \"{0}\"", scriptPath)); - // do some .then stuff to be able to show results? + + // TODO: Make sure args and environment are handled correctly. + // TODO: Possibly concatenate env with process.env, similar to how the CMake driver does it. const child = proc.execute(cmakeExe.path, concreteArgs.concat(scriptArgs), outputConsumer); while ( From e3d3703656599ff1c5f065ce5ca8b3b69c30a007 Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Wed, 2 Aug 2023 13:58:53 -0400 Subject: [PATCH 06/22] log statements, ensure package.json allows the right args in right situation, set up env for script debugging --- package.json | 27 +++++-- ...AdapterNamedPipeServerDescriptorFactory.ts | 2 +- src/debug/debuggerScriptDriver.ts | 77 ++++++++++--------- 3 files changed, 65 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index 29231fd7c..3f97b7282 100644 --- a/package.json +++ b/package.json @@ -765,9 +765,18 @@ "scriptEnv": { "type": "array", "items": { - "type": "string" + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name" + }, + "value": { + "type": "string", + "description": "Value" + } + } }, - "default": [], "description": "%cmake-tools.debugger.scriptEnv.description" } }, @@ -818,7 +827,6 @@ } }, { - "required": ["scriptPath"], "properties": { "scriptPath": { "type": "string", @@ -836,9 +844,18 @@ "scriptEnv": { "type": "array", "items": { - "type": "string" + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name" + }, + "value": { + "type": "string", + "description": "Value" + } + } }, - "default": [], "description": "Env for the script to debug" }, "pipeName": { diff --git a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts index 9d0bcea4e..13f50384c 100644 --- a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts +++ b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts @@ -35,7 +35,7 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu if (session.configuration.scriptPath) { const script = session.configuration.scriptPath; const args: string[] = session.configuration.scriptArgs ?? []; - const env = session.configuration.scriptEnv ?? []; + const env = new Map(session.configuration.scriptEnv.map((e: {name: string; value: string}) => [e.name, e.value])) ?? new Map(); void executeScriptWithDebugger(script, args, env, debuggerInformation); } else { if (session.configuration.clean) { diff --git a/src/debug/debuggerScriptDriver.ts b/src/debug/debuggerScriptDriver.ts index 54c4cba4d..6c34c2369 100644 --- a/src/debug/debuggerScriptDriver.ts +++ b/src/debug/debuggerScriptDriver.ts @@ -5,6 +5,7 @@ import { getCMakeExecutableInformation } from '@cmt/cmake/cmakeExecutable'; import { extensionManager } from '@cmt/extension'; import * as logging from '../logging'; import * as nls from "vscode-nls"; +import { EnvironmentUtils } from '@cmt/environmentVariables'; nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); const localize: nls.LocalizeFunc = nls.loadMessageBundle(); @@ -12,45 +13,51 @@ const localize: nls.LocalizeFunc = nls.loadMessageBundle(); const cmakeLogger = logging.createLogger('cmake'); const scriptLogger = logging.createLogger('cmake-script'); -export async function executeScriptWithDebugger(scriptPath: string, scriptArgs: string[], _scriptEnv: string[], debuggerInformation: DebuggerInformation): Promise { +export async function executeScriptWithDebugger(scriptPath: string, scriptArgs: string[], scriptEnv: Map, debuggerInformation: DebuggerInformation): Promise { const outputConsumer: CMakeOutputConsumer = new CMakeOutputConsumer("", scriptLogger); - // TODO: Currently this is dependent on there being an active project. We might need to grab directly from settings, but it might be fine. - const cmakePath = await extensionManager?.getActiveProject()?.getCMakePathofProject(); - if (cmakePath) { + // This is dependent on there being an active project. This feels reasonable since we're expecting them to be in a CMake project. + // However, it could be safer to simply grab the cmake path directly from the settings. + const cmakeProject = extensionManager?.getActiveProject(); + const cmakePath = await cmakeProject?.getCMakePathofProject(); + if (cmakeProject && cmakePath) { const cmakeExe = await getCMakeExecutableInformation(cmakePath); - const concreteArgs = ["-P", scriptPath]; - concreteArgs.push("--debugger"); - concreteArgs.push("--debugger-pipe"); - concreteArgs.push(`${debuggerInformation.pipeName}`); - if (debuggerInformation.dapLog) { - concreteArgs.push("--debugger-dap-log"); - concreteArgs.push(debuggerInformation.dapLog); - } - - cmakeLogger.info(localize('run.script', "Executing CMake script: \"{0}\"", scriptPath)); - - // TODO: Make sure args and environment are handled correctly. - // TODO: Possibly concatenate env with process.env, similar to how the CMake driver does it. - const child = proc.execute(cmakeExe.path, concreteArgs.concat(scriptArgs), outputConsumer); - - while ( - !outputConsumer.stateMessages.includes( - StateMessage.WaitingForDebuggerClient - ) - ) { - await new Promise((resolve) => setTimeout(resolve, 50)); - } - - if (debuggerInformation.debuggerIsReady) { - debuggerInformation.debuggerIsReady(); - } - - const result = await child.result; - if (result.retc === 0) { - cmakeLogger.info(localize('run.script.successful', "CMake script: \"{0}\" completed successfully.", scriptPath)); + if (cmakeExe.isDebuggerSupported) { + const concreteArgs = ["-P", scriptPath]; + concreteArgs.push(...scriptArgs); + concreteArgs.push("--debugger"); + concreteArgs.push("--debugger-pipe"); + concreteArgs.push(`${debuggerInformation.pipeName}`); + if (debuggerInformation.dapLog) { + concreteArgs.push("--debugger-dap-log"); + concreteArgs.push(debuggerInformation.dapLog); + } + + cmakeLogger.info(localize('run.script', "Executing CMake script: \"{0}\"", scriptPath)); + + const env = EnvironmentUtils.merge([process.env, EnvironmentUtils.create(scriptEnv)]); + const child = proc.execute(cmakeExe.path, concreteArgs, outputConsumer, { environment: env}); + + while ( + !outputConsumer.stateMessages.includes( + StateMessage.WaitingForDebuggerClient + ) + ) { + await new Promise((resolve) => setTimeout(resolve, 50)); + } + + if (debuggerInformation.debuggerIsReady) { + debuggerInformation.debuggerIsReady(); + } + + const result = await child.result; + if (result.retc === 0) { + cmakeLogger.info(localize('run.script.successful', "CMake script: \"{0}\" completed successfully.", scriptPath)); + } else { + cmakeLogger.info(localize('run.script.failed', "CMake script: \"{0}\" completed unsuccessfully.", scriptPath)); + } } else { - cmakeLogger.info(localize('run.script.failed', "CMake script: \"{0}\" completed unsuccessfully.", scriptPath)); + cmakeLogger.error(localize('run.script.cmakeDebugger.not.supported', "Cannot debug a script with this version of CMake, ensure your version of CMake supports debugging")); } } } From 5c1d651703770fb4ae6f1f2730302062a2bf2867 Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Wed, 2 Aug 2023 14:08:17 -0400 Subject: [PATCH 07/22] push worst case copying the description and settings of the debugger options --- package.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 3f97b7282..f6f0730f2 100644 --- a/package.json +++ b/package.json @@ -769,11 +769,11 @@ "properties": { "name": { "type": "string", - "description": "Name" + "description": "%cmake-tools.debugger.name%" }, "value": { "type": "string", - "description": "Value" + "description": "%cmake-tools.debugger.value%" } } }, @@ -794,7 +794,7 @@ "properties": { "externalLaunch": { "type": "boolean", - "description": "Whether the cmake debuggee was externally launched", + "description": "%cmake-tools.debugger.externalLaunch.description", "default": false }, "pipeName": { @@ -830,7 +830,7 @@ "properties": { "scriptPath": { "type": "string", - "descripttion": "The path to the script to debug", + "descripttion": "%cmake-tools.debugger.scriptPath.description", "default": "" }, "scriptArgs": { @@ -839,7 +839,7 @@ "type": "string" }, "default": [], - "description": "Arguments for the script to debug" + "description": "%cmake-tools.debugger.scriptArgs.description" }, "scriptEnv": { "type": "array", @@ -848,15 +848,15 @@ "properties": { "name": { "type": "string", - "description": "Name" + "description": "%cmake-tools.debugger.name%" }, "value": { "type": "string", - "description": "Value" + "description": "%cmake-tools.debugger.value%" } } }, - "description": "Env for the script to debug" + "description": "%cmake-tools.debugger.scriptEnv.description" }, "pipeName": { "type": "string", From ee83c45861e97c65489ef95b7bfc27727d2eac3a Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Wed, 2 Aug 2023 15:07:23 -0400 Subject: [PATCH 08/22] I think I've covered all launch config cases --- package.json | 29 +++++++++++++++++++---------- package.nls.json | 2 ++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index f6f0730f2..ff73c98f4 100644 --- a/package.json +++ b/package.json @@ -726,7 +726,7 @@ "properties": { "externalLaunch": { "type": "boolean", - "description": "%cmake-tools.debugger.externalLaunch.description", + "description": "%cmake-tools.debugger.externalLaunch.description%", "default": false }, "pipeName": { @@ -751,7 +751,7 @@ }, "scriptPath": { "type": "string", - "descripttion": "%cmake-tools.debugger.scriptPath.description", + "descripttion": "%cmake-tools.debugger.scriptPath.description%", "default": "" }, "scriptArgs": { @@ -760,7 +760,7 @@ "type": "string" }, "default": [], - "description": "%cmake-tools.debugger.scriptArgs.description" + "description": "%cmake-tools.debugger.scriptArgs.description%" }, "scriptEnv": { "type": "array", @@ -777,7 +777,7 @@ } } }, - "description": "%cmake-tools.debugger.scriptEnv.description" + "description": "%cmake-tools.debugger.scriptEnv.description%" } }, "allOf": [ @@ -790,11 +790,11 @@ "required": ["externalLaunch"] }}, { - "required": ["pipeName"], + "required": ["externalLaunch", "pipeName"], "properties": { "externalLaunch": { "type": "boolean", - "description": "%cmake-tools.debugger.externalLaunch.description", + "description": "%cmake-tools.debugger.externalLaunch.description%", "default": false }, "pipeName": { @@ -827,10 +827,11 @@ } }, { + "required": ["scriptPath"], "properties": { "scriptPath": { "type": "string", - "descripttion": "%cmake-tools.debugger.scriptPath.description", + "descripttion": "%cmake-tools.debugger.scriptPath.description%", "default": "" }, "scriptArgs": { @@ -839,7 +840,7 @@ "type": "string" }, "default": [], - "description": "%cmake-tools.debugger.scriptArgs.description" + "description": "%cmake-tools.debugger.scriptArgs.description%" }, "scriptEnv": { "type": "array", @@ -856,7 +857,7 @@ } } }, - "description": "%cmake-tools.debugger.scriptEnv.description" + "description": "%cmake-tools.debugger.scriptEnv.description%" }, "pipeName": { "type": "string", @@ -878,7 +879,15 @@ } ] } - ] + ], + "dependencies": { + "scriptEnv": [ + "scriptPath" + ], + "scriptArgs": [ + "scriptPath" + ] + } } } } diff --git a/package.nls.json b/package.nls.json index 6336bb7d1..d7689af7e 100644 --- a/package.nls.json +++ b/package.nls.json @@ -202,6 +202,8 @@ "cmake-tools.debugger.scriptPath.description": "The path to the script to debug", "cmake-tools.debugger.scriptArgs.description": "Arguments for the script to debug", "cmake-tools.debugger.scriptEnv.description": "Environment for the script to use", + "cmake-tools.debugger.name": "Name", + "cmake-tools.debugger.value": "Value", "cmake-tools.taskDefinitions.properties.label.description": "The name of the task", "cmake-tools.taskDefinitions.properties.command.description": "CMake command", "cmake-tools.taskDefinitions.properties.targets.description": "CMake build targets", From ea036b98a5389a89053a864b54196e626e906fc6 Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Thu, 3 Aug 2023 10:52:46 -0400 Subject: [PATCH 09/22] better package.json schema, though still not perfect, matches other debug types, and stub validation in code --- package.json | 226 ++++++++---------- package.nls.json | 2 +- ...AdapterNamedPipeServerDescriptorFactory.ts | 24 +- 3 files changed, 127 insertions(+), 125 deletions(-) diff --git a/package.json b/package.json index ff73c98f4..6514bd893 100644 --- a/package.json +++ b/package.json @@ -693,7 +693,7 @@ }, "options": { "type": "object", - "description": "%cmake-tools.taskDefinitions.properties.options.description", + "description": "%cmake-tools.taskDefinitions.properties.options.description%", "properties": { "cwd": { "type": "string", @@ -724,31 +724,6 @@ "configurationAttributes": { "launch": { "properties": { - "externalLaunch": { - "type": "boolean", - "description": "%cmake-tools.debugger.externalLaunch.description%", - "default": false - }, - "pipeName": { - "type": "string", - "description": "%cmake-tools.debugger.pipeName.description%", - "default": "" - }, - "clean": { - "type": "boolean", - "description": "%cmake-tools.debugger.clean.description%", - "default": false - }, - "configureAll": { - "type": "boolean", - "description": "%cmake-tools.debugger.configureAll.description%", - "default": false - }, - "dapLog": { - "type": "string", - "description": "%cmake-tools.debugger.dapLog.description%", - "default": "" - }, "scriptPath": { "type": "string", "descripttion": "%cmake-tools.debugger.scriptPath.description%", @@ -777,117 +752,124 @@ } } }, + "default": [], "description": "%cmake-tools.debugger.scriptEnv.description%" + }, + "dapLog": { + "type": "string", + "description": "%cmake-tools.debugger.dapLog.description%", + "default": "" + }, + "pipeName": { + "type": "string", + "description": "%cmake-tools.debugger.pipeName.description%", + "default": "" + }, + "clean": { + "type": "boolean", + "description": "%cmake-tools.debugger.clean.description%", + "default": false + }, + "configureAll": { + "type": "boolean", + "description": "%cmake-tools.debugger.configureAll.description%", + "default": false + }, + "cmakeDebugType": { + "type": "string", + "enum": ["configure", "external", "script"], + "description": "%cmake-tools.debugger.debugType" } }, - "allOf": [ + "required": [ + "cmakeDebugType" + ], + "oneOf": [ { - "anyOf": [ - { "not": { - "properties": { - "externalLaunch": { "enum": [true]} + "properties": { + "cmakeDebugType": { + "enum": [ + "script" + ] + }, + "scriptPath": { + "type": "string", + "description": "%cmake-tools.debugger.scriptPath.description%", + "default": "" + }, + "scriptArgs": { + "type": "array", + "items": { + "type": "string" }, - "required": ["externalLaunch"] - }}, - { - "required": ["externalLaunch", "pipeName"], - "properties": { - "externalLaunch": { - "type": "boolean", - "description": "%cmake-tools.debugger.externalLaunch.description%", - "default": false - }, - "pipeName": { - "type": "string", - "description": "%cmake-tools.debugger.pipeName.description%", - "default": "" + "default": [], + "description": "%cmake-tools.debugger.scriptArgs.description%" + }, + "scriptEnv": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "%cmake-tools.debugger.name%" + }, + "value": { + "type": "string", + "description": "%cmake-tools.debugger.value%" + } } }, - "not": { - "anyOf": [ - { "required": ["configureAll"]}, - { "required": ["clean"]}, - { "required": ["scriptPath"]}, - { "required": ["scriptArgs"]}, - { "required": ["scriptEnv"]}, - { "required": ["dapLog"]} - ] - } + "default": [], + "description": "%cmake-tools.debugger.scriptEnv.description%" + }, + "dapLog": { + "type": "string", + "description": "%cmake-tools.debugger.dapLog.description%", + "default": "" } + }, + "required": [ + "scriptPath" ] }, { - "anyOf": [ - { - "not": { - "properties": { - "scriptPath": { "enum": [""]} - }, - "required": ["scriptPath"] - } + "properties": { + "cmakeDebugType": { + "enum": [ + "configure" + ] }, - { - "required": ["scriptPath"], - "properties": { - "scriptPath": { - "type": "string", - "descripttion": "%cmake-tools.debugger.scriptPath.description%", - "default": "" - }, - "scriptArgs": { - "type": "array", - "items": { - "type": "string" - }, - "default": [], - "description": "%cmake-tools.debugger.scriptArgs.description%" - }, - "scriptEnv": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "%cmake-tools.debugger.name%" - }, - "value": { - "type": "string", - "description": "%cmake-tools.debugger.value%" - } - } - }, - "description": "%cmake-tools.debugger.scriptEnv.description%" - }, - "pipeName": { - "type": "string", - "description": "%cmake-tools.debugger.pipeName.description%", - "default": "" - }, - "dapLog": { - "type": "string", - "description": "%cmake-tools.debugger.dapLog.description%", - "default": "" - } - }, - "not": { - "anyOf": [ - { "required": ["configureAll"]}, - { "required": ["clean"]} - ] - } + "clean": { + "type": "boolean", + "description": "%cmake-tools.debugger.clean.description%", + "default": false + }, + "configureAll": { + "type": "boolean", + "description": "%cmake-tools.debugger.configureAll.description%", + "default": false + }, + "dapLog": { + "type": "string", + "description": "%cmake-tools.debugger.dapLog.description%", + "default": "" + } + } + }, + { + "properties": { + "cmakeDebugType": { + "enum": [ + "external" + ] } + }, + "required": [ + "pipeName" ] } - ], - "dependencies": { - "scriptEnv": [ - "scriptPath" - ], - "scriptArgs": [ - "scriptPath" - ] - } + ] } } } diff --git a/package.nls.json b/package.nls.json index d7689af7e..1af81b22b 100644 --- a/package.nls.json +++ b/package.nls.json @@ -198,12 +198,12 @@ "cmake-tools.debugger.clean.description": "Clean prior to configuring.", "cmake-tools.debugger.configureAll.description": "Configure for all projects.", "cmake-tools.debugger.dapLog.description": "Where the debugger DAP log should be logged.", - "cmake-tools.debugger.externalLaunch.description": "Whether the cmake debuggee was externally launched.", "cmake-tools.debugger.scriptPath.description": "The path to the script to debug", "cmake-tools.debugger.scriptArgs.description": "Arguments for the script to debug", "cmake-tools.debugger.scriptEnv.description": "Environment for the script to use", "cmake-tools.debugger.name": "Name", "cmake-tools.debugger.value": "Value", + "cmake-tools.debugger.debugType": "Type of CMake debug session", "cmake-tools.taskDefinitions.properties.label.description": "The name of the task", "cmake-tools.taskDefinitions.properties.command.description": "CMake command", "cmake-tools.taskDefinitions.properties.targets.description": "CMake build targets", diff --git a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts index 13f50384c..261b6f1f4 100644 --- a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts +++ b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts @@ -24,15 +24,31 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu debuggerIsReady: () => undefined }; + if (session.configuration.request !== "launch") { + throw new Error("TODO: Only launch request is supported"); + } + + if (session.configuration.cmakeDebugType === undefined) { + throw new Error("TODO: Must define the cmake debug type"); + } + // undocumented configuration field that lets us know if the session is being invoked from a command // This should only be used from inside the extension from a command that invokes the debugger. if (!session.configuration.fromCommand) { - if (session.configuration.request === "launch" && !session.configuration.externalLaunch) { + + // TODO: Check for conflicting types of requests from launch.json + + const cmakeDebugType: "configure" | "script" | "external" = session.configuration.cmakeDebugType; + if (cmakeDebugType === "configure" || cmakeDebugType === "script") { const promise = new Promise((resolve) => { debuggerInformation.debuggerIsReady = resolve; }); - if (session.configuration.scriptPath) { + if (cmakeDebugType === "script") { + if (session.configuration.scriptPath === undefined) { + throw new Error("TODO: In cmake debug type script, script path must be defined"); + } + const script = session.configuration.scriptPath; const args: string[] = session.configuration.scriptArgs ?? []; const env = new Map(session.configuration.scriptEnv.map((e: {name: string; value: string}) => [e.name, e.value])) ?? new Map(); @@ -62,6 +78,10 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu } await promise; + } else if (cmakeDebugType === "external") { + if (session.configuration.pipeName === undefined) { + throw new Error("TODO: In CMake Debug type external, pipeName must be defined"); + } } } From a8a372184da195c541cecfacf7f8aaba3a029179 Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Thu, 3 Aug 2023 10:57:01 -0400 Subject: [PATCH 10/22] localize error messages --- .../debugAdapterNamedPipeServerDescriptorFactory.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts index 261b6f1f4..fa6bcbc93 100644 --- a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts +++ b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts @@ -25,19 +25,16 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu }; if (session.configuration.request !== "launch") { - throw new Error("TODO: Only launch request is supported"); + throw new Error(localize("cmake.debug.only.launch.supported", "'cmake' debug type only supports the 'launch' request.")); } if (session.configuration.cmakeDebugType === undefined) { - throw new Error("TODO: Must define the cmake debug type"); + throw new Error(localize("cmake.debug.must.define.debugType", "The 'cmake' debug type requires you to define the 'cmakeDebugType'. Available options are 'configure', 'external', and 'script'.")); } // undocumented configuration field that lets us know if the session is being invoked from a command // This should only be used from inside the extension from a command that invokes the debugger. if (!session.configuration.fromCommand) { - - // TODO: Check for conflicting types of requests from launch.json - const cmakeDebugType: "configure" | "script" | "external" = session.configuration.cmakeDebugType; if (cmakeDebugType === "configure" || cmakeDebugType === "script") { const promise = new Promise((resolve) => { @@ -46,7 +43,7 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu if (cmakeDebugType === "script") { if (session.configuration.scriptPath === undefined) { - throw new Error("TODO: In cmake debug type script, script path must be defined"); + throw new Error(localize("cmake.debug.script.requires.scriptPath", "The 'cmake' debug type with 'cmakeDebugType' set to 'script' requires you to define 'scriptPath'.")); } const script = session.configuration.scriptPath; @@ -80,7 +77,7 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu await promise; } else if (cmakeDebugType === "external") { if (session.configuration.pipeName === undefined) { - throw new Error("TODO: In CMake Debug type external, pipeName must be defined"); + throw new Error(localize("cmake.debug.external.requires.pipeName", "The 'cmake' debug type with 'cmakeDebugType' set to 'external' requires you to define 'pipeName'.")); } } } From 663fa088ab59cd1c02fabe2633e25f466cc8760f Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Thu, 3 Aug 2023 10:57:17 -0400 Subject: [PATCH 11/22] add 'The' --- src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts index fa6bcbc93..564da180a 100644 --- a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts +++ b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts @@ -25,7 +25,7 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu }; if (session.configuration.request !== "launch") { - throw new Error(localize("cmake.debug.only.launch.supported", "'cmake' debug type only supports the 'launch' request.")); + throw new Error(localize("cmake.debug.only.launch.supported", "The 'cmake' debug type only supports the 'launch' request.")); } if (session.configuration.cmakeDebugType === undefined) { From 264a80008683f15aa0bdf912dcd493b61fc285db Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Thu, 3 Aug 2023 11:02:59 -0400 Subject: [PATCH 12/22] switch to double quotes --- src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts index 564da180a..8874e6688 100644 --- a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts +++ b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts @@ -25,11 +25,11 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu }; if (session.configuration.request !== "launch") { - throw new Error(localize("cmake.debug.only.launch.supported", "The 'cmake' debug type only supports the 'launch' request.")); + throw new Error(localize("cmake.debug.only.launch.supported", "The \"cmake\" debug type only supports the \"launch\" request.")); } if (session.configuration.cmakeDebugType === undefined) { - throw new Error(localize("cmake.debug.must.define.debugType", "The 'cmake' debug type requires you to define the 'cmakeDebugType'. Available options are 'configure', 'external', and 'script'.")); + throw new Error(localize("cmake.debug.must.define.debugType", "The \"cmake\" debug type requires you to define the \"cmakeDebugType\". Available options are \"configure\", \"external\", and \"script\".")); } // undocumented configuration field that lets us know if the session is being invoked from a command @@ -43,7 +43,7 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu if (cmakeDebugType === "script") { if (session.configuration.scriptPath === undefined) { - throw new Error(localize("cmake.debug.script.requires.scriptPath", "The 'cmake' debug type with 'cmakeDebugType' set to 'script' requires you to define 'scriptPath'.")); + throw new Error(localize("cmake.debug.script.requires.scriptPath", "The \"cmake\" debug type with \"cmakeDebugType\" set to \"script\" requires you to define \"scriptPath\".")); } const script = session.configuration.scriptPath; @@ -77,7 +77,7 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu await promise; } else if (cmakeDebugType === "external") { if (session.configuration.pipeName === undefined) { - throw new Error(localize("cmake.debug.external.requires.pipeName", "The 'cmake' debug type with 'cmakeDebugType' set to 'external' requires you to define 'pipeName'.")); + throw new Error(localize("cmake.debug.external.requires.pipeName", "The \"cmake\" debug type with \"cmakeDebugType\" set to \"external\" requires you to define \"pipeName\".")); } } } From 0484233c12b43ac7c259631dacb9f1bf99ed101d Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Thu, 3 Aug 2023 11:24:55 -0400 Subject: [PATCH 13/22] add docs page for debugging --- docs/debug.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ package.nls.json | 8 ++++---- 2 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 docs/debug.md diff --git a/docs/debug.md b/docs/debug.md new file mode 100644 index 000000000..12289d0be --- /dev/null +++ b/docs/debug.md @@ -0,0 +1,48 @@ +# CMake Debugging + +Starting with CMake 3.27, debugging CMake is now supported in CMake Tools! + +The following documentation will help you understand the various ways you can debug CMake. + +## Debugging from CMake Tools UI entry points + +The most common reason to debug CMake is to debug CMake Configuration! There are many ways that you can accomplish this: + +* Commands + * CMake: Configure with CMake Debugger + * CMake: Delete Cache and Reconfigure with CMake Debugger +* Folder Explorer + * Right click on CMakeLists.txt context menu entry. +* Project Outline + * Right click on CMakeLists.txt context menu entry. + * Expand the "..." in the project outline. There is an entry to use the Debugger! + +## Debugging from CMake Tools launch.json + +CMake Tools now provides a new debug type `cmake`! + +The `cmake` debug type supports three different types of `cmakeDebugType`: `configure`, `external`, `script`. They each come with their own settings that can be used to modify and control the debug session! + +Listed below are the settings that are available for each configuration based on `cmakeDebugType`: + +* `configure` + * required + * optional + * `pipeName` - Name of the pipe (on Windows) or domain socket (on Unix) to use for debugger communication. + * `clean` - Clean prior to configuring. + * `configureAll` - Configure for all projects. + * `dapLog` - Where the debugger DAP log should be logged. +* `external` + * required + * `pipeName` - Name of the pipe (on Windows) or domain socket (on Unix) to use for debugger communication. + * optional +* `script` + * required + * `scriptPath` - The path to the script to debug. + * optional + * `scriptArgs` - Arguments for the script to debug. + * `scriptEnv` - Environment for the script to use. + * `pipeName` - Name of the pipe (on Windows) or domain socket (on Unix) to use for debugger communication. + * `dapLog` - Where the debugger DAP log should be logged. + +The `cmake` debug type only supports the `request` type: `launch`. diff --git a/package.nls.json b/package.nls.json index 1af81b22b..c135a613a 100644 --- a/package.nls.json +++ b/package.nls.json @@ -198,12 +198,12 @@ "cmake-tools.debugger.clean.description": "Clean prior to configuring.", "cmake-tools.debugger.configureAll.description": "Configure for all projects.", "cmake-tools.debugger.dapLog.description": "Where the debugger DAP log should be logged.", - "cmake-tools.debugger.scriptPath.description": "The path to the script to debug", - "cmake-tools.debugger.scriptArgs.description": "Arguments for the script to debug", - "cmake-tools.debugger.scriptEnv.description": "Environment for the script to use", + "cmake-tools.debugger.scriptPath.description": "The path to the script to debug.", + "cmake-tools.debugger.scriptArgs.description": "Arguments for the script to debug.", + "cmake-tools.debugger.scriptEnv.description": "Environment for the script to use.", "cmake-tools.debugger.name": "Name", "cmake-tools.debugger.value": "Value", - "cmake-tools.debugger.debugType": "Type of CMake debug session", + "cmake-tools.debugger.debugType": "The type of the CMake debug session. Available options are: \"configure\", \"external\", \"script\".", "cmake-tools.taskDefinitions.properties.label.description": "The name of the task", "cmake-tools.taskDefinitions.properties.command.description": "CMake command", "cmake-tools.taskDefinitions.properties.targets.description": "CMake build targets", From fedd875543a9bc2cabeb8dc3e10505a134dd49d4 Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Thu, 3 Aug 2023 11:39:18 -0400 Subject: [PATCH 14/22] slight modifications --- package.json | 2 +- package.nls.json | 2 +- ...gAdapterNamedPipeServerDescriptorFactory.ts | 18 +++++++----------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 6514bd893..2b251a8a8 100644 --- a/package.json +++ b/package.json @@ -778,7 +778,7 @@ "cmakeDebugType": { "type": "string", "enum": ["configure", "external", "script"], - "description": "%cmake-tools.debugger.debugType" + "description": "%cmake-tools.debugger.debugType.description%" } }, "required": [ diff --git a/package.nls.json b/package.nls.json index c135a613a..7322d1b27 100644 --- a/package.nls.json +++ b/package.nls.json @@ -203,7 +203,7 @@ "cmake-tools.debugger.scriptEnv.description": "Environment for the script to use.", "cmake-tools.debugger.name": "Name", "cmake-tools.debugger.value": "Value", - "cmake-tools.debugger.debugType": "The type of the CMake debug session. Available options are: \"configure\", \"external\", \"script\".", + "cmake-tools.debugger.debugType.description": "The type of the CMake debug session. Available options are: \"configure\", \"external\", \"script\".", "cmake-tools.taskDefinitions.properties.label.description": "The name of the task", "cmake-tools.taskDefinitions.properties.command.description": "CMake command", "cmake-tools.taskDefinitions.properties.targets.description": "CMake build targets", diff --git a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts index 8874e6688..86d8e8430 100644 --- a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts +++ b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts @@ -13,17 +13,6 @@ const logger = logging.createLogger('debugger'); export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.DebugAdapterDescriptorFactory { async createDebugAdapterDescriptor(session: vscode.DebugSession, _executable: vscode.DebugAdapterExecutable | undefined): Promise> { - // first invoke cmake - // invoke internal methods that call into and maybe have a handler once we've got the debugger is ready - const pipeName = session.configuration.pipeName ?? getDebuggerPipeName(); - - // we can only set up the dapLog from this end if it's not launched external - const debuggerInformation: DebuggerInformation = { - pipeName, - dapLog: session.configuration.externalLaunch ? undefined : session.configuration.dapLog, - debuggerIsReady: () => undefined - }; - if (session.configuration.request !== "launch") { throw new Error(localize("cmake.debug.only.launch.supported", "The \"cmake\" debug type only supports the \"launch\" request.")); } @@ -32,6 +21,13 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu throw new Error(localize("cmake.debug.must.define.debugType", "The \"cmake\" debug type requires you to define the \"cmakeDebugType\". Available options are \"configure\", \"external\", and \"script\".")); } + const pipeName = session.configuration.pipeName ?? getDebuggerPipeName(); + const debuggerInformation: DebuggerInformation = { + pipeName, + dapLog: session.configuration.dapLog, + debuggerIsReady: () => undefined + }; + // undocumented configuration field that lets us know if the session is being invoked from a command // This should only be used from inside the extension from a command that invokes the debugger. if (!session.configuration.fromCommand) { From 08511df8d645751a8b566ae2fe8a971267f14122 Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Fri, 4 Aug 2023 09:55:18 -0400 Subject: [PATCH 15/22] didn't handle case where scriptEnv was undefined --- src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts index 86d8e8430..015663503 100644 --- a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts +++ b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts @@ -44,7 +44,7 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu const script = session.configuration.scriptPath; const args: string[] = session.configuration.scriptArgs ?? []; - const env = new Map(session.configuration.scriptEnv.map((e: {name: string; value: string}) => [e.name, e.value])) ?? new Map(); + const env = new Map(session.configuration.scriptEnv?.map((e: {name: string; value: string}) => [e.name, e.value])) ?? new Map(); void executeScriptWithDebugger(script, args, env, debuggerInformation); } else { if (session.configuration.clean) { From 921de878510ce2482af1ddbeb3393f9eb22246a1 Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Thu, 10 Aug 2023 12:33:33 -0400 Subject: [PATCH 16/22] add configurationSnippets --- package.json | 42 ++++++++++++++++++++++++++++++++++++++++-- package.nls.json | 9 +++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 2b251a8a8..08fcda105 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "vscode": "^1.63.0" }, "categories": [ - "Other" + "Other", + "Debuggers" ], "galleryBanner": { "color": "#13578c", @@ -50,6 +51,7 @@ "onCommand:cmake.buildKit", "onCommand:cmake.tasksBuildCommand", "onDebugResolve:cmake", + "onDebugInitialConfigurations", "workspaceContains:CMakeLists.txt", "workspaceContains:*/CMakeLists.txt", "workspaceContains:*/*/CMakeLists.txt", @@ -871,7 +873,43 @@ } ] } - } + }, + "configurationSnippets": [ + { + "label": "%cmake-tools.debugger.configure.snippet.label%", + "description": "%cmake-tools.debugger.configure.snippet.description%", + "body": { + "type": "cmake", + "request": "launch", + "name": "%cmake-tools.debugger.configure.snippet.body.name%", + "cmakeDebugType": "configure", + "clean": false, + "configureAll": false + } + }, + { + "label": "%cmake-tools.debugger.script.snippet.label%", + "description": "%cmake-tools.debugger.script.snippet.description%", + "body": { + "type": "cmake", + "request": "launch", + "name": "%cmake-tools.debugger.script.snippet.body.name%", + "cmakeDebugType": "script", + "scriptPath": "^\"\\${workspaceFolder}/<...>\"" + } + }, + { + "label": "%cmake-tools.debugger.external.snippet.label%", + "description": "%cmake-tools.debugger.external.snippet.description%", + "body": { + "type": "cmake", + "request": "launch", + "name": "%cmake-tools.debugger.external.snippet.body.name%", + "cmakeDebugType": "external", + "pipeName": "<...>" + } + } + ] } ], "menus": { diff --git a/package.nls.json b/package.nls.json index 7322d1b27..9bb875c9b 100644 --- a/package.nls.json +++ b/package.nls.json @@ -204,6 +204,15 @@ "cmake-tools.debugger.name": "Name", "cmake-tools.debugger.value": "Value", "cmake-tools.debugger.debugType.description": "The type of the CMake debug session. Available options are: \"configure\", \"external\", \"script\".", + "cmake-tools.debugger.configure.snippet.label": "CMake: Configure", + "cmake-tools.debugger.configure.snippet.description": "Debug a CMake project configuration", + "cmake-tools.debugger.configure.snippet.body.name": "CMake: Configure project", + "cmake-tools.debugger.script.snippet.label": "CMake: Script", + "cmake-tools.debugger.script.snippet.description": "Debug a CMake script", + "cmake-tools.debugger.script.snippet.body.name": "CMake: Script debugging", + "cmake-tools.debugger.external.snippet.label": "CMake: External", + "cmake-tools.debugger.external.snippet.description": "Connect to an externally launched CMake invocation", + "cmake-tools.debugger.external.snippet.body.name": "CMake: Externally launched", "cmake-tools.taskDefinitions.properties.label.description": "The name of the task", "cmake-tools.taskDefinitions.properties.command.description": "CMake command", "cmake-tools.taskDefinitions.properties.targets.description": "CMake build targets", From b63c7d37f4142e02f1d9c681fe4eb87232ee6291 Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Thu, 10 Aug 2023 12:34:03 -0400 Subject: [PATCH 17/22] add stub for debugconfigurationprovider --- src/debug/debugConfigurationProvider.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/debug/debugConfigurationProvider.ts diff --git a/src/debug/debugConfigurationProvider.ts b/src/debug/debugConfigurationProvider.ts new file mode 100644 index 000000000..1853e3892 --- /dev/null +++ b/src/debug/debugConfigurationProvider.ts @@ -0,0 +1,5 @@ +import * as vscode from "vscode"; + +export class DebugConfigurationProvider implements vscode.DebugConfigurationProvider { + +} From 496e4e0205c0a9a55689ab8115819744475b868f Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Thu, 10 Aug 2023 14:00:18 -0400 Subject: [PATCH 18/22] add ability to 'run and debug' without launch.json on *.cmake files --- package.json | 1 + src/debug/debugConfigurationProvider.ts | 17 +++++++++++++++++ src/extension.ts | 3 +++ 3 files changed, 21 insertions(+) diff --git a/package.json b/package.json index 08fcda105..c56433d55 100644 --- a/package.json +++ b/package.json @@ -874,6 +874,7 @@ ] } }, + "initialConfigurations": [], "configurationSnippets": [ { "label": "%cmake-tools.debugger.configure.snippet.label%", diff --git a/src/debug/debugConfigurationProvider.ts b/src/debug/debugConfigurationProvider.ts index 1853e3892..b919d5d18 100644 --- a/src/debug/debugConfigurationProvider.ts +++ b/src/debug/debugConfigurationProvider.ts @@ -1,5 +1,22 @@ import * as vscode from "vscode"; +import * as nls from "vscode-nls"; + +nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); +const localize: nls.LocalizeFunc = nls.loadMessageBundle(); export class DebugConfigurationProvider implements vscode.DebugConfigurationProvider { + resolveDebugConfiguration(_folder: vscode.WorkspaceFolder | undefined, debugConfiguration: vscode.DebugConfiguration, _token?: vscode.CancellationToken | undefined): vscode.ProviderResult { + if (!debugConfiguration.type && !debugConfiguration.request && !debugConfiguration.name) { + const editor = vscode.window.activeTextEditor; + if (editor && editor.document.fileName.endsWith(".cmake")) { + debugConfiguration.type = "cmake"; + debugConfiguration.name = localize("cmake.debug.without.launch", "Debugging cmake script with default launch"); + debugConfiguration.request = "launch"; + debugConfiguration.cmakeDebugType = "script"; + debugConfiguration.scriptPath = editor.document.fileName; + } + } + return debugConfiguration; + } } diff --git a/src/extension.ts b/src/extension.ts index 3ff57cfb0..7ff4e4f68 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -46,6 +46,7 @@ import { StatusBar } from '@cmt/status'; import { DebugAdapterNamedPipeServerDescriptorFactory } from './debug/debugAdapterNamedPipeServerDescriptorFactory'; import { getCMakeExecutableInformation } from './cmake/cmakeExecutable'; import { DebuggerInformation, getDebuggerPipeName } from './debug/debuggerConfigureDriver'; +import { DebugConfigurationProvider } from './debug/debugConfigurationProvider'; nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); const localize: nls.LocalizeFunc = nls.loadMessageBundle(); @@ -1742,6 +1743,8 @@ async function setup(context: vscode.ExtensionContext, progress?: ProgressHandle ) ); + context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider("cmake", new DebugConfigurationProvider())); + // List of functions that will be bound commands const funs: (keyof ExtensionManager)[] = [ 'activeFolderName', From 9f1b1b52300caa9624d73076d37452aeb3b623db Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Thu, 10 Aug 2023 14:34:15 -0400 Subject: [PATCH 19/22] modify when we sanity check --- ...AdapterNamedPipeServerDescriptorFactory.ts | 20 +++-------- src/debug/debugConfigurationProvider.ts | 36 +++++++++++++++++++ src/debug/debuggerScriptDriver.ts | 1 + 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts index 015663503..d7b77ebac 100644 --- a/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts +++ b/src/debug/debugAdapterNamedPipeServerDescriptorFactory.ts @@ -5,6 +5,7 @@ import { executeScriptWithDebugger } from "./debuggerScriptDriver"; import * as logging from '../logging'; import * as nls from "vscode-nls"; +import { fs } from "../pr"; nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })(); const localize: nls.LocalizeFunc = nls.loadMessageBundle(); @@ -13,14 +14,6 @@ const logger = logging.createLogger('debugger'); export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.DebugAdapterDescriptorFactory { async createDebugAdapterDescriptor(session: vscode.DebugSession, _executable: vscode.DebugAdapterExecutable | undefined): Promise> { - if (session.configuration.request !== "launch") { - throw new Error(localize("cmake.debug.only.launch.supported", "The \"cmake\" debug type only supports the \"launch\" request.")); - } - - if (session.configuration.cmakeDebugType === undefined) { - throw new Error(localize("cmake.debug.must.define.debugType", "The \"cmake\" debug type requires you to define the \"cmakeDebugType\". Available options are \"configure\", \"external\", and \"script\".")); - } - const pipeName = session.configuration.pipeName ?? getDebuggerPipeName(); const debuggerInformation: DebuggerInformation = { pipeName, @@ -38,11 +31,10 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu }); if (cmakeDebugType === "script") { - if (session.configuration.scriptPath === undefined) { - throw new Error(localize("cmake.debug.script.requires.scriptPath", "The \"cmake\" debug type with \"cmakeDebugType\" set to \"script\" requires you to define \"scriptPath\".")); - } - const script = session.configuration.scriptPath; + if (!fs.existsSync(script)) { + throw new Error(localize("cmake.debug.scriptPath.does.not.exist", "The script path, \"{0}\", could not be found.", script)); + } const args: string[] = session.configuration.scriptArgs ?? []; const env = new Map(session.configuration.scriptEnv?.map((e: {name: string; value: string}) => [e.name, e.value])) ?? new Map(); void executeScriptWithDebugger(script, args, env, debuggerInformation); @@ -71,10 +63,6 @@ export class DebugAdapterNamedPipeServerDescriptorFactory implements vscode.Debu } await promise; - } else if (cmakeDebugType === "external") { - if (session.configuration.pipeName === undefined) { - throw new Error(localize("cmake.debug.external.requires.pipeName", "The \"cmake\" debug type with \"cmakeDebugType\" set to \"external\" requires you to define \"pipeName\".")); - } } } diff --git a/src/debug/debugConfigurationProvider.ts b/src/debug/debugConfigurationProvider.ts index b919d5d18..73de3845f 100644 --- a/src/debug/debugConfigurationProvider.ts +++ b/src/debug/debugConfigurationProvider.ts @@ -14,6 +14,42 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv debugConfiguration.request = "launch"; debugConfiguration.cmakeDebugType = "script"; debugConfiguration.scriptPath = editor.document.fileName; + } else { + throw new Error (localize("cmake.debugging.not.supported", "CMake does not support automatic debugging for this file")); + } + } + + if (debugConfiguration.request !== "launch") { + throw new Error( + localize( + "cmake.debug.only.launch.supported", + 'The "cmake" debug type only supports the "launch" request.' + ) + ); + } + + if (debugConfiguration.cmakeDebugType === undefined) { + throw new Error( + localize( + "cmake.debug.must.define.debugType", + 'The "cmake" debug type requires you to define the "cmakeDebugType". Available options are "configure", "external", and "script".' + ) + ); + } else { + if (debugConfiguration.cmakeDebugType === "external" && debugConfiguration.pipeName === undefined) { + throw new Error( + localize( + "cmake.debug.external.requires.pipeName", + 'The "cmake" debug type with "cmakeDebugType" set to "external" requires you to define "pipeName".' + ) + ); + } else if (debugConfiguration.cmakeDebugType === "script" && debugConfiguration.scriptPath === undefined) { + throw new Error( + localize( + "cmake.debug.script.requires.scriptPath", + 'The "cmake" debug type with "cmakeDebugType" set to "script" requires you to define "scriptPath".' + ) + ); } } diff --git a/src/debug/debuggerScriptDriver.ts b/src/debug/debuggerScriptDriver.ts index 6c34c2369..77e2a2604 100644 --- a/src/debug/debuggerScriptDriver.ts +++ b/src/debug/debuggerScriptDriver.ts @@ -55,6 +55,7 @@ export async function executeScriptWithDebugger(scriptPath: string, scriptArgs: cmakeLogger.info(localize('run.script.successful', "CMake script: \"{0}\" completed successfully.", scriptPath)); } else { cmakeLogger.info(localize('run.script.failed', "CMake script: \"{0}\" completed unsuccessfully.", scriptPath)); + throw new Error("HEY"); } } else { cmakeLogger.error(localize('run.script.cmakeDebugger.not.supported', "Cannot debug a script with this version of CMake, ensure your version of CMake supports debugging")); From bb7a69fb0e72e810ee42f27f40d37e97214cbcef Mon Sep 17 00:00:00 2001 From: Garrett Campbell Date: Mon, 21 Aug 2023 07:40:30 -0400 Subject: [PATCH 20/22] make adjustments based on feedback and add automatic configuration --- docs/README.md | 1 + docs/debug.md | 54 ++++++++++++++++++------- package.json | 8 +++- src/debug/debugConfigurationProvider.ts | 22 +++++++++- src/debug/debuggerScriptDriver.ts | 2 +- src/extension.ts | 8 +++- 6 files changed, 74 insertions(+), 21 deletions(-) diff --git a/docs/README.md b/docs/README.md index d4e306668..970f463ca 100644 --- a/docs/README.md +++ b/docs/README.md @@ -41,6 +41,7 @@ CMake Tools is an extension designed to make it easy to work with CMake-based pr * [Quick debugging](debug-launch.md#quick-debugging) * [Debug using a launch.json file](debug-launch.md#debug-using-a-launchjson-file) * [Run without debugging](debug-launch.md#run-without-debugging) +* [Debugging CMake](debug.md) [Configure CMake Tools settings](cmake-settings.md) * [CMake Tools settings](cmake-settings.md#cmake-settings) diff --git a/docs/debug.md b/docs/debug.md index 12289d0be..1d113c6f0 100644 --- a/docs/debug.md +++ b/docs/debug.md @@ -1,48 +1,72 @@ # CMake Debugging -Starting with CMake 3.27, debugging CMake is now supported in CMake Tools! +Starting with CMake 3.27, debugging CMake is supported in CMake Tools. -The following documentation will help you understand the various ways you can debug CMake. +The following documentation will help you understand the various ways you can debug CMake scripts and cache generation. ## Debugging from CMake Tools UI entry points -The most common reason to debug CMake is to debug CMake Configuration! There are many ways that you can accomplish this: +The most common reason to debug CMake scripts and cache generation is to debug CMake cache generation. There are many ways that you can accomplish this: * Commands * CMake: Configure with CMake Debugger * CMake: Delete Cache and Reconfigure with CMake Debugger * Folder Explorer - * Right click on CMakeLists.txt context menu entry. + * Right click on CMakeLists.txt -> Configure All Projects with CMake Debugger. * Project Outline - * Right click on CMakeLists.txt context menu entry. - * Expand the "..." in the project outline. There is an entry to use the Debugger! + * Right click on CMakeLists.txt -> Configure All Projects with CMake Debugger. + * Expand the "..." in the project outline. There is an entry to use the Debugger. -## Debugging from CMake Tools launch.json +## Debugging from launch.json -CMake Tools now provides a new debug type `cmake`! +CMake Tools provides a new debug type `cmake`. -The `cmake` debug type supports three different types of `cmakeDebugType`: `configure`, `external`, `script`. They each come with their own settings that can be used to modify and control the debug session! +The `cmake` debug type supports three different types of `cmakeDebugType`: `configure`, `external`, `script`. They each come with their own settings that can be used to modify and control the debug session. + +### Example launch.json + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "type": "cmake", + "request": "launch", + "name": "CMake script debugging", + "cmakeDebugType": "script", + "scriptPath": "${workspaceFolder}/