bazel-contrib / rules_go

Go rules for Bazel
Apache License 2.0
1.38k stars 660 forks source link

depend on rules that don't have mandatory providers: 'GoLibrary' #3119

Closed Kruemelmann closed 2 years ago

Kruemelmann commented 2 years ago

What version of rules_go are you using?

v0.31.0

What version of gazelle are you using?

v0.24.0

What version of Bazel are you using?

5.1.1

Does this issue reproduce with the latest releases of all the above?

yes

What operating system and processor architecture are you using?

on both:

Any other potentially useful information about your toolchain?

What did you do?

I am building a frontend (in my case react using the rules_nodejs) and after this i want to embed its output into a go binary. So in my understanding i need to depend on the rule that builds my frontend and after this i can use it in embedsrc.

go_library(
    name = "example",
    srcs = ["main.go"],
    embedsrcs = [
        "//ui/example:build_folder",  # keep <- so that gazelle does not kick it out
    ],
    importpath = "github.com/example/example",
    visibility = ["//visibility:public"],
    deps = [
        "//ui/example:build", # keep <- so that gazelle does not kick it out
    ]
)

The project where i got this problem is on github but if thats needed i can provide a minimal example project to reproduce.

What did you expect to see?

I expect the build to first build the gui and after this build use the output and embed it into my go binary.

What did you see instead?

I got this error:

ERROR: /Users/.../example/BUILD.bazel:24:11: in deps attribute of go_library rule //:example: '//ui/example:build' does not have 
mandatory providers: 'GoLibrary'. Since this rule was created by the macro 'go_library_macro', the error might have been caused 
by the macro implementation

which in my understanding means that i can only depend on rules related to rules_go.

Kruemelmann commented 2 years ago

Maybe i am missunderstanding something. Sorry if thats the case just close this issue

achew22 commented 2 years ago

Hurm... Is //ui/example:build a go_library? If not then I don't think this should work that way. embedsrcs (just like data) is about taking a series of bytes and making them available to your binary. deps is how you specify a library that you're going to add an import statement in a .go file for.

Could you elaborate a bit on what //ui/example:build is? Maybe you could point to a repo that's public where this is happening?

Kruemelmann commented 2 years ago

hey @achew22 many thanks for your fast reply on my issue (more a question:) )

Sure first the project https://github.com/Kruemelmann/komodo/blob/1e3221300af5baee4d743480bbb915e7f27f4d9f/BUILD.bazel#L31 The link is pointing to the line in my BUILD file where this happens.

And secound :) thats what I already feared. I am trying to use the build output of a react build and embed these files into my go binary using embedsrcs. Independently the two builds are running and if i use 'ls' I can see the react-build outputfiles in the bazel-bin/ directory. But i dont get the go_library rule in the root of my project to use these files in its build and embed them.

achew22 commented 2 years ago

I think there may be a miscommunication here.

deps is exclusively used when you have go code that wants to depend on go code. That is why it is required to be a GoLibrary provider. Your Javascript is not valid go code and thus can not be depended upon. The code you pointed me to should not exhibit the error that you described in the issue.

You can have all of your js artifacts as an embedsrc target though and that's probably what you actually want and it appears to be what you have. I guess I'm unsure what it is you would want beyond that? It seems like this code is doing something reasonable -- embedding some js source files into the binary using go's embed package.

Can you explain a little bit more, maybe?

Kruemelmann commented 2 years ago

First of all thanks for your patience with me. If that's too much I am sorry and don't want to waste your time.

Yes, you are right the code in the Build file that I was pointing to is indeed running without errors. I commented the deps out because I don't want to commit 'broken' code.

First of all the react-build is working so if I build it using bazel I can see the build output in the bazel-bin folder. (Later more about it in 2.)


  1. Ok what I am able to build:

    1.1 localy build the frontend using

    yarn build

    1.2 start the go build using bazel

    bazel build komodo:komodo_lib

    This build is working fine and with no errors. (That's the current state in my project since I failed to figure out the mistake which I did with bazel)

komodo/
│   WORKSPACE
│   BUILD.bazel
│   
└─ui/
  └──komodo/
     │   BUILD.bazel
     └   build/  <- this is what I can embed, but must build it locally by hand

  1. What i want to build: 1.1 start the go build using bazel
    bazel build komodo:komodo_lib

    If I never build my front-end then there is no build folder in my ui/komodo folder. Now if I trigger the Go build I want bazel to recognise the dependence on the frontend build-output files and build it first.

My frotend can be build using bazel:

bazel build //ui/komodo:build

Which is running without errors, but the build output of the bazel build is obviously inside the bazel-bin folder. So if I trigger a bazel back-end build after my bazel front-end build is finished bazel can't find the build output from the GUI build and does not embed it plus I get this error:

ERROR: <path_to_project>/github.com/kruemelmann/komodo/BUILD.bazel:24:11: GoCompilePkg komodo.a failed: (Exit 1): builder failed: error executing command bazel-out/darwin-opt-exec-2B5CBBC6/bin/external/go_sdk/builder compilepkg -sdk external/go_sdk -installsuffix darwin_amd64 -src embed.go -importpath github.com/kruemelmann/komodo -p ... (remaining 11 arguments skipped)

Use --sandbox_debug to see verbose messages from the sandbox
compilepkg: <path_to_tmp>/sandbox/darwin-sandbox/2/execroot/komodo/embed.go:5:12: could not embed ui/komodo/build/*: no matching files found
Target //cmd/komodo:komodo_lib failed to build
Use --verbose_failures to see the command lines of failed build steps.

The error occurs because bazel can´t find the build-output folder since it is inside the bazel-bin folder.

komodo/
│   WORKSPACE
│   BUILD.bazel
└──bazel-bin/
   └─ui/
      └──komodo/
         └── build/  <- this is what i want to embed so i dont need to build it by hand
Kruemelmann commented 2 years ago

hi @achew22

In the last weeks I was thinking about this problem and was not able to solve it. I would be happy to provide a minimal working example if you wish to.

Kruemelmann commented 2 years ago

I am closing this issue since I found my problem thanks to this: https://github.com/bazelbuild/rules_go/issues/3040#issuecomment-1142570586

Many thanks again for your patience and help @achew22 :)