in Extension/src/Debugger/configurationProvider.ts [121:246]
async provideDebugConfigurations(folder?: vscode.WorkspaceFolder, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration[]> {
const defaultConfig: vscode.DebugConfiguration = this.provider.getInitialConfigurations(this.type).find((config: any) =>
isDebugLaunchStr(config.name) && config.request === "launch");
console.assert(defaultConfig, "Could not find default debug configuration.");
const platformInfo: PlatformInformation = await PlatformInformation.GetPlatformInformation();
const platform: string = platformInfo.platform;
// Import the tasks from tasks.json file.
const buildTasksJson: CppBuildTask[] = await cppBuildTaskProvider.getJsonTasks();
// Provide detected tasks by cppBuildTaskProvider.
const buildTasksDetected: CppBuildTask[] = await cppBuildTaskProvider.getTasks(true);
// Rename the provided tasks that has same name as tasks in tasks.json.
const buildTasksDetectedRename: CppBuildTask[] = buildTasksDetected.map(taskDetected => {
for (const taskJson of buildTasksJson) {
if ((taskDetected.definition.label as string) === (taskJson.definition.label as string)) {
taskDetected.name = cppBuildTaskProvider.provideUniqueTaskLabel(taskJson.definition.label, buildTasksJson);
taskDetected.definition.label = taskDetected.name;
break;
}
}
return taskDetected;
});
let buildTasks: CppBuildTask[] = [];
buildTasks = buildTasks.concat(buildTasksJson, buildTasksDetectedRename);
if (buildTasks.length === 0) {
return Promise.resolve(this.provider.getInitialConfigurations(this.type));
}
if (buildTasks.length === 0) {
return Promise.resolve(this.provider.getInitialConfigurations(this.type));
}
// Filter out build tasks that don't match the currently selected debug configuration type.
buildTasks = buildTasks.filter((task: CppBuildTask) => {
const command: string = task.definition.command as string;
if (!command) {
return false;
}
if (defaultConfig.name.startsWith("(Windows) ")) {
if (command.startsWith("cl.exe")) {
return true;
}
} else {
if (!command.startsWith("cl.exe")) {
return true;
}
}
return false;
});
// Generate new configurations for each build task.
// Generating a task is async, therefore we must *await* *all* map(task => config) Promises to resolve.
const configs: vscode.DebugConfiguration[] = await Promise.all(buildTasks.map<Promise<vscode.DebugConfiguration>>(async task => {
const definition: CppBuildTaskDefinition = task.definition as CppBuildTaskDefinition;
const compilerPath: string = definition.command;
const compilerName: string = path.basename(compilerPath);
const newConfig: vscode.DebugConfiguration = {...defaultConfig}; // Copy enumerables and properties
newConfig.name = compilerName + buildAndDebugActiveFileStr();
newConfig.preLaunchTask = task.name;
if (newConfig.type === "cppdbg") {
newConfig.externalConsole = false;
} else {
newConfig.console = "externalTerminal";
}
const exeName: string = path.join("${fileDirname}", "${fileBasenameNoExtension}");
const isWindows: boolean = platform === 'win32';
newConfig.program = isWindows ? exeName + ".exe" : exeName;
// Add the "detail" property to show the compiler path in QuickPickItem.
// This property will be removed before writing the DebugConfiguration in launch.json.
newConfig.detail = task.detail ? task.detail : definition.command;
const isCl: boolean = compilerName === "cl.exe";
newConfig.cwd = isWindows && !isCl && !process.env.PATH?.includes(path.dirname(compilerPath)) ? path.dirname(compilerPath) : "${fileDirname}";
return new Promise<vscode.DebugConfiguration>(resolve => {
if (platform === "darwin") {
return resolve(newConfig);
} else {
let debuggerName: string;
if (compilerName.startsWith("clang")) {
newConfig.MIMode = "lldb";
debuggerName = "lldb-mi";
// Search for clang-8, clang-10, etc.
if ((compilerName !== "clang-cl.exe") && (compilerName !== "clang-cpp.exe")) {
const suffixIndex: number = compilerName.indexOf("-");
if (suffixIndex !== -1) {
const suffix: string = compilerName.substr(suffixIndex);
debuggerName += suffix;
}
}
newConfig.type = "cppdbg";
} else if (compilerName === "cl.exe") {
newConfig.miDebuggerPath = undefined;
newConfig.type = "cppvsdbg";
return resolve(newConfig);
} else {
debuggerName = "gdb";
}
if (isWindows) {
debuggerName = debuggerName.endsWith(".exe") ? debuggerName : (debuggerName + ".exe");
}
const compilerDirname: string = path.dirname(compilerPath);
const debuggerPath: string = path.join(compilerDirname, debuggerName);
if (isWindows) {
newConfig.miDebuggerPath = debuggerPath;
return resolve(newConfig);
} else {
fs.stat(debuggerPath, (err, stats: fs.Stats) => {
if (!err && stats && stats.isFile) {
newConfig.miDebuggerPath = debuggerPath;
} else {
newConfig.miDebuggerPath = path.join("/usr", "bin", debuggerName);
}
return resolve(newConfig);
});
}
}
});
}));
configs.push(defaultConfig);
return configs;
}