Skip to content
This repository was archived by the owner on Sep 9, 2025. It is now read-only.
This repository was archived by the owner on Sep 9, 2025. It is now read-only.

How will you resolve C/C++ include locations? #493

Description

@dangerzone

Thanks for this project, I realize C and C++ aren't supported yet, but I'm sure it's something you've thought about it. It's something I'm running into now.

Without trying to build the software, how will Stack Graphs know how to resolve an #include location? such things are typically managed by a make file or some build system like cmake because there is no standardized way of setting up projects in C/C++.

Looking forward to your insight, because I'm stumped.

Activity

  1. dcreager commented on Jun 10, 2025

    @dcreager
    Contributor

    Thanks for reaching out! I should point out that GitHub is no longer investing in stack graphs, and I no longer work for GitHub even if they were! But here are some of the possibilities that we had been considering.

    The simplest is to not worry about where the include files actually live, and lean into the fact that C has a single global namespace for identifiers. You'd create a reference node for each identifier, and would add a path leading to the root node that would look for that identifier in some other file. (That would be in addition to the paths that would look for the identifier in the current translation unit.) As long as you process all of the .h and .c files in your project, you'd find cross-file paths from the reference to its declaration and/or definition regardless of which file they appear in. (That means that you couldn't use your stack graph to enforce that each file correctly #includes all of the headers that it needs to. But that's not necessarily a bad thing for an exploratory feature like Code Nav.)

    If you do want to enforce correct #includes, then you'd add a guard node to each file's stack graph. The guard node would be a definition node or a pop node. It would be in between the root node and the definitions in that file, and its symbol would encode the filename of the file. That would prevent other files from "seeing" the definitions unless they pushed the correct filename symbol onto the symbol stack before moving to the root node. You'd add a separate edge to the root node for each #include statement, each of which uses a push node to add the filename symbol for that #include. That ensures that you can only see cross-file definitions if you include the right header — but only really works for include files that don't have path components.

    To add path awareness, you need to start generating stack graph content for things other than the .h and .c files. You would add stack graph content for the directory structure itself, and for e.g. the Makefiles in your project. Each file would have a guard node encoding its blob SHA, not its filename. The directory structure from git would tell you things like "there is a file at include/libcork/core.h with SHA ab123". The Makefile would tell you things like "we have -Iinclude in our build flags, so if you're trying to include FOO, you might find it at include/FOO". And all of that together should let you trace from the original reference, through the #include gadget that encodes the filename, through the build flags + directory structure that turns that into a blob SHA, through the guard node into the file that actually holds the definition.

    (We actually implemented a version of the second for Python, generating stack graph content for setup.py and pyproject.toml to link up Python module structure with project-specific locations within a repo. But that was only in the internal services, and never made it out to the open-source stack graph rules that I'm aware of.)

  2. CleanCut commented on Sep 9, 2025

    @CleanCut

    The github/stack-graphs repository is no longer being maintained. As per #502, I'm closing all issues and pull requests before archiving the repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions