Skip to content

Commit 9249e27

Browse files
Jim Griesmerbobbrow
authored andcommitted
Initial implementation for supporting vcpkg (#1886)
* Initial implementation for supporting vcpkg
1 parent 063c4bd commit 9249e27

File tree

2 files changed

+70
-7
lines changed

2 files changed

+70
-7
lines changed

Extension/src/LanguageServer/configurations.ts

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ export class CppProperties {
8080
private defaultCppStandard: string = null;
8181
private defaultIncludes: string[] = null;
8282
private defaultFrameworks: string[] = null;
83+
private vcpkgIncludes: string[] = [];
84+
private vcpkgPathReady: boolean = false;
8385
private defaultIntelliSenseMode: string = null;
8486
private readonly configurationGlobPattern: string = "**/c_cpp_properties.json"; // TODO: probably should be a single file, not all files...
8587
private disposables: vscode.Disposable[] = [];
@@ -124,6 +126,8 @@ export class CppProperties {
124126
this.handleConfigurationChange();
125127
});
126128

129+
this.buildVcpkgIncludePath();
130+
127131
this.disposables.push(vscode.Disposable.from(this.configurationsChanged, this.selectionChanged, this.compileCommandsChanged));
128132
}
129133

@@ -184,8 +188,8 @@ export class CppProperties {
184188
this.configurationIncomplete = true;
185189
}
186190

187-
private applyDefaultIncludePathsAndFrameworks(): void {
188-
if (this.configurationIncomplete && this.defaultIncludes && this.defaultFrameworks) {
191+
private applyDefaultIncludePathsAndFrameworks(): void {
192+
if (this.configurationIncomplete && this.defaultIncludes && this.defaultFrameworks && this.vcpkgPathReady) {
189193
let configuration: Configuration = this.configurationJson.configurations[this.CurrentConfiguration];
190194
let settings: CppSettings = new CppSettings(this.rootUri);
191195

@@ -197,15 +201,15 @@ export class CppProperties {
197201

198202
if (!settings.defaultIncludePath) {
199203
// We don't add system includes to the includePath anymore. The language server has this information.
200-
configuration.includePath = ["${workspaceFolder}"];
204+
configuration.includePath = ["${workspaceFolder}"].concat(this.vcpkgIncludes);
205+
}
206+
if (!settings.defaultBrowsePath) {
207+
// We don't add system includes to the includePath anymore. The language server has this information.
208+
configuration.browse.path = ["${workspaceFolder}"].concat(this.vcpkgIncludes);
201209
}
202210
if (!settings.defaultDefines) {
203211
configuration.defines = (process.platform === 'win32') ? ["_DEBUG", "UNICODE", "_UNICODE"] : [];
204212
}
205-
if (!settings.defaultBrowsePath) {
206-
// We don't add system includes to the browse.path anymore. The language server has this information.
207-
configuration.browse.path = ["${workspaceFolder}"];
208-
}
209213
if (!settings.defaultMacFrameworkPath && process.platform === 'darwin') {
210214
configuration.macFrameworkPath = this.defaultFrameworks;
211215
}
@@ -225,6 +229,35 @@ export class CppProperties {
225229
}
226230
}
227231

232+
private async buildVcpkgIncludePath(): Promise<void> {
233+
try {
234+
// Check for vcpkg instance and include relevent paths if found.
235+
if (await util.checkFileExists(util.getVcpkgPathDescriptorFile())) {
236+
let vcpkgRoot: string = await util.readFileText(util.getVcpkgPathDescriptorFile());
237+
let vcpkgInstallPath: string = path.join(vcpkgRoot.trim(), "/vcpkg/installed");
238+
if (await util.checkDirectoryExists(vcpkgInstallPath)) {
239+
let list: string[] = await util.readDir(vcpkgInstallPath);
240+
// For every *directory* in the list (non-recursive)
241+
list.forEach((entry) => {
242+
if (entry !== "vcpkg") {
243+
let pathToCheck: string = path.join(vcpkgInstallPath, entry);
244+
if (fs.existsSync(pathToCheck)) {
245+
let p: string = path.join(pathToCheck, "include");
246+
if (fs.existsSync(p)) {
247+
this.vcpkgIncludes.push(p);
248+
}
249+
}
250+
}
251+
});
252+
}
253+
}
254+
} catch (error) {} finally {
255+
this.vcpkgPathReady = true;
256+
this.handleConfigurationChange();
257+
}
258+
259+
}
260+
228261
private getConfigIndexForPlatform(config: any): number {
229262
if (this.configurationJson.configurations.length > 3) {
230263
return this.configurationJson.configurations.length - 1; // Default to the last custom configuration.

Extension/src/common.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ export function getPackageJsonPath(): string {
4949
return getExtensionFilePath("package.json");
5050
}
5151

52+
export function getVcpkgPathDescriptorFile(): string {
53+
if (process.platform === 'win32') {
54+
return path.join(process.env.LOCALAPPDATA, "vcpkg/vcpkg.path.txt");
55+
} else {
56+
return path.join(process.env.HOME, ".vcpkg/vcpkg.path.txt");
57+
}
58+
}
59+
5260
// Extension is ready if install.lock exists and debugAdapters folder exist.
5361
export async function isExtensionReady(): Promise<boolean> {
5462
const doesInstallLockFileExist: boolean = await checkInstallLockFile();
@@ -266,6 +274,28 @@ export function checkFileExists(filePath: string): Promise<boolean> {
266274
});
267275
}
268276

277+
/** Test whether a directory exists */
278+
export function checkDirectoryExists(dirPath: string): Promise<boolean> {
279+
return new Promise((resolve, reject) => {
280+
fs.stat(dirPath, (err, stats) => {
281+
if (stats && stats.isDirectory()) {
282+
resolve(true);
283+
} else {
284+
resolve(false);
285+
}
286+
});
287+
});
288+
}
289+
290+
/** Read the files in a directory */
291+
export function readDir(dirPath: string): Promise<string[]> {
292+
return new Promise((resolve) => {
293+
fs.readdir(dirPath, (err, list) => {
294+
resolve(list);
295+
});
296+
});
297+
}
298+
269299
/** Test whether the lock file exists.*/
270300
export function checkInstallLockFile(): Promise<boolean> {
271301
return checkFileExists(getInstallLockPath());

0 commit comments

Comments
 (0)