MCPcopy
hub / github.com/colbymchenry/codegraph / loadCppIncludeDirsFromCompileDB

Function loadCppIncludeDirsFromCompileDB

src/resolution/import-resolver.ts:367–433  ·  view source on GitHub ↗

* Try to load include directories from compile_commands.json. * Returns null if no compilation database is found (so the heuristic * fallback can run). Returns an array (possibly empty) otherwise.

(projectRoot: string)

Source from the content-addressed store, hash-verified

365 * fallback can run). Returns an array (possibly empty) otherwise.
366 */
367function loadCppIncludeDirsFromCompileDB(projectRoot: string): string[] | null {
368 const candidates = [
369 path.join(projectRoot, 'compile_commands.json'),
370 path.join(projectRoot, 'build', 'compile_commands.json'),
371 path.join(projectRoot, 'cmake-build-debug', 'compile_commands.json'),
372 path.join(projectRoot, 'cmake-build-release', 'compile_commands.json'),
373 path.join(projectRoot, 'out', 'compile_commands.json'),
374 ];
375
376 let dbPath: string | undefined;
377 for (const c of candidates) {
378 try {
379 if (fs.existsSync(c)) {
380 dbPath = c;
381 break;
382 }
383 } catch {
384 // ignore
385 }
386 }
387 if (!dbPath) return null;
388
389 try {
390 const content = fs.readFileSync(dbPath, 'utf-8');
391 const entries = JSON.parse(content) as Array<{
392 directory: string;
393 command?: string;
394 arguments?: string[];
395 }>;
396 if (!Array.isArray(entries)) return null;
397
398 const dirSet = new Set<string>();
399 for (const entry of entries) {
400 const dir = entry.directory || projectRoot;
401 const args = entry.arguments || (entry.command ? shlexSplit(entry.command) : []);
402 for (let i = 0; i < args.length; i++) {
403 const arg = args[i]!;
404 let includeDir: string | undefined;
405 // -I<dir> (no space)
406 if (arg.startsWith('-I') && arg.length > 2) {
407 includeDir = arg.substring(2);
408 }
409 // -isystem <dir> (space-separated)
410 else if ((arg === '-isystem' || arg === '-I') && i + 1 < args.length) {
411 includeDir = args[i + 1];
412 i++; // skip next arg
413 }
414 if (includeDir) {
415 // Normalize: resolve relative to the compilation directory
416 const absPath = path.isAbsolute(includeDir)
417 ? includeDir
418 : path.resolve(dir, includeDir);
419 const relPath = path.relative(projectRoot, absPath).replace(/\\/g, '/');
420 // Skip system directories and paths outside the project
421 // (relative paths starting with .. or absolute paths like
422 // /usr/include or C:\usr on Windows)
423 if (!relPath.startsWith('..') && relPath.length > 0 && !path.isAbsolute(relPath)) {
424 dirSet.add(relPath);

Callers 1

loadCppIncludeDirsFunction · 0.85

Calls 3

shlexSplitFunction · 0.85
joinMethod · 0.80
resolveMethod · 0.80

Tested by

no test coverage detected