cps-org / cps

Common Package Specification — A cross-tool mechanism for locating software dependencies
https://cps-org.github.io/cps/
Other
91 stars 8 forks source link

Interface manifests #18

Open bretbrownjr opened 9 months ago

bretbrownjr commented 9 months ago

This is not a required feature for a "1.0" release of CPS. But I could see this being one of a few "killer apps" that drive goodwill and adoption for CPS.

The use case I have in mind is a tool, possibly a feature of a build system, that can communicate to project maintainers about when library dependencies are missing or unneeded. This is analogous to tools like include-what-you-use, but targeting interproject dependencies.

Now, there are various pieces of functionality needed to implement a feature like that, but there is a missing bit of data that seems to be essential but missing. Specifically we need to be able to tell what dependency a #include maps to. I believe a sensible way to supply that information is for CPS files to contain a manifest (or multiple manifests in some cases) describing the interface for the library. That is, not just provide the install location of the headers but a list of the headers themselves.

Essentially, a link-what-you-include tool would need to be able to look at a #include <some/arbitrary/interface> and know what CPS-defined libraries provide some/arbitrary/interface. Then actual dependency declarations (like *LINK_LIBRARIES properties on CMake targets) can be inspected for errors.

CMake already models the required metadata via the new HEADERS FILE_SET feature. I would be looking for a CPS version of that information exported for end users.

As we gain more opinions about C++ modules, I expect that module interfaces would likewise be listed, though I expect some version of that information would be available via whatever module metadata files are developed. This problem is more essential to C++ modules workflows since there's immediately a need to map from import some_arbitrary_module; to actual files to parse.

jsharpe commented 8 months ago

IMO this is absolutely required for a "1.0" release; build systems that utilise sandboxing such as Bazel / Buck2 / Pants require an exact list of input files to place into the sandbox in order to ensure hermeticity of the build. Ideally the input files are broken down into the individual phases of compilation i.e. files required for cpp-compile and those required for linking.

mathstuf commented 8 months ago

There are also things like #embed and std::embed, so resource files may be of interest here. Other than that, I think just having ways of specifying relevant languages (e.g., a foo.hpp wrapper around a C API doesn't need to be mentioned for a C compilation) and a compile/link split sounds fine to me.