Skip to content

Commit

Permalink
Support debug port's CMakeLists (#10)
Browse files Browse the repository at this point in the history
Co-authored-by: jyu49 <[email protected]>
  • Loading branch information
JackBoosY and jyu49 authored Feb 28, 2024
1 parent de8b5dc commit 9dffad5
Show file tree
Hide file tree
Showing 6 changed files with 354 additions and 29 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,11 @@ Note: please only enable/disable in `workspace`!

### Debug portfile or other vcpkg provided cmake code

1. Set debug point in the portfile.cmake (required) or other cmake file.
1. Set breakpoint in the portfile.cmake (required) or other cmake file.
2. Open `Run and Debug` in left side bar, select `Debug portfile(s)`, click the green triangle to run debugging.

### Debug port's CMake code

1. Set breakpoint in the portfile.cmake.
2. Run install command with `--editable`(important!) then set breakpoint in source cmake file(folder name without `.clean`).
3. Open `Run and Debug` in left side bar, select `Debug portfile(s)`, click the green triangle to run debugging.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"icon": "images/vcpkg-logo.png",
"publisher": "JackBoosY",
"license": "MIT",
"version": "2.1.0",
"version": "2.2.0",
"engines": {
"vscode": "^1.76.0"
},
Expand Down
260 changes: 260 additions & 0 deletions src/cmakeDebugger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
import * as vscode from 'vscode';
import {VcpkgLogMgr} from './log';
import {VcpkgDebugger} from './vcpkgDebugger';
import { debug } from 'vscode';
import * as fs from 'fs';

function sleep(time: number){
return new Promise((resolve) => setTimeout(resolve, time));
}

export class CmakeDebugger {
private _vcpkgDbg: VcpkgDebugger;
private _logMgr : VcpkgLogMgr;
private _waitDebug : boolean;

constructor(vcpkgDebugger: VcpkgDebugger, logMgr : VcpkgLogMgr)
{
this._vcpkgDbg = vcpkgDebugger;
this._logMgr = logMgr;
this._waitDebug = false;

this.updateConfigurations();
}

private generatePipeline()
{
if (process.platform === 'win32')
{
return "\\\\.\\\\pipe\\\\vscode-vcpkg-cmake-debugger-pipe";
}
else
{
return "/tmp/vscode-vcpkg-cmakelists-debugger-pipe";
}
}

private getTasksJsonContent()
{
this._logMgr.logInfo("Loading tasks json content.");
return this.readFromFile("tasks");
}

private async updateConfig()
{
this._logMgr.logInfo("Updating tasks.json");

let fullContent = this.getTasksJsonContent();

if (JSON.stringify(fullContent) === "{}")
{
this._logMgr.logErr("tasks json is empty!");
return;
}
else
{
if (fullContent.has("tasks"))
{
let taskArray = new Array;
let originCommand = "";
let currTask;
for (let index = 0; index < fullContent["tasks"].length; index++)
{
const element = fullContent["tasks"][index];
if (element["label"] === "Debug vcpkg commands")
{
this._logMgr.logInfo("Found exists task, update now.");

currTask = element;
originCommand = element["command"];
}
else
{
taskArray.push(element);
}
}

if (originCommand)
{
if (originCommand.indexOf("--x-cmake-configure-debug") === -1)
{
let config = originCommand + " --x-cmake-configure-debug " + this.generatePipeline() + " --editable";
currTask["command"] = config;

taskArray.push(currTask);

this._logMgr.logInfo("Update command " + config + " in Tasks json command");
await this.writeToFile("tasks", "tasks", taskArray);
}
else
{
this._logMgr.logInfo("Already update command");
}
}
}
else
{
this._logMgr.logInfo("Tasks item not found, new one now.");
return;
}
}
}

private readFromFile(fileName: string)
{
return vscode.workspace.getConfiguration(fileName);
}

private async writeToFile(fileName: string, scope: string, content: any)
{
this._logMgr.logInfo("Updating " + fileName + " - " + scope);
await vscode.workspace.getConfiguration(fileName).update(scope, content, null);
}

private async cleanConfig()
{
this._logMgr.logInfo("Clean command in Tasks json command.");

let fullContent = this.getTasksJsonContent();

if (JSON.stringify(fullContent) === "{}")
{
this._logMgr.logErr("tasks json is empty!");
return;
}
else
{
if (fullContent.has("tasks"))
{
let taskArray = new Array;
let originCommand = "";
let currTask;
for (let index = 0; index < fullContent["tasks"].length; index++)
{
const element = fullContent["tasks"][index];
if (element["label"] === "Debug vcpkg commands")
{
this._logMgr.logInfo("Found exists task, update now.");

currTask = element;
originCommand = element["command"];
}
else
{
taskArray.push(element);
}
}

if (originCommand)
{
if (currTask["command"].indexOf(" --x-cmake-configure-debug") !== -1)
{
let config = currTask["command"];
config = config.substring(0, config.indexOf(" --x-cmake-configure-debug"));
currTask["command"] = config;

taskArray.push(currTask);

this._logMgr.logInfo("Delete command in Tasks json command");
await this.writeToFile("tasks", "tasks", taskArray);
}
else
{
this._logMgr.logInfo("Command is alreay cleaned.");
}
}
}
else
{
this._logMgr.logInfo("Tasks item not found, new one now.");
return;
}
}
}

public updateConfigurations()
{
let breakPoints = debug.breakpoints;
let validBreakPoint = false;
for (let index = 0; index < breakPoints.length; index++)
{
const element = breakPoints[index];
// @ts-ignore
if (element.location.uri.toString().search("buildtrees") !== -1)
{
// @ts-ignore
this._logMgr.logInfo("Found breakpoint path: " + element.location.uri.toString());
validBreakPoint = true;
break;
}
}

if (validBreakPoint)
{
this._logMgr.logInfo("Found valid CMake breakpoint.");
this.updateConfig();
}
else
{
this._logMgr.logInfo("No valid CMake breakpoint was found.");
this.cleanConfig();
}
}

public stopWaitingDebug()
{
this._waitDebug = false;
}

public async startDebugging(vcpkgRoot: any, currentTriplet : any)
{
this._logMgr.logInfo("Starting debug cmake.");
if (vcpkgRoot === undefined || !vcpkgRoot.length)
{
this._logMgr.logErr("vcpkgRoot(" + vcpkgRoot + ") is empty!");
vscode.window.showErrorMessage("Vcpkg root is empty! Please manually set.");
return;
}
else if (currentTriplet === undefined || !currentTriplet.length)
{
this._logMgr.logErr("currentTriplet(" + currentTriplet + ") is empty!");
vscode.window.showErrorMessage("Current default triplet is empty! Please manually set first.");
return;
}

let portName = this._vcpkgDbg.getModifiedPorts();
portName = portName?.replace(" ", "");
let outName = vcpkgRoot + "/buildtrees/" + portName + "/stdout-" + currentTriplet + ".log";
let content = "";
let whenConfigure = false;

// wait for configure
this._logMgr.logInfo("Waiting for configure, reading output in " + outName);
this._waitDebug = true;
do {
if (!this._waitDebug)
{
this._logMgr.logInfo("Cancel debug CMakeLists.");
return;
}
content = fs.readFileSync(outName, { encoding: 'utf8', flag: 'r' });
await sleep(100);
if (content.search("-- Configuring ") !== -1 && content.search("-- Performing post-build validation") === -1)
{
whenConfigure = true;
}
} while (!whenConfigure);

this._waitDebug = false;

this._logMgr.logInfo("Connecting cmake debug pipe.");
vscode.debug.startDebugging(undefined, {
name: "Vcpkg extension Debugger",
request: "launch",
type: "cmake",
cmakeDebugType: "external",
pipeName: this.generatePipeline(),
fromCommand: true
});
}
}
48 changes: 25 additions & 23 deletions src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,12 @@ export class ConfigurationManager implements vscode.Disposable
this._logMgr = logMgr;
this._versionMgr = verMgr;

this.getVcpkgPathFromConfig().then((vcpkgPath) => {
if (vcpkgPath !== undefined)
{
this._versionMgr.setVcpkgRoot(vcpkgPath);
this.updateVcpkgSetting(this._vcpkgPathConfig, vcpkgPath, true);
}
});
let vcpkgPath= this.getVcpkgPathFromConfig();
if (vcpkgPath !== undefined)
{
this._versionMgr.setVcpkgRoot(vcpkgPath);
this.updateVcpkgSetting(this._vcpkgPathConfig, vcpkgPath, true);
}

// Update vcpkg target triplet
let automaticUpdateTriplet = workspace.getConfiguration('vcpkg').get<Boolean>(this._autoUpdateTriplet);
Expand Down Expand Up @@ -213,7 +212,7 @@ export class ConfigurationManager implements vscode.Disposable
return path;
}

private async getVcpkgPathFromEnv()
private getVcpkgPathFromEnv()
{
let envVar = process.env[this._vcpkgRootConfig];
// let envVar = this._context.environmentVariableCollection.get(this._vcpkgRootConfig);
Expand All @@ -226,11 +225,11 @@ export class ConfigurationManager implements vscode.Disposable
return undefined;
}

private async getVcpkgPathFromConfig()
private getVcpkgPathFromConfig()
{
let tryFirst = workspace.getConfiguration('vcpkg').get<string>(this._vcpkgPathConfig);

if ((tryFirst !== undefined && tryFirst.length !== 0) && await this.isVcpkgExistInPath(tryFirst))
if ((tryFirst !== undefined && tryFirst.length !== 0) && this.isVcpkgExistInPath(tryFirst))
{
return tryFirst;
}
Expand Down Expand Up @@ -265,7 +264,7 @@ export class ConfigurationManager implements vscode.Disposable
return config !== undefined ? config : false;
}

private async isVcpkgExistInPath(path: string)
private isVcpkgExistInPath(path: string)
{
let fullPath = '';
// check whether this path is a environment variable
Expand All @@ -287,17 +286,6 @@ export class ConfigurationManager implements vscode.Disposable
if (fs.existsSync(fullPath))
{
return true;
// too strict, skip the following code
let version = await this.runCommand(fullPath, '--version', path);
if (version.match('vcpkg package management program version') !== null)
{
return true;
}
else
{
this.logErr('Run command: ' + fullPath + ' --version failed with ' + version);
return false;
}
}
else
{
Expand Down Expand Up @@ -814,10 +802,24 @@ export class ConfigurationManager implements vscode.Disposable
await this.updateCMakeSetting(this._cmakeOptionConfig, newConfigs);
}

public getVcpkgRealPath()
{
let config = this.getVcpkgPathFromConfig();
// environment variable
if (config?.indexOf("$ENV") === 0) {
return this.getVcpkgPathFromEnv();
}
else
{
// true real path
return config;
}
}

private getAllSupportedTriplets()
{
let triplets = [];
let vcpkgPath = this.getVcpkgPathFromConfig();
let vcpkgPath = this.getVcpkgRealPath();

if (vcpkgPath === undefined)
{
Expand Down
Loading

0 comments on commit 9dffad5

Please sign in to comment.