Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cl.exe being excluded for .c files and c/cpp caching. #9544

Merged
merged 2 commits into from
Jul 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions Extension/src/Debugger/configurationProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
private assetProvider: IConfigurationAssetProvider;
// Keep a list of tasks detected by cppBuildTaskProvider.
private static detectedBuildTasks: CppBuildTask[] = [];
Colengms marked this conversation as resolved.
Show resolved Hide resolved
private static detectedCppBuildTasks: CppBuildTask[] = [];
private static detectedCBuildTasks: CppBuildTask[] = [];
protected static recentBuildTaskLabel: string;

public constructor(assetProvider: IConfigurationAssetProvider, type: DebuggerType) {
Expand Down Expand Up @@ -449,8 +451,44 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
}

private async loadDetectedTasks(): Promise<void> {
if (!DebugConfigurationProvider.detectedBuildTasks || DebugConfigurationProvider.detectedBuildTasks.length === 0) {
DebugConfigurationProvider.detectedBuildTasks = await cppBuildTaskProvider.getTasks(true);
const editor: vscode.TextEditor | undefined = vscode.window.activeTextEditor;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These checks are taken from the start of getTask -- I didn't see a good way to refactor it so I didn't bother.

const emptyTasks: CppBuildTask[] = [];
if (!editor) {
DebugConfigurationProvider.detectedBuildTasks = emptyTasks;
return;
}

const fileExt: string = path.extname(editor.document.fileName);
if (!fileExt) {
DebugConfigurationProvider.detectedBuildTasks = emptyTasks;
return;
}

// Don't offer tasks for header files.
const isHeader: boolean = util.isHeaderFile (editor.document.uri);
if (isHeader) {
DebugConfigurationProvider.detectedBuildTasks = emptyTasks;
return;
}

// Don't offer tasks if the active file's extension is not a recognized C/C++ extension.
const fileIsCpp: boolean = util.isCppFile(editor.document.uri);
const fileIsC: boolean = util.isCFile(editor.document.uri);
if (!(fileIsCpp || fileIsC)) {
DebugConfigurationProvider.detectedBuildTasks = emptyTasks;
return;
}

if (fileIsCpp) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the same detectedBuildTasks cache being used for c and cpp.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One way is not to keep a cache and always load the tasks. It may help when a new compiler is being installed in the middle of a session. I added this cache so that we don't keep getting the tasks over and over again, but now I am not sure that it was the right decision. Which way you think is better? to keep the cache or to always load the tasks?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know. Using caches seems fine to me -- I see the cache get hit 2 times for every debug invocation and it's possible the list of compilers could be big, so it's hard to say how long that could potentially add to debug startup time. Installing a new compiler in the middle of a sessions seems pretty rare, and a user who did that and didn't see the new compiler added would probably guess they might need to reload VS Code.

if (!DebugConfigurationProvider.detectedCppBuildTasks || DebugConfigurationProvider.detectedCppBuildTasks.length === 0) {
DebugConfigurationProvider.detectedCppBuildTasks = await cppBuildTaskProvider.getTasks(true);
}
DebugConfigurationProvider.detectedBuildTasks = DebugConfigurationProvider.detectedCppBuildTasks;
} else {
if (!DebugConfigurationProvider.detectedCBuildTasks || DebugConfigurationProvider.detectedCBuildTasks.length === 0) {
DebugConfigurationProvider.detectedCBuildTasks = await cppBuildTaskProvider.getTasks(true);
}
DebugConfigurationProvider.detectedBuildTasks = DebugConfigurationProvider.detectedCBuildTasks;
}
}

Expand Down
17 changes: 13 additions & 4 deletions Extension/src/LanguageServer/cppBuildTaskProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,19 @@ export class CppBuildTaskProvider implements TaskProvider {
const knownCompilerPathsSet: Set<string> = new Set();
let knownCompilers: configs.KnownCompiler[] | undefined = await activeClient.getKnownCompilers();
if (knownCompilers) {
const compiler_condition: (info: configs.KnownCompiler) => boolean = info => ((fileIsCpp && !info.isC) || (fileIsC && info.isC)) &&
(!isCompilerValid || (!!userCompilerPathAndArgs &&
(path.basename(info.path) !== userCompilerPathAndArgs.compilerName))) &&
(!isWindows || !info.path.startsWith("/")); // TODO: Add WSL compiler support.
const compiler_condition: (info: configs.KnownCompiler) => boolean = info =>
(
// Filter out c compilers for cpp files and vice versa, except for cl.exe, which handles both.
path.basename(info.path) === "cl.exe" ||
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check fixes cl.exe not appearing for .c files.

(fileIsCpp && !info.isC) || (fileIsC && info.isC)
) &&
(
!isCompilerValid || (!!userCompilerPathAndArgs &&
(path.basename(info.path) !== userCompilerPathAndArgs.compilerName))
) &&
(
!isWindows || !info.path.startsWith("/")
); // TODO: Add WSL compiler support.
const cl_to_add: configs.KnownCompiler | undefined = userCompilerIsCl ? undefined : knownCompilers.find(info =>
((path.basename(info.path) === "cl.exe") && compiler_condition(info)));
knownCompilers = knownCompilers.filter(info =>
Expand Down