in src/debugger.ts [156:234]
export async function getDebugConfigurationFromCache(cache: CMakeCache, target: ExecutableTarget, platform: string,
modeOverride?: MIModes, debuggerPathOverride?: string):
Promise<VSCodeDebugConfiguration | null> {
const entry = cache.get('CMAKE_LINKER');
if (entry !== null) {
const linker = entry.value as string;
const is_msvc_linker = linker.endsWith('link.exe') || linker.endsWith('ld.lld.exe');
if (is_msvc_linker) {
return createMSVCDebugConfiguration(target);
}
}
const debugger_name = modeOverride || (platform === 'darwin' ? 'lldb' : 'gdb');
const description = DEBUG_GEN[debugger_name];
if (debuggerPathOverride) {
if (path.isAbsolute(debuggerPathOverride) && await fs.exists(debuggerPathOverride)) {
return description.createConfig(debuggerPathOverride, target);
}
log.warning(localize('invalid.miDebuggerPath.override',
'{0} in {1} must be an absolute path to a debugger (variable expansion is not currently supported). Got: {2}',
'"miDebuggerPath"', '"cmake.debugConfig"', `"${debuggerPathOverride}"`));
}
const compiler_path = searchForCompilerPathInCache(cache);
if (compiler_path === null) {
throw Error(localize('no.compiler.found.in.cache', 'No compiler found in cache file.')); // MSVC should be already found by CMAKE_LINKER
}
if (compiler_path.endsWith('cl.exe')) {
return createMSVCDebugConfiguration(target);
}
// Look for a debugger, in the following order:
// 1. LLDB-MI
const clang_compiler_regex = /(clang[\+]{0,2})+(?!-cl)/gi;
let mi_debugger_path = compiler_path.replace(clang_compiler_regex, 'lldb-mi');
if (modeOverride !== "gdb" && (mi_debugger_path.search(new RegExp('lldb-mi')) !== -1)) {
const cpptoolsExtension = vscode.extensions.getExtension('ms-vscode.cpptools');
const cpptoolsDebuggerPath = cpptoolsExtension ? path.join(cpptoolsExtension.extensionPath, "debugAdapters", "lldb-mi", "bin", "lldb-mi") : undefined;
// 1a. lldb-mi in the compiler path
if (await checkDebugger(mi_debugger_path)) {
return createLLDBDebugConfiguration(mi_debugger_path, target);
}
// 1b. lldb-mi installed by CppTools
if (cpptoolsDebuggerPath && await checkDebugger(cpptoolsDebuggerPath)) {
return createLLDBDebugConfiguration(cpptoolsDebuggerPath, target);
}
}
// 2. gdb in the compiler path
mi_debugger_path = compiler_path.replace(clang_compiler_regex, 'gdb');
if (modeOverride !== "lldb" && (mi_debugger_path.search(new RegExp('gdb')) !== -1) && await checkDebugger(mi_debugger_path)) {
return createGDBDebugConfiguration(mi_debugger_path, target);
}
// 3. lldb in the compiler path
mi_debugger_path = compiler_path.replace(clang_compiler_regex, 'lldb');
if (modeOverride !== "gdb" && (mi_debugger_path.search(new RegExp('lldb')) !== -1) && await checkDebugger(mi_debugger_path)) {
return createLLDBDebugConfiguration(mi_debugger_path, target);
}
const gcc_compiler_regex = /([cg]\+\+|g?cc)(?=[^\/\\]*$)/gi;
let gdb_debugger_path = compiler_path.replace(gcc_compiler_regex, description.miMode);
if (path.isAbsolute(gdb_debugger_path) && !await fs.exists(gdb_debugger_path)) {
gdb_debugger_path = path.join(path.dirname(compiler_path), description.miMode);
if (process.platform === 'win32') {
gdb_debugger_path = gdb_debugger_path + '.exe';
}
}
if (gdb_debugger_path.search(new RegExp(description.miMode)) !== -1) {
return description.createConfig(gdb_debugger_path, target);
}
log.warning(localize('unable.to.determine.debugger.for.compiler',
'Unable to automatically determine debugger corresponding to compiler: {0}', compiler_path));
return null;
}