Add script mode and ability to connect to externally launched CMake process. (#3277)
* storing initial thoughts * rough version of trying to work on new options for debugger configurations * made progress enabling script debugging from launch.json * add some output messaging regarding the debugger and script * add TODO's in case I don't get to it today * log statements, ensure package.json allows the right args in right situation, set up env for script debugging * push worst case copying the description and settings of the debugger options * I think I've covered all launch config cases * better package.json schema, though still not perfect, matches other debug types, and stub validation in code * localize error messages * add 'The' * switch to double quotes * add docs page for debugging * slight modifications * didn't handle case where scriptEnv was undefined * add configurationSnippets * add stub for debugconfigurationprovider * add ability to 'run and debug' without launch.json on *.cmake files * modify when we sanity check * make adjustments based on feedback and add automatic configuration * ensure that configure with debugger works with the right format * update changelog
This commit is contained in:
Родитель
b4bd31490b
Коммит
661e9ed3e3
|
@ -8,6 +8,7 @@ Features:
|
|||
Improvements:
|
||||
- Updated debugging documentation to add the LLDB configuration needed for macOS. [PR #3332](https://github.com/microsoft/vscode-cmake-tools/pull/3332) [@slhck](https://github.com/slhck)
|
||||
- In multi-root workspace, the Project Outline View now shows all configured projects. [PR #3270](https://github.com/microsoft/vscode-cmake-tools/pull/3270) [@vlavati](https://github.com/vlavati)
|
||||
- Added script mode and ability to connect to externally launched CMake processes. [PR #3277](https://github.com/microsoft/vscode-cmake-tools/pull/3277)
|
||||
|
||||
## 1.15
|
||||
Features:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# CMake Debugging
|
||||
|
||||
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 scripts and cache generation.
|
||||
|
||||
## Debugging from CMake Tools UI entry points
|
||||
|
||||
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 -> Configure All Projects with CMake Debugger.
|
||||
* Project Outline
|
||||
* 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 launch.json
|
||||
|
||||
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.
|
||||
|
||||
### Example launch.json
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "cmake",
|
||||
"request": "launch",
|
||||
"name": "CMake script debugging",
|
||||
"cmakeDebugType": "script",
|
||||
"scriptPath": "${workspaceFolder}/<script>.cmake"
|
||||
},
|
||||
{
|
||||
"type": "cmake",
|
||||
"request": "launch",
|
||||
"name": "Debug externally launched CMake process",
|
||||
"cmakeDebugType": "external",
|
||||
"pipeName": "<insert-pipe-name>"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Listed below are the settings that are available for each configuration based on `cmakeDebugType`:
|
||||
|
||||
* `configure`
|
||||
* required: none
|
||||
* 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 debug adapter protocol (DAP) communication should be logged. If omitted, DAP communication is not 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 CMake script to debug.
|
||||
* optional
|
||||
* `scriptArgs` - Arguments for the CMake script to debug.
|
||||
* `scriptEnv` - Environment for the CMake script to use.
|
||||
* `pipeName` - Name of the pipe (on Windows) or domain socket (on Unix) to use for debugger communication.
|
||||
* `dapLog` - Where the debug adapter protocol (DAP) communication should be logged. If omitted, DAP communication is not logged.
|
||||
|
||||
The `cmake` debug type only supports the `request` type: `launch`.
|
186
package.json
186
package.json
|
@ -24,7 +24,8 @@
|
|||
"vscode": "^1.63.0"
|
||||
},
|
||||
"categories": [
|
||||
"Other"
|
||||
"Other",
|
||||
"Debuggers"
|
||||
],
|
||||
"galleryBanner": {
|
||||
"color": "#13578c",
|
||||
|
@ -49,6 +50,9 @@
|
|||
"onCommand:cmake.executableTargets",
|
||||
"onCommand:cmake.buildKit",
|
||||
"onCommand:cmake.tasksBuildCommand",
|
||||
"onDebugResolve:cmake",
|
||||
"onDebugInitialConfigurations",
|
||||
"onDebugDynamicConfigurations:cmake",
|
||||
"workspaceContains:CMakeLists.txt",
|
||||
"workspaceContains:*/CMakeLists.txt",
|
||||
"workspaceContains:*/*/CMakeLists.txt",
|
||||
|
@ -692,7 +696,7 @@
|
|||
},
|
||||
"options": {
|
||||
"type": "object",
|
||||
"description": "%cmake-tools.taskDefinitions.properties.options.description",
|
||||
"description": "%cmake-tools.taskDefinitions.properties.options.description%",
|
||||
"properties": {
|
||||
"cwd": {
|
||||
"type": "string",
|
||||
|
@ -720,12 +724,52 @@
|
|||
{
|
||||
"type": "cmake",
|
||||
"label": "%cmake-tools.debugger.label%",
|
||||
"languages": [
|
||||
"cmake"
|
||||
],
|
||||
"configurationAttributes": {
|
||||
"launch": {
|
||||
"properties": {
|
||||
"scriptPath": {
|
||||
"type": "string",
|
||||
"descripttion": "%cmake-tools.debugger.scriptPath.description%",
|
||||
"default": "script.cmake"
|
||||
},
|
||||
"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%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"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%"
|
||||
"description": "%cmake-tools.debugger.pipeName.description%",
|
||||
"default": ""
|
||||
},
|
||||
"clean": {
|
||||
"type": "boolean",
|
||||
|
@ -737,14 +781,140 @@
|
|||
"description": "%cmake-tools.debugger.configureAll.description%",
|
||||
"default": false
|
||||
},
|
||||
"dapLog": {
|
||||
"cmakeDebugType": {
|
||||
"type": "string",
|
||||
"description": "%cmake-tools.debugger.dapLog.description%",
|
||||
"default": ""
|
||||
}
|
||||
"enum": ["configure", "external", "script"],
|
||||
"description": "%cmake-tools.debugger.debugType.description%"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"cmakeDebugType"
|
||||
],
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"cmakeDebugType": {
|
||||
"enum": [
|
||||
"script"
|
||||
]
|
||||
},
|
||||
"scriptPath": {
|
||||
"type": "string",
|
||||
"description": "%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%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"default": [],
|
||||
"description": "%cmake-tools.debugger.scriptEnv.description%"
|
||||
},
|
||||
"dapLog": {
|
||||
"type": "string",
|
||||
"description": "%cmake-tools.debugger.dapLog.description%",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"scriptPath"
|
||||
]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"cmakeDebugType": {
|
||||
"enum": [
|
||||
"configure"
|
||||
]
|
||||
},
|
||||
"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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"initialConfigurations": [],
|
||||
"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}/<...>.cmake\""
|
||||
}
|
||||
},
|
||||
{
|
||||
"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": {
|
||||
|
|
|
@ -205,6 +205,21 @@
|
|||
"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.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",
|
||||
|
|
|
@ -47,7 +47,7 @@ import { PresetsController } from './presetsController';
|
|||
import paths from './paths';
|
||||
import { ProjectController } from './projectController';
|
||||
import { MessageItem } from 'vscode';
|
||||
import { DebugTrackerFactory, DebuggerInformation } from './debug/debuggerConfigureDriver';
|
||||
import { DebugTrackerFactory, DebuggerInformation, getDebuggerPipeName } from './debug/debuggerConfigureDriver';
|
||||
|
||||
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
|
||||
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
|
||||
|
@ -1392,7 +1392,9 @@ export class CMakeProject {
|
|||
{title: localize('no.configureWithDebugger.button', 'Cancel')})
|
||||
.then(async chosen => {
|
||||
if (chosen && chosen.title === yesButtonTitle) {
|
||||
await this.configureInternal(trigger, extraArgs, ConfigureType.NormalWithDebugger);
|
||||
await this.configureInternal(trigger, extraArgs, ConfigureType.NormalWithDebugger, {
|
||||
pipeName: getDebuggerPipeName()
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
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";
|
||||
import { fs } from "../pr";
|
||||
|
||||
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<vscode.ProviderResult<vscode.DebugAdapterDescriptor>> {
|
||||
// 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();
|
||||
const debuggerInformation: DebuggerInformation = {
|
||||
pipeName,
|
||||
|
@ -15,35 +24,49 @@ 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<void>((resolve) => {
|
||||
debuggerInformation.debuggerIsReady = resolve;
|
||||
});
|
||||
const cmakeDebugType: "configure" | "script" | "external" = session.configuration.cmakeDebugType;
|
||||
if (cmakeDebugType === "configure" || cmakeDebugType === "script") {
|
||||
const promise = new Promise<void>((resolve) => {
|
||||
debuggerInformation.debuggerIsReady = resolve;
|
||||
});
|
||||
|
||||
if (session.configuration.clean) {
|
||||
if (session.configuration.configureAll) {
|
||||
void extensionManager?.cleanConfigureAllWithDebuggerInternal(
|
||||
debuggerInformation
|
||||
);
|
||||
if (cmakeDebugType === "script") {
|
||||
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<string, string>(session.configuration.scriptEnv?.map((e: {name: string; value: string}) => [e.name, e.value])) ?? new Map();
|
||||
void executeScriptWithDebugger(script, args, env, debuggerInformation);
|
||||
} else {
|
||||
void extensionManager?.cleanConfigureWithDebuggerInternal(
|
||||
debuggerInformation
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (session.configuration.configureAll) {
|
||||
void extensionManager?.configureAllWithDebuggerInternal(
|
||||
debuggerInformation
|
||||
);
|
||||
} else {
|
||||
void extensionManager?.configureWithDebuggerInternal(
|
||||
debuggerInformation
|
||||
);
|
||||
if (session.configuration.clean) {
|
||||
if (session.configuration.configureAll) {
|
||||
void extensionManager?.cleanConfigureAllWithDebuggerInternal(
|
||||
debuggerInformation
|
||||
);
|
||||
} else {
|
||||
void extensionManager?.cleanConfigureWithDebuggerInternal(
|
||||
debuggerInformation
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (session.configuration.configureAll) {
|
||||
void extensionManager?.configureAllWithDebuggerInternal(
|
||||
debuggerInformation
|
||||
);
|
||||
} else {
|
||||
void extensionManager?.configureWithDebuggerInternal(
|
||||
debuggerInformation
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await promise;
|
||||
}
|
||||
|
||||
await promise;
|
||||
}
|
||||
|
||||
logger.info(localize('debugger.create.descriptor', 'Connecting debugger on named pipe: \"{0}\"', pipeName));
|
||||
return new vscode.DebugAdapterNamedPipeServer(pipeName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
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 DynamicDebugConfigurationProvider implements vscode.DebugConfigurationProvider {
|
||||
provideDebugConfigurations(_folder: vscode.WorkspaceFolder | undefined, _token?: vscode.CancellationToken | undefined): vscode.ProviderResult<vscode.DebugConfiguration[]> {
|
||||
const providers: vscode.DebugConfiguration[] = [];
|
||||
|
||||
providers.push(
|
||||
{
|
||||
name: 'CMake: CMake Script',
|
||||
type: "cmake",
|
||||
request: "launch",
|
||||
cmakeDebugType: "script",
|
||||
scriptPath: '${file}'
|
||||
}
|
||||
);
|
||||
|
||||
return providers;
|
||||
}
|
||||
}
|
||||
|
||||
export class DebugConfigurationProvider implements vscode.DebugConfigurationProvider {
|
||||
resolveDebugConfiguration(_folder: vscode.WorkspaceFolder | undefined, debugConfiguration: vscode.DebugConfiguration, _token?: vscode.CancellationToken | undefined): vscode.ProviderResult<vscode.DebugConfiguration> {
|
||||
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;
|
||||
} 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.endsWith(".cmake") || (debugConfiguration.scriptPath === "${file}" && vscode.window.activeTextEditor?.document.fileName.endsWith(".cmake")))) {
|
||||
throw new Error(
|
||||
localize(
|
||||
"cmake.debug.script.requires.scriptPath",
|
||||
'The "cmake" debug type with "cmakeDebugType" set to "script" requires you to define a "scriptPath" that points to a CMake script.'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return debugConfiguration;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
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';
|
||||
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();
|
||||
|
||||
const cmakeLogger = logging.createLogger('cmake');
|
||||
const scriptLogger = logging.createLogger('cmake-script');
|
||||
|
||||
export async function executeScriptWithDebugger(scriptPath: string, scriptArgs: string[], scriptEnv: Map<string, string>, debuggerInformation: DebuggerInformation): Promise<void> {
|
||||
const outputConsumer: CMakeOutputConsumer = new CMakeOutputConsumer("", scriptLogger);
|
||||
|
||||
// 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);
|
||||
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));
|
||||
throw new Error("HEY");
|
||||
}
|
||||
} else {
|
||||
cmakeLogger.error(localize('run.script.cmakeDebugger.not.supported', "Cannot debug a script with this version of CMake, ensure you have CMake version 3.27 or later."));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -279,6 +279,7 @@ export class CMakeFileApiDriver extends CMakeDriver {
|
|||
name: localize("cmake.debug.name", "CMake Debugger"),
|
||||
request: "launch",
|
||||
type: "cmake",
|
||||
cmakeDebugType: "configure",
|
||||
pipeName: debuggerInformation.pipeName,
|
||||
fromCommand: true
|
||||
});
|
||||
|
|
|
@ -45,6 +45,7 @@ import { StatusBar } from '@cmt/status';
|
|||
import { DebugAdapterNamedPipeServerDescriptorFactory } from './debug/debugAdapterNamedPipeServerDescriptorFactory';
|
||||
import { getCMakeExecutableInformation } from './cmake/cmakeExecutable';
|
||||
import { DebuggerInformation, getDebuggerPipeName } from './debug/debuggerConfigureDriver';
|
||||
import { DebugConfigurationProvider, DynamicDebugConfigurationProvider } from './debug/debugConfigurationProvider';
|
||||
|
||||
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
|
||||
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
|
||||
|
@ -1758,6 +1759,14 @@ async function setup(context: vscode.ExtensionContext, progress?: ProgressHandle
|
|||
)
|
||||
);
|
||||
|
||||
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider("cmake", new DebugConfigurationProvider()));
|
||||
context.subscriptions.push(
|
||||
vscode.debug.registerDebugConfigurationProvider(
|
||||
"cmake",
|
||||
new DynamicDebugConfigurationProvider(),
|
||||
vscode.DebugConfigurationProviderTriggerKind.Dynamic)
|
||||
);
|
||||
|
||||
// List of functions that will be bound commands
|
||||
const funs: (keyof ExtensionManager)[] = [
|
||||
'activeFolderName',
|
||||
|
|
Загрузка…
Ссылка в новой задаче