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

feat: extra language inputs for bazel codegen #1904

Open
wants to merge 1 commit into
base: v2
Choose a base branch
from

Conversation

sgammon
Copy link

@sgammon sgammon commented Jan 12, 2024

Summary

When using language plugins like Cap'n'proto for Java from Bazel, there needs to be a way to add language extras as inputs to the codegen phase.

This is only needed when generating capnp code in multiple languages. Even if the generator is only producing a C++ output in a given invocation, the imports for other languages will fail to be found due to Bazel's strict sandboxing. This new attribute fixes that condition.

Fixes and closes #1903.

Changelog

  • add language_extras argument to cc_capnp_library macro
  • add language_extras label_list attribute to rule definition
  • process such inputs, if provided, into inputs and args (-I <parent_dir_of_extra>)

@sgammon sgammon changed the title feat: extra language inputs for codegen feat: extra language inputs for bazel codegen Jan 12, 2024
@sgammon sgammon mentioned this pull request Jan 16, 2024
12 tasks
@sgammon
Copy link
Author

sgammon commented Jan 23, 2024

@kentonv / @mikea any objection to merging this one first? I can then rebase it out of my bigger PR for Bzlmod. This one should be pretty inert and sensible.

@mikea
Copy link
Collaborator

mikea commented Feb 9, 2024

Sorry for delay. Multi language support is something I wanted to add myself. I was hoping to do it similar to the way protobuf is structured, but quickly ran into limitations of my bazel knowledge.

This change looks much simpler, however I don't understand how does it help with the task? Where are additional plug-in arguments specified?

Could you expand a little on the usage too? How do you use it to, generate another language? (Not sure what's your interest but I was looking into rust)

Comment on lines +52 to +63
# process language extras, starting with files we should include
extra_inputs = ctx.files.language_extras or []

# then compute input flags, taking the parent of the first file in each extra as the include path
if len(ctx.attr.language_extras) > 0:
for extra in ctx.attr.language_extras:
files = extra.files.to_list()
if len(files) > 0:
args.add_all(["-I", files[0].dirname.removesuffix("/capnp")])

ctx.actions.run(
inputs = inputs + ctx.files._capnpc_cxx + ctx.files._capnpc_capnp + ctx.files._capnp_system,
inputs = inputs + ctx.files._capnpc_cxx + ctx.files._capnpc_capnp + ctx.files._capnp_system + extra_inputs,
Copy link
Author

@sgammon sgammon Feb 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mikea Here's the entire change; the rest is wiring. If the user passes additional targets via the language_extras attribute, their files are included as inputs in the run, and each directory containing language extras is included via -I.

The effect is that the user can pass arbitrary dependencies to be exposed in the sandbox, and can include them easily within the capnp sources.

We're using this change downstream in an internal Bazel project, and it's working great, specifically to generate Java capnp sources.

I actually know exactly what you're talking about re/rules_proto. It is a little brain-melting to get aspects all working together properly, certainly not for the faint of heart. I've died on that same hill before.

So, I think you're right, it would be fantastic to get true first-class Bazel support for capnp in the same way Protocol Buffers is supported, including easy generation of different languages. But in the meantime, this gives capnp users an escape hatch in Bazel builds where there is no explicit support for their language yet.

Thus, these attributes could be kept to use in-house language implementations, or to facilitate easy testing, etc etc, alongside future attributes or rules or aspects which bring support to parity.

In other words, this change shouldn't preclude better support later.

@sgammon
Copy link
Author

sgammon commented Feb 14, 2024

Usage example, which I'm happy to add to docs/README:

@capnp-java//:capnpj_system_library:

# ...

filegroup(
   name = "capnpj_system_library",
   srcs = [
       "java.capnp",
   ],
   visibility = ["//visibility:public"],
)

# ...

BUILD.bazel:

# ...

cc_capnp_library(
    name = "some-capnp",
    srcs = ["some.capnp"],
    language_extras = ["@capnp-java//:capnpj_system_library"],
    # ...
)

# ...

some.capnp:

using Cxx = import "/capnp/c++.capnp";
using Java = import "/capnp/java.capnp";

# ...

When using language plugins like Cap'n'proto for Java from Bazel,
there needs to be a way to add language extras as inputs to the
codegen phase.

This is only needed when generating capnp code in multiple
languages. Even if the generator is only producing a C++ in a
given invocation, the imports for other languages will fail to be
found due to Bazel's strict sandboxing. This new attribute fixes
that condition.

Fixes and closes capnproto#1903.

Relates-To: elide-dev/bigtent#6
Relates-To: capnproto#1903
Signed-off-by: Sam Gammon <sam@elide.ventures>
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

Successfully merging this pull request may close these issues.

No way to pass extra language inputs
2 participants