Skip to content

Commit 0dcf6b8

Browse files
CopilotOmotolahanniavaleraHannia Valera
authored
Fix ${workspaceFolder} expansion in cmake.additionalCompilerSearchDirs for single-root workspaces (#4822)
* Initial plan * Fix ${workspaceFolder} expansion in additionalCompilerSearchDirs for single-root workspaces (#4571) Co-authored-by: Omotola <[email protected]> * Revert multiroot changes and apply simpler fix Co-authored-by: Omotola <[email protected]> Agent-Logs-Url: https://github.com/microsoft/vscode-cmake-tools/sessions/fb47d979-7034-47d4-b72f-0906f68d7e6d * fixed the npmrc file being renamed --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: Omotola <[email protected]> Co-authored-by: Omotola <[email protected]> Co-authored-by: Hannia Valera <[email protected]> Co-authored-by: Hannia Valera <[email protected]>
1 parent 9e07fd6 commit 0dcf6b8

4 files changed

Lines changed: 80 additions & 34 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ Improvements:
3131
- Honor `debugger.workingDirectory` from the CMake File API when debugging a target, so that the `DEBUGGER_WORKING_DIRECTORY` target property is used as the debugger working directory. [#4595](https://github.com/microsoft/vscode-cmake-tools/issues/4595)
3232

3333
Bug Fixes:
34+
- Fix `cmake.additionalCompilerSearchDirs` ignoring per-folder overrides in multiroot workspaces. The setting is now read from each folder's scoped configuration with `${workspaceFolder}` expanded per-folder, and the results are unioned. Also fix `cmake.cmakePath` resolution during kit scanning to try all workspace folders instead of only the first.
35+
- Fix `${workspaceFolder}` expansion in `cmake.additionalCompilerSearchDirs` for single-root workspaces. Previously only the multi-root `${workspaceFolder:name}` syntax worked. [#4571](https://github.com/microsoft/vscode-cmake-tools/issues/4571)
3436
- Fix `cmake.revealLog` set to `"focus"` not revealing the output panel or stealing focus. The output channel now correctly appears and takes focus on both configure success and failure when this setting is used. [#4471](https://github.com/microsoft/vscode-cmake-tools/issues/4471)
3537
- Fix `${command:cmake.selectConfigurePreset}` (and other preset/kit selection commands) failing with "command did not return a result of type string" when used in `tasks.json` as a command variable. The commands now return the selected preset or kit name instead of a boolean. [#4239](https://github.com/microsoft/vscode-cmake-tools/issues/4239)
3638
- Fix renaming a CMake project creating a duplicate node in the Project Outline instead of replacing the existing one. [#4343](https://github.com/microsoft/vscode-cmake-tools/issues/4343)

docs/cmake-settings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Options that support substitution, in the table below, allow variable references
88

99
| Setting | Description | Default value | Supports substitution |
1010
|---------|---------|---------|-----|
11-
| `cmake.additionalCompilerSearchDirs`| List of paths to search for additional compilers, like a MinGW installation. This means that GCC does not need to be on your `$PATH` for it to be found via kit scanning. For example: `["C:\\MinGW\\bin"]` (Search in C:\MinGW\bin for a MinGW installation) | `[]` | no |
11+
| `cmake.additionalCompilerSearchDirs`| List of paths to search for additional compilers, like a MinGW installation. This means that GCC does not need to be on your `$PATH` for it to be found via kit scanning. For example: `["C:\\MinGW\\bin"]` (Search in C:\MinGW\bin for a MinGW installation) | `[]` | yes |
1212
| `cmake.additionalKits` | Array of paths to custom kit files. These are in addition to the default kit files. | `[]` | no |
1313
| `cmake.allowCommentsInPresetsFile` | Allow the use of JSON extensions such as comments in CMakePresets.json. Please note that your CMakePresets.json file may be considered invalid by other IDEs or on the command line if you use non-standard JSON. | `false` | no |
1414
| `cmake.allowUnsupportedPresetsVersions` | Enables the use of presets files that are using features from the versions that Cmake Tools extension doesn't currently support. Unknown properties and macros will be ignored. | `false` | no |

src/config.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -547,12 +547,23 @@ export class ConfigurationReader implements vscode.Disposable {
547547
}
548548

549549
get additionalCompilerSearchDirs(): string[] {
550+
return ConfigurationReader.getAdditionalCompilerSearchDirsFromConfig(this.configData);
551+
}
552+
553+
/**
554+
* Extract additionalCompilerSearchDirs from raw config data, applying the
555+
* mingwSearchDirs deprecation fallback. This is intentionally static so
556+
* callers that only have an `ExtensionConfigurationSettings` object (e.g.
557+
* the multiroot aggregation in extension.ts) can reuse the logic without
558+
* constructing a full ConfigurationReader.
559+
*/
560+
static getAdditionalCompilerSearchDirsFromConfig(configData: ExtensionConfigurationSettings): string[] {
550561
// mingwSearchDirs is deprecated, but we still use it if additionalCompilerSearchDirs is not set for backwards compatibility
551-
if (this.configData.additionalCompilerSearchDirs.length === 0 && this.configData.mingwSearchDirs.length > 0) {
562+
if (configData.additionalCompilerSearchDirs.length === 0 && configData.mingwSearchDirs.length > 0) {
552563
log.warning(localize('please.upgrade.configuration', 'The setting {0} is replaced by {1}. Please upgrade your configuration.', '"mingwSearchDirs"', '"additionalCompilerSearchDirs"'));
553-
return this.configData.mingwSearchDirs;
564+
return configData.mingwSearchDirs;
554565
}
555-
return this.configData.additionalCompilerSearchDirs;
566+
return configData.additionalCompilerSearchDirs;
556567
}
557568
get additionalKits(): string[] {
558569
return this.configData.additionalKits;

src/extension.ts

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,8 +1061,19 @@ export class ExtensionManager implements vscode.Disposable {
10611061
if (!vscode.workspace.workspaceFolders || vscode.workspace.workspaceFolders.length < 1) {
10621062
return;
10631063
}
1064-
const workspaceContext = DirectoryContext.createForDirectory(vscode.workspace.workspaceFolders[0], new StateManager(this.extensionContext, vscode.workspace.workspaceFolders[0]));
1065-
const cmakePath: string = await workspaceContext.getCMakePath() || '';
1064+
1065+
// Resolve the cmake path from workspace folders. In a multiroot workspace different
1066+
// folders may configure different cmake.cmakePath values; try each folder and use the
1067+
// first one that resolves to a non-empty path.
1068+
let cmakePath = '';
1069+
for (const folder of vscode.workspace.workspaceFolders) {
1070+
const workspaceContext = DirectoryContext.createForDirectory(folder, new StateManager(this.extensionContext, folder));
1071+
cmakePath = await workspaceContext.getCMakePath() || '';
1072+
if (cmakePath) {
1073+
break;
1074+
}
1075+
}
1076+
10661077
const duplicateRemoved = await KitsController.scanForKits(cmakePath);
10671078
if (duplicateRemoved) {
10681079
// Check each project. If there is an active kit set and if it is of the old definition, unset the kit.
@@ -1079,38 +1090,60 @@ export class ExtensionManager implements vscode.Disposable {
10791090
}
10801091

10811092
/**
1082-
* Get the current additional compiler search directories, like MinGW directories
1093+
* Get the current additional compiler search directories, like MinGW directories.
1094+
* In multiroot workspaces, reads the setting from each folder's scoped configuration
1095+
* and expands ${workspaceFolder} per-folder, returning the union of all directories.
10831096
*/
10841097
private async getAdditionalCompilerDirs(): Promise<string[]> {
1085-
const optsVars: KitContextVars = {
1086-
userHome: paths.userHome,
1087-
1088-
// This is called during scanning for kits, which is an operation that happens
1089-
// outside the scope of a project folder, so it doesn't need the below variables.
1090-
buildKit: "",
1091-
buildType: "",
1092-
generator: "",
1093-
workspaceFolder: "",
1094-
workspaceFolderBasename: "",
1095-
workspaceHash: "",
1096-
workspaceRoot: "",
1097-
workspaceRootFolderName: "",
1098-
buildKitVendor: "",
1099-
buildKitTriple: "",
1100-
buildKitVersion: "",
1101-
buildKitHostOs: "",
1102-
buildKitTargetOs: "",
1103-
buildKitTargetArch: "",
1104-
buildKitVersionMajor: "",
1105-
buildKitVersionMinor: "",
1106-
projectName: "",
1107-
sourceDir: ""
1108-
};
11091098
const result = new Set<string>();
1110-
for (const dir of this.workspaceConfig.additionalCompilerSearchDirs) {
1111-
const expandedDir: string = util.lightNormalizePath(await expandString(dir, { vars: optsVars }));
1112-
result.add(expandedDir);
1099+
const folders = vscode.workspace.workspaceFolders ?? [];
1100+
1101+
// Collect (folder, dirs) pairs from all workspace folders.
1102+
// Each folder may have its own cmake.additionalCompilerSearchDirs override.
1103+
const folderDirPairs: { folderPath: string; dirs: string[] }[] = [];
1104+
if (folders.length === 0) {
1105+
// No workspace folders — fall back to the extension-level config
1106+
folderDirPairs.push({ folderPath: '', dirs: this.workspaceConfig.additionalCompilerSearchDirs });
1107+
} else {
1108+
for (const folder of folders) {
1109+
const folderConfig = ConfigurationReader.loadConfig(folder);
1110+
const dirs = ConfigurationReader.getAdditionalCompilerSearchDirsFromConfig(folderConfig);
1111+
folderDirPairs.push({ folderPath: folder.uri.fsPath, dirs });
1112+
}
1113+
}
1114+
1115+
for (const { folderPath, dirs } of folderDirPairs) {
1116+
const optsVars: KitContextVars = {
1117+
userHome: paths.userHome,
1118+
1119+
// This is called during scanning for kits, which is an operation that happens
1120+
// outside the scope of a project folder, so it doesn't need most of the below variables.
1121+
// workspaceFolder is populated so that ${workspaceFolder} can be used in additionalCompilerSearchDirs.
1122+
buildKit: "",
1123+
buildType: "",
1124+
generator: "",
1125+
workspaceFolder: folderPath,
1126+
workspaceFolderBasename: folderPath ? path.basename(folderPath) : "",
1127+
workspaceHash: folderPath ? util.makeHashString(folderPath) : "",
1128+
workspaceRoot: folderPath,
1129+
workspaceRootFolderName: folderPath ? path.basename(folderPath) : "",
1130+
buildKitVendor: "",
1131+
buildKitTriple: "",
1132+
buildKitVersion: "",
1133+
buildKitHostOs: "",
1134+
buildKitTargetOs: "",
1135+
buildKitTargetArch: "",
1136+
buildKitVersionMajor: "",
1137+
buildKitVersionMinor: "",
1138+
projectName: "",
1139+
sourceDir: ""
1140+
};
1141+
for (const dir of dirs) {
1142+
const expandedDir: string = util.lightNormalizePath(await expandString(dir, { vars: optsVars }));
1143+
result.add(expandedDir);
1144+
}
11131145
}
1146+
11141147
return Array.from(result);
11151148
}
11161149

0 commit comments

Comments
 (0)