Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalize to multiple C libraries #294

Open
edsko opened this issue Nov 20, 2024 · 2 comments
Open

Generalize to multiple C libraries #294

edsko opened this issue Nov 20, 2024 · 2 comments

Comments

@edsko
Copy link
Collaborator

edsko commented Nov 20, 2024

(This could be considered an instance of #75.)

Suppose we are generating bindings for multiple C libraries, and those libraries have inter-dependencies; perhaps library A exports some types that are used by library B. Then we should be able to generate bindings for library B in such a way that the bindings for A and B can be used together.

@edsko edsko added this to the 1: `Storable` instances milestone Nov 20, 2024
@phadej
Copy link
Collaborator

phadej commented Nov 26, 2024

I guess this is a generalization of having "stdlib prelude + header" to "stdlib prelude + some libraries + header". We'd need a way to configure that some (intermediate) types are from some 3rd party module.

Then we can process various "libraries" separately.

As I said in #75, trying to process into multiple modules would not work, not with Cabal-like 1-to-1 preprocessor support, not really with TH either.

@edsko
Copy link
Collaborator Author

edsko commented Jan 29, 2025

Current proposal:

  1. The critical thing when interacting with other bindings is that the types line up. We therefore propose that bindgen can read files that map C identifiers to Haskell identifiers.
  2. To make this mapping precise, on the Haskell side it's relatively easy: package, module, type name.
  3. On the C side it's a bit trickier. We propose that the binding can say "C identifier foo, defined in any of the following list of headers: x, y,. .. z". We then consider a C identifier to be a match if we see foo and it's defined in a header h which is either one of x, y, ..., z, or (directly or indirectly) included by any of the x, y, .. z. Rationale: (1) some C types are defined in what are essentially "private" headers, that are included by public headers, but should not be considered as part of the public API, and (2) some of these types, defined in an internal header, are actually reachable ("part of") multiple public headers.
  4. This makes it possible to use types defined in other Haskell packages whether or not they use hs-bindgen or not (of course they need to be compatible, but that's the responsibility of the author of the mapping).
  5. The stdlib then becomes a set of two of these files: one for types defined in base, and one for the few types (there's only a dozen or so) in the C stdlib that aren't in base and that we define in hs-bindgen-runtime.
  6. Whether or not we generate the prelude is now much less of a concern; we can stick with what we have for now, and can always reconsider later. One advantage of this approach is that it's actually fine if we cannot parse or process the full prelude; all we need to know is the "header DAG" (we should find a better name for that).
  7. For bindings generated by hs-bindgen, hs-bindgen can of course generate such a mapping, which would then be usable in other hs-bindgen bindings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants