Skip to content

Commit c3141d4

Browse files
committed
Add support for debug
1 parent 620f967 commit c3141d4

File tree

4 files changed

+168
-12
lines changed

4 files changed

+168
-12
lines changed

README.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,18 @@ This is a simple extension to add TinyGo support to Visual Studio Code.
66

77
## Features
88

9-
Right now the only feature this extension supports is setting the right environment variables in the `.vscode/settings.json` of your workspace. For example, it may set the following configuration to work with the [BBC micro:bit](https://microbit.org/):
10-
11-
```json
12-
{
13-
"go.toolsEnvVars": {
14-
"GOROOT": "/home/user/.cache/tinygo/goroot-go1.14-f930d5b5f36579e8cbd1c139012b3d702281417fb6bdf67303c4697195b9ef1f-syscall",
15-
"GOFLAGS": "-tags=cortexm,baremetal,linux,arm,nrf51822,nrf51,nrf,microbit,tinygo,gc.conservative,scheduler.tasks"
16-
}
17-
}
18-
```
9+
The following features are supported.
10+
11+
* Set the right environment variables in the `.vscode/settings.json` of your workspace
12+
* Add support for 'preview' functionality
13+
* Add debug settings to `.vscode/settings.json`, `.vscode/launch.json` and `.vscode/tasks.json` of your workspace
1914

2015
To use it, click on the `TinyGo` status bar element at the bottom of the screen and select a target. Alternatively, you could open the [command palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) and search for `TinyGo target`.
2116

17+
Debugging can be started via `Run > StartDebugging (F5)`. At this time, debug using openocd is supported. The interface used by openocd can be changed from the following.
18+
19+
![settings](images/settings.png)
20+
2221
Notes:
2322

2423
* It is probably necessary to reload the window once you've set a new TinyGo target. You will be prompted for this if it's necessary.
@@ -30,6 +29,10 @@ This extension depends on the following:
3029

3130
* The [Go extension for VS Code](https://marketplace.visualstudio.com/items?itemName=golang.go). This extension should be automatically installed as a dependency.
3231
* The TinyGo compiler, version 0.15 or later. See [installation instructions for your operating system](https://tinygo.org/getting-started/).
32+
* The [Cortex-Debug extension for VS Code](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug). This extension should be automatically installed as a dependency.
33+
* for debug support
34+
* The TinyGo compiler, version 0.23 later. See [installation instructions for your operating system](https://tinygo.org/getting-started/).
35+
* See [Debugging - Debug Tinygo programs using GDB](https://tinygo.org/docs/guides/debugging/). At least tinygo gdb must work.
3336

3437
## Development
3538

images/settings.png

13.5 KB
Loading

package.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"name": "vscode-tinygo",
33
"displayName": "TinyGo",
4-
"version": "0.3.0",
4+
"version": "0.4.0-dev1",
55
"publisher": "tinygo",
66
"description": "TinyGo support for Visual Studio Code",
77
"license": "BSD-3-Clause",
88
"icon": "images/tinygo-logo.png",
99
"categories": [
1010
"Programming Languages"
1111
],
12-
"extensionDependencies": ["golang.go"],
12+
"extensionDependencies": ["golang.go", "marus25.cortex-debug"],
1313
"repository": {
1414
"type": "git",
1515
"url": "https://github.com/tinygo-org/vscode-tinygo"
@@ -44,6 +44,16 @@
4444
"group": "navigation"
4545
}
4646
]
47+
},
48+
"configuration": {
49+
"title": "TinyGo Configuration",
50+
"properties": {
51+
"tinygo.openocdInterface": {
52+
"description": "which hardware programmer to use (ex: jlink, cmsis-dap, stlink-v2, ...)",
53+
"type": "string",
54+
"default": "cmsis-dap"
55+
}
56+
}
4757
}
4858
},
4959
"scripts": {

src/extension.ts

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import * as vscode from 'vscode';
22
import * as cp from 'child_process';
33
import * as util from 'util';
44
import * as preview from './preview';
5+
import * as path from 'path';
6+
import * as fs from 'fs';
7+
import * as os from 'os';
58

69
let statusbarItem: vscode.StatusBarItem;
710

@@ -32,6 +35,12 @@ export async function activate(context: vscode.ExtensionContext) {
3235
// Register the command, _after_ the list of targets has been read. This
3336
// makes sure the user will never see an empty list.
3437
let disposable = vscode.commands.registerCommand('vscode-tinygo.selectTarget', async () => {
38+
let buildPkg = '';
39+
let editor = vscode.window.activeTextEditor;
40+
if (editor) {
41+
buildPkg = editor.document.fileName;
42+
}
43+
3544
// Load targets (if not already loaded).
3645
if (!targets) {
3746
targets = await readTargetList(context);
@@ -51,6 +60,10 @@ export async function activate(context: vscode.ExtensionContext) {
5160
// Obtain information about this target (GOROOT, build tags).
5261
let goroot = '';
5362
let buildTags = '';
63+
let tinygoroot = '';
64+
let openocdInterface = '';
65+
let openocdTarget = '';
66+
let gdbPath = '';
5467
if (target != '-') {
5568
try {
5669
const execFile = util.promisify(cp.execFile);
@@ -81,6 +94,46 @@ export async function activate(context: vscode.ExtensionContext) {
8194
vscode.window.showErrorMessage(`Could not find GOROOT variable for ${target}, perhaps you have an older TinyGo version?`);
8295
return;
8396
}
97+
98+
try {
99+
const execFile = util.promisify(cp.execFile);
100+
const { stdout, stderr } = await execFile('tinygo', ['env', 'TINYGOROOT']);
101+
tinygoroot = stdout.trimRight()
102+
} catch (err) {
103+
vscode.window.showErrorMessage(`Could not run 'tinygo env TINYGOROOT':\n` + err);
104+
return;
105+
}
106+
107+
try {
108+
openocdInterface = vscode.workspace.getConfiguration('tinygo')['openocdInterface'];
109+
110+
const execFile = util.promisify(cp.execFile);
111+
const { stdout, stderr } = await execFile('tinygo', ['build', '-json', '-target', target, '-o', 'out.elf', '-programmer', openocdInterface]);
112+
let buildInfo = JSON.parse(stdout);
113+
114+
if (buildInfo.Target['openocd-target']) {
115+
openocdTarget = buildInfo.Target['openocd-target'];
116+
}
117+
gdbPath = '';
118+
119+
let pathSep = ':';
120+
if (os.platform() == 'win32') {
121+
pathSep = ';';
122+
}
123+
process.env.PATH?.split(pathSep).forEach(line => {
124+
for (var i in buildInfo.Target.gdb) {
125+
let g = path.join(line, buildInfo.Target.gdb[i])
126+
if (os.platform() == 'win32') {
127+
g += '.exe';
128+
}
129+
if (fs.existsSync(g)) {
130+
gdbPath = g;
131+
}
132+
}
133+
})
134+
} catch (err) {
135+
vscode.window.showErrorMessage(`Could not run 'tinygo build -json -target ${target}':\n` + err);
136+
}
84137
}
85138

86139
// Update the configuration in the current workspace.
@@ -89,8 +142,98 @@ export async function activate(context: vscode.ExtensionContext) {
89142
let envVars = config.get<NodeJS.Dict<string>>('toolsEnvVars', {});
90143
envVars.GOROOT = goroot ? goroot: undefined;
91144
envVars.GOFLAGS = buildTags ? "-tags="+(buildTags.split(' ').join(',')) : undefined;
145+
envVars.TARGET = target;
146+
envVars.TINYGOROOT = tinygoroot;
147+
envVars.GdbPath = path.basename(gdbPath);
148+
envVars.OpenocdInterface = openocdInterface;
149+
envVars.OpenocdTarget = openocdTarget;
150+
envVars.TmpDir = os.tmpdir();
151+
152+
{
153+
let folders = vscode.workspace.workspaceFolders
154+
if (folders) {
155+
let g = folders[0].uri;
156+
buildPkg = path.dirname(path.relative(folders[0].uri.fsPath, buildPkg));
157+
}
158+
envVars.TargetPkg = "./" + buildPkg;
159+
}
92160
config.update('toolsEnvVars', envVars, vscode.ConfigurationTarget.Workspace);
93161

162+
{
163+
const config = vscode.workspace.getConfiguration('cortex-debug', null);
164+
config.update('armToolchainPath', path.dirname(gdbPath));
165+
config.update('gdbPath', path.basename(gdbPath));
166+
}
167+
168+
{
169+
// launch.json configuration
170+
const launchConfig = vscode.workspace.getConfiguration('launch');
171+
const configurations = launchConfig['configurations'];
172+
let found = false
173+
for (var i in configurations) {
174+
let cfg = configurations[i];
175+
if (cfg.name == 'tinygo-debug') {
176+
found = true;
177+
}
178+
}
179+
180+
if (!found) {
181+
configurations.push({
182+
"name": "tinygo-debug",
183+
"type": "cortex-debug",
184+
"servertype": "openocd",
185+
"request": "launch",
186+
"runToEntryPoint": "main.main",
187+
"executable": "${config:go.toolsEnvVars.TmpDir}/out.elf",
188+
"configFiles": [
189+
"interface/${config:go.toolsEnvVars.OpenocdInterface}.cfg",
190+
"target/${config:go.toolsEnvVars.OpenocdTarget}.cfg"
191+
],
192+
"preLaunchTask": "tinygo build task",
193+
"cwd": "${workspaceRoot}",
194+
"gdbPath": "${config:go.toolsEnvVars.GdbPath}",
195+
});
196+
launchConfig.update('configurations', configurations, false).then(() =>
197+
vscode.window.showInformationMessage('Added tinygo configuration to launch.json!')
198+
);
199+
}
200+
}
201+
202+
{
203+
// tasks.json configuration
204+
const tasksConfig = vscode.workspace.getConfiguration('tasks');
205+
const task = {
206+
"label": "tinygo build task",
207+
"type": "shell",
208+
"command": "tinygo build -o ${config:go.toolsEnvVars.TmpDir}/out.elf -target ${config:go.toolsEnvVars.TARGET} -size short -opt 1 ${config:go.toolsEnvVars.TargetPkg}",
209+
"problemMatcher": [],
210+
"group": {
211+
"kind": "build",
212+
"isDefault": true
213+
}
214+
};
215+
if (!tasksConfig['tasks']) {
216+
tasksConfig.update('tasks', [task]).then(() =>
217+
vscode.window.showInformationMessage('Added tinygo configuration to tasks.json!')
218+
);
219+
} else {
220+
let configurations = tasksConfig['tasks'];
221+
let found = false
222+
for (var i in configurations) {
223+
let cfg = configurations[i];
224+
if (cfg.label == 'tinygo build task') {
225+
found = true;
226+
}
227+
}
228+
if (!found) {
229+
configurations.push(task);
230+
tasksConfig.update('tasks', configurations, false).then(() =>
231+
vscode.window.showInformationMessage('Added tinygo configuration to tasks.json!')
232+
);
233+
}
234+
}
235+
}
236+
94237
// Update status bar.
95238
context.workspaceState.update('tinygo-target', target);
96239
updateStatusBar();

0 commit comments

Comments
 (0)