0.25.1
0.22.3
3.7.2
Hey all, I recently decided to use rules_go in an attempt to generate shared dynamic libraries using CGo and consume my Go code from other non-Go Bazel targets. I thought that perhaps just listing the go_binary as a dependency might use the output of the binary build, but instead, I received:
alias referring to go_transition_binary rule '//shared:odict' is misplaced here (expected cc_binary, cc_library, genrule, genproto, java_import, java_library, java_proto_library, java_lite_proto_library, proto_library, sh_binary or sh_library).
I'm aware of #2445 adding CcInfo functionality to go_binary, which would be ideal, but in the meantime, I'm curious if there are any workarounds anyone is using.
Just add .cc to the target name and use linkmode="c-archive" or "c-shared".
The tests have an example of this if you need more info.
@steeve Oh wow, thanks! Had no idea it was that easy. Do you also happen to know how you can access the library from your code? I realized using data or resources (for Java, for instance) will copy over at least the dylib so you could call System.Load() from within the runfiles directory. Specifying a cc dep doesn't seem to do that.
@Nickersoft the dylib should be available for System.load() to work, just like any other .so.
Hello! I have a similar question to @Nickersoft I was hoping someone could answer. I'm also trying to load a generated .so library from my c code. I tried following the steps @steeve suggested as well as the comments made in this stackoverflow post, but to no avail. Any thoughts what I could be doing wrong here?
Bazel BUILD file:
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_binary(
name = "go_code",
srcs = ["go_hello.go"],
cgo = True,
linkmode = "c-shared",
out = "go_code.so",
)
cc_binary(
name = "cc_code",
srcs = ["cc_hello.c"],
deps = [":go_code.cc"],
)
cc_hello.c file which should use the generate Golang shared lib
#include "go_hello.h"
int main()
{
SayHello();
return 0;
}
go_hello.go file which should generate the .so and .h file to be used in the c-code
package main
import "fmt"
import "C"
//export SayHello
func SayHello() {
fmt.Println("hello")
}
func main() {}
But when building this configuration with the command bazel build //:cc_code, I get the following error:
...
03_bazel_go_starlark_dlls/cc_hello.c:1:10: fatal error: 'go_hello.h' file not found
#include "go_hello.h"
...
Any thoughts on what I'm doing wrong here? Thanks in advance for any help 😄
@josiahsrc If I had to guess, you may need to import the generated header from a subdirectory in your runfiles directory (although it usually follows the structure of your actual project, so in this case I might not be sure...) Good news is though the project I'm working on is open-source and I managed to get the generated .so working with C++, JNI, and Python! So you can reference it if you want.
So to give an example, my Go target lived in //bridge:archived, so the generated header was found under bridge/archived.h.
That project source was very helpful. You were spot on, I was importing the file from an invalid path 🤦♂️ Your project also helped me use the .so files within a java context which was my original goal. Thanks @Nickersoft !
In case anyone else stumbles across this issue, here is another playground example in addition to @Nickersoft's repository.
@josiahsrc I'm glad! You have NO idea how long it took me to finally get the code in that repo working haha. Anyway, sounds like this issue is pretty much resolved so I'm going to close it out. Hopefully #2445 can be merged someday soon :) Thanks @steeve for all the help!
Indeed, the path to the header is the full package path.
Perhaps we should document it better in the docs, but I'm rooting for the time where .cc is not needed anymore.
Most helpful comment
@josiahsrc I'm glad! You have NO idea how long it took me to finally get the code in that repo working haha. Anyway, sounds like this issue is pretty much resolved so I'm going to close it out. Hopefully #2445 can be merged someday soon :) Thanks @steeve for all the help!