@@ -5,12 +5,11 @@ import * as fs from 'fs';
55import * as os from 'os' ;
66import * as path from 'path' ;
77import * as vscode from 'vscode' ;
8- import { WorkspaceFolder } from 'vscode' ;
9- import * as process from './process' ;
10-
11- import { config as settings } from './config' ;
128import { log } from './log' ;
9+ import * as utils from './utils' ;
10+ import { config } from './config' ;
1311import { Option } from './option' ;
12+ import * as process from './process' ;
1413
1514/**
1615 * integrated: Use integrated terminal in VSCode
@@ -39,9 +38,9 @@ interface TargetInformations {
3938
4039async function getDebuggableTargets ( ) : Promise < Array < string > > {
4140 let targets = "" ;
42- let getTargetsPathScript = path . join ( __dirname , `../../assets/ debuggable_targets.lua` ) ;
41+ let getTargetsPathScript = utils . getAssetsScriptPath ( " debuggable_targets.lua" ) ;
4342 if ( fs . existsSync ( getTargetsPathScript ) ) {
44- targets = ( await process . iorunv ( settings . executable , [ "l" , getTargetsPathScript ] , { "COLORTERM" : "nocolor" } , settings . workingDirectory ) ) . stdout . trim ( ) ;
43+ targets = ( await process . iorunv ( config . executable , [ "l" , getTargetsPathScript ] , { "COLORTERM" : "nocolor" } , config . workingDirectory ) ) . stdout . trim ( ) ;
4544 }
4645 if ( targets ) {
4746 return process . getAnnotatedJSON ( targets ) [ 0 ] ;
@@ -55,12 +54,25 @@ async function getDebuggableTargets(): Promise<Array<string>> {
5554 * @returns TargetInformations
5655 */
5756async function getInformations ( targetName : string ) : Promise < TargetInformations > {
58- let getTargetInformationsScript = path . join ( __dirname , `../../assets/ target_informations.lua` ) ;
57+ let getTargetInformationsScript = utils . getAssetsScriptPath ( " target_informations.lua" ) ;
5958 if ( fs . existsSync ( getTargetInformationsScript ) ) {
60- let targetInformations = ( await process . iorunv ( settings . executable , [ "l" , getTargetInformationsScript , targetName ] , { "COLORTERM" : "nocolor" } , settings . workingDirectory ) ) . stdout . trim ( ) ;
61- if ( targetInformations ) {
62- return process . getAnnotatedJSON ( targetInformations ) [ 0 ] ;
59+ try {
60+ const result = await process . iorunv ( config . executable , [ "l" , getTargetInformationsScript , targetName ] , { "COLORTERM" : "nocolor" } , config . workingDirectory ) ;
61+ const targetInformations = result . stdout . trim ( ) ;
62+
63+ if ( targetInformations ) {
64+ const parsed = process . getAnnotatedJSON ( targetInformations ) ;
65+ if ( parsed && parsed . length > 0 ) {
66+ return parsed [ 0 ] ;
67+ }
68+ }
69+
70+ log . error ( `Failed to get target informations for ${ targetName } . Result: ${ targetInformations } ` ) ;
71+ } catch ( error ) {
72+ log . error ( `Error executing target_informations.lua: ${ error } ` ) ;
6373 }
74+ } else {
75+ log . error ( `target_informations.lua script not found at ${ getTargetInformationsScript } ` ) ;
6476 }
6577
6678 return null ;
@@ -72,9 +84,9 @@ async function getInformations(targetName: string): Promise<TargetInformations>
7284 */
7385async function findGdbPath ( ) : Promise < string > {
7486 let gdbPath = "" ;
75- let findGdbScript = path . join ( __dirname , `../../assets/ find_gdb.lua` ) ;
87+ let findGdbScript = utils . getAssetsScriptPath ( " find_gdb.lua" ) ;
7688 if ( fs . existsSync ( findGdbScript ) ) {
77- gdbPath = ( await process . iorunv ( settings . executable , [ "l" , findGdbScript ] , { "COLORTERM" : "nocolor" } , settings . workingDirectory ) ) . stdout . trim ( ) ;
89+ gdbPath = ( await process . iorunv ( config . executable , [ "l" , findGdbScript ] , { "COLORTERM" : "nocolor" } , config . workingDirectory ) ) . stdout . trim ( ) ;
7890 if ( gdbPath ) {
7991 gdbPath = gdbPath . split ( '\n' ) [ 0 ] . trim ( ) ;
8092 }
@@ -158,7 +170,7 @@ class XmakeConfigurationProvider implements vscode.DebugConfigurationProvider {
158170 * @param token
159171 * @returns the modified config to cpptols or codelldb
160172 */
161- public async resolveDebugConfiguration ( folder : WorkspaceFolder | undefined , config : XmakeDebugConfiguration , token ?: vscode . CancellationToken ) : Promise < vscode . DebugConfiguration > {
173+ public async resolveDebugConfiguration ( folder : vscode . WorkspaceFolder | undefined , config : XmakeDebugConfiguration , token ?: vscode . CancellationToken ) : Promise < vscode . DebugConfiguration > {
162174
163175 // If target is not set, resolve it with the status
164176 if ( ! config . target ) {
@@ -180,7 +192,7 @@ class XmakeConfigurationProvider implements vscode.DebugConfigurationProvider {
180192
181193 // Set the program path
182194 if ( ! ( targetInformations . path && fs . existsSync ( targetInformations . path ) ) ) {
183- await vscode . window . showErrorMessage ( ' The target program not found!' ) ;
195+ await vscode . window . showErrorMessage ( " The target program not found! Please build the project first." ) ;
184196 return { name : "Error: Target not found" , type : "cppdbg" , request : "launch" } ; // Return a fake config
185197 }
186198 config . program = targetInformations . path ;
@@ -199,24 +211,24 @@ class XmakeConfigurationProvider implements vscode.DebugConfigurationProvider {
199211 if ( ! config . args ) {
200212 let args = [ ] ;
201213
202- if ( config . target in settings . debuggingTargetsArguments )
203- args = settings . debuggingTargetsArguments [ config . target ] ;
204- else if ( "default" in settings . debuggingTargetsArguments )
205- args = settings . debuggingTargetsArguments [ "default" ] ;
206- else if ( config . target in settings . runningTargetsArguments )
214+ if ( config . target in config . debuggingTargetsArguments )
215+ args = config . debuggingTargetsArguments [ config . target ] ;
216+ else if ( "default" in config . debuggingTargetsArguments )
217+ args = config . debuggingTargetsArguments [ "default" ] ;
218+ else if ( config . target in config . runningTargetsArguments )
207219 args = config . runningTargetsArguments [ config . target ] ;
208- else if ( "default" in settings . runningTargetsArguments )
209- args = settings . runningTargetsArguments [ "default" ] ;
220+ else if ( "default" in config . runningTargetsArguments )
221+ args = config . runningTargetsArguments [ "default" ] ;
210222
211223 config . args = args ;
212224 }
213225
214226 // Get xmake env and merge it with config envs
215227 const sep = os . platform ( ) == "win32" ? ';' : ':'
216228 let xmakeEnvs = targetInformations . envs ;
217- if ( settings . envBehaviour === 'override' ) {
229+ if ( config . envBehaviour === 'override' ) {
218230 config . env = { ...xmakeEnvs , ...config . env } ;
219- } else if ( settings . envBehaviour === 'merge' && config . env !== undefined ) {
231+ } else if ( config . envBehaviour === 'merge' && config . env !== undefined ) {
220232 // Merge behaviour between xmake envs and launch.json envs
221233 for ( const key in xmakeEnvs ) {
222234 // If the key exist in debug envs
@@ -242,7 +254,7 @@ class XmakeConfigurationProvider implements vscode.DebugConfigurationProvider {
242254 }
243255
244256 // Switch to lldb if needed
245- if ( settings . debugConfigType == "codelldb" ) {
257+ if ( config . debugConfigType == "codelldb" ) {
246258 config . type = 'lldb' ;
247259 config . stopOnEntry = config . stopAtEntry ;
248260 // Code LLDB doesn't support newExternal
@@ -256,6 +268,39 @@ class XmakeConfigurationProvider implements vscode.DebugConfigurationProvider {
256268 config . program = `${ targetInformations . name } .exe` ;
257269 }
258270 }
271+
272+ // Switch to LLDB DAP if needed
273+ if ( config . debugConfigType == "lldb-dap" ) {
274+ config . type = 'lldb-dap' ;
275+ config . stopOnEntry = config . stopOnEntry ;
276+ // LLDB DAP doesn't support newExternal
277+ if ( config . terminal == 'newExternal' ) {
278+ config . terminal = 'external' ;
279+ }
280+
281+ // LLDB DAP use program key for search a running process
282+ if ( config . request == 'attach' ) {
283+ config . stopOnEntry = false ;
284+ config . program = `${ targetInformations . name } .exe` ;
285+ }
286+ }
287+
288+ // Switch to GDB DAP if needed
289+ if ( config . debugConfigType == "gdb-dap" ) {
290+ config . type = 'gdb' ;
291+ config . stopOnEntry = config . stopOnEntry ;
292+ // GDB DAP doesn't support newExternal
293+ if ( config . terminal == 'newExternal' ) {
294+ config . terminal = 'external' ;
295+ }
296+
297+ // GDB DAP use program key for search a running process
298+ if ( config . request == 'attach' ) {
299+ config . stopOnEntry = false ;
300+ config . program = `${ targetInformations . name } .exe` ;
301+ }
302+ }
303+
259304 // Set MIMode for macos
260305 if ( os . platform ( ) == 'darwin' ) {
261306 config . MIMode = "lldb" ;
@@ -285,7 +330,7 @@ class XmakeConfigurationProvider implements vscode.DebugConfigurationProvider {
285330 config = { ...config , ...setupCommands } ;
286331
287332 // Merge the custom debug config with actual config
288- config = { ...config , ...settings . customDebugConfig } ;
333+ config = { ...config , ...config . customDebugConfig } ;
289334
290335 return config ;
291336 }
@@ -294,20 +339,26 @@ class XmakeConfigurationProvider implements vscode.DebugConfigurationProvider {
294339export function initDebugger ( context : vscode . ExtensionContext , option : Option ) {
295340 const cpptools = vscode . extensions . getExtension ( "ms-vscode.cpptools" ) ;
296341 const codelldb = vscode . extensions . getExtension ( "vadimcn.vscode-lldb" ) ;
342+ const lldbdap = vscode . extensions . getExtension ( "llvm-vs-code-extensions.lldb-dap" ) ;
297343
298- if ( ! cpptools && ! codelldb ) {
299- log . error ( "Neither CppTools or Code LLDB is installed" ) ;
300- vscode . window . showErrorMessage ( "Neither CppTools or Code LLDB is installed. Install one of this extension to debug" ) ;
344+ if ( ! cpptools && ! codelldb && ! lldbdap ) {
345+ log . error ( "No debugging extensions are installed" ) ;
346+ vscode . window . showErrorMessage ( "No debugging extensions found. Please install CppTools, CodeLLDB, or LLDB DAP extension to debug" ) ;
301347 return ;
302348 }
303349
304- if ( ! codelldb && settings . debugConfigType == 'codelldb' ) {
305- vscode . window . showErrorMessage ( "Code LLDB is not installed. Install it first to use the debugger." ) ;
350+ // Check if the configured debugger is available
351+ if ( config . debugConfigType == "lldb-dap" && ! lldbdap ) {
352+ log . info ( "LLDB DAP is configured but not available, falling back to available debuggers" ) ;
353+ }
354+ if ( config . debugConfigType == "codelldb" && ! codelldb ) {
355+ log . info ( "CodeLLDB is configured but not available, falling back to available debuggers" ) ;
306356 }
307357
308- // Activate the two extensions
358+ // Activate all available debugging extensions
309359 cpptools ?. activate ( ) ;
310- codelldb ?. activate ( )
360+ codelldb ?. activate ( ) ;
361+ lldbdap ?. activate ( ) ;
311362
312363 const provider = new XmakeConfigurationProvider ( option ) ;
313364 context . subscriptions . push ( vscode . debug . registerDebugConfigurationProvider ( 'xmake' , provider , vscode . DebugConfigurationProviderTriggerKind . Dynamic ) ) ;
0 commit comments