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

Is it possible to have a rule forward to another rule? #496

Closed
zjturner opened this issue Nov 15, 2023 · 4 comments
Closed

Is it possible to have a rule forward to another rule? #496

zjturner opened this issue Nov 15, 2023 · 4 comments

Comments

@zjturner
Copy link
Contributor

zjturner commented Nov 15, 2023

If I do this:

def _inner_impl(ctx: AnalysisContext) -> list[Provider]:
    return [DefaultInfo()]

def _outer_impl(ctx: AnalysisContext) -> list[Provider]:
    return inner()

inner = rule(
    attrs = {},
    impl = _inner_impl
)

outer = rule(
    attrs = {},
    impl = _outer_impl
)

I get the following error:

BUILD FAILED
Error running analysis for `root//:outer (foo//platforms:my-platform#23b3e4bdecafe14a)`

Caused by:
    Traceback (most recent call last):
      File <builtin>, in <module>
      * foo/test_rule.bzl:8, in _outer_impl
          return inner()
    error: This function is unavailable during analysis (usual solution is to place the information on a toolchain)
     --> foo/test_rule.bzl:8:12
      |
    8 |     return inner()
      |            ^^^^^^^

I was experimenting with the idea of wrapping rules like cxx_library() to modify / change up the arguments before I pass them in. I feel like it gives me the ability to generate better error messages when the user does something wrong.

My guess is you just can't do this, but figured it was worth asking about.

@cormacrelf
Copy link
Contributor

cormacrelf commented Nov 15, 2023

You can make a macro.

def wrapped_cxx_library(srcs=[], **kwargs):
    srcs.append("file.hh")
    native.cxx_library(srcs = srcs, **kwargs)

You don't need to return anything, rules don't return anything when you call them anyway (only the impl functions do). You can call multiple rules, and connect up the outputs of one to the inputs of the other, by constructing

whatever = "{}-whatever".format(name)
native.cxx_library(name = whatever, ...)

native.cxx_library(..., deps = kwargs.pop("deps") + [":{}".format(whatever)], **kwargs)

@zjturner
Copy link
Contributor Author

I'm using macros for this purpose right now, and it generally works ok but sometimes I wish I had access to some of the things in a rule impl's context structure.

@cjhopman
Copy link
Contributor

The inner() function is a function that declares a target (and does a bunch of other stuff). As the error message indicates, you cannot do that during analysis. You could, however, call the _inner_impl() function if you wanted.

@zjturner
Copy link
Contributor Author

Yea, unfortunately I can't do that unless I have access to the impl. So I can't do it, for example, if I want to forward to cxx_library. In any case, I can continue with just using macros, I can still solve the problem I was having, just not as nicely as if I had the full power of a rule.

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

3 participants