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

How to cross compile to a different libc implementation? #4007

Open
popovicu opened this issue Aug 5, 2024 · 4 comments
Open

How to cross compile to a different libc implementation? #4007

popovicu opened this issue Aug 5, 2024 · 4 comments

Comments

@popovicu
Copy link

popovicu commented Aug 5, 2024

What version of rules_go are you using?

0.46.0

What version of gazelle are you using?

0.35.0

What version of Bazel are you using?

Bazelisk version: v1.19.0

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

Yes

What operating system and processor architecture are you using?

Linux x86_64

Any other potentially useful information about your toolchain?

No

What did you do?

go_binary(
    name = "myprogram",
    srcs = [
        "myprogram.go",
    ],
    deps = [
       ...
    ],
    static = "on",
    cgo=False,
)

go_cross_binary(
    name = "myprogram_rpi0",
    platform = "//platforms:rpi0_linux",
    target = ":myprogram",
)

I want to deploy my binary on a Raspberry Pi Zero and when I just build the myprogram target, I se these warnings:

/tmp/go-link-2058405138/000004.o:cgo_unix_cgo.cgo2.c:function _cgo_97ab22c4dc7b_C2func_getaddrinfo: warning: Using 'getaddrin
fo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking       
/tmp/go-link-2058405138/000004.o:cgo_unix_cgo.cgo2.c:function _cgo_97ab22c4dc7b_Cfunc_getaddrinfo: warning: Using 'getaddrinf
o' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

My Raspberry Pi Zero platform is defined like this:

platform(
    name = "rpi0_linux",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:armv7",
        "@rules_go//go/toolchain:cgo_off",
        "@rules_go//go/constraints/arm:5",
    ],
)

Ultimately, I will want to have musl libc implementation on my Raspberry Pi Zero. How can I avoid the assumption that the libc implementation is GNU on my target platform when cross compiling?

What did you expect to see?

I don't want to see glibc warnings in my build.

What did you see instead?

glibc-related warnings. I understand that static compilation still has some dynamic linking involved in the final product, but this build assumes glibc on the target, I wouldn't want it to do that.

@fmeum
Copy link
Collaborator

fmeum commented Aug 5, 2024

Are you also seeing these warnings with a non-Bazel Go build? It would be very helpful to see and compare the exact command lines the Bazel build and the Go build run.

@popovicu
Copy link
Author

popovicu commented Aug 5, 2024

Hm, this project has grown quite a bit in size and it's very Bazel-centric. Is there any set of CLI flags I can pass to get some debug info? It would be hard to simply rebuild using plain Go.

That said, is it possible for Go to cross compile to another libc at all? What I find in other forums is that it's very centered towards the host's libc implementation.

LLVM/clang on the other hand can cross compile between libcs.

@fmeum
Copy link
Collaborator

fmeum commented Aug 9, 2024

You could override Go rules with local_repository or local_path_override and flip this flag in code:

flags.BoolVar(&env.verbose, "v", false, "Whether subprocess command lines should be printed")

Together with --subcommands, this should allow you to see all compilation commands, including compiler and linker invocations.

@albertocavalcante
Copy link
Contributor

albertocavalcante commented Aug 14, 2024

Thanks for sharing this tip, @fmeum! It's really helpful. Just wondering, do you know if this is documented somewhere? I think it would be useful to add to the docs, if not. I was considering raising a PR for this.

Wanted to add, to test locally I thought a patch would be simpler, so in case it helps, here's an example:

├── patches
│   ├── BUILD.bazel (empty)
│   └── verbose.patch
├── BUILD.bazel
├── MODULE.bazel

MODULE.bazel

bazel_dep(name = "rules_go", version = "0.49.0")
single_version_override(
    module_name = "rules_go",
    patch_strip = 1,
    patches = ["//patches:verbose.patch"],
    version = "0.49.0",
)

verbose.patch

diff --git a/go/tools/builders/env.go b/go/tools/builders/env.go
index bb01ac20..8f70fff5 100644
--- a/go/tools/builders/env.go
+++ b/go/tools/builders/env.go
@@ -75,7 +75,7 @@ func envFlags(flags *flag.FlagSet) *env {
 	flags.StringVar(&env.goroot, "goroot", "", "The value to set for GOROOT.")
 	flags.Var(&tagFlag{}, "tags", "List of build tags considered true.")
 	flags.StringVar(&env.installSuffix, "installsuffix", "", "Standard library under GOROOT/pkg")
-	flags.BoolVar(&env.verbose, "v", false, "Whether subprocess command lines should be printed")
+	flags.BoolVar(&env.verbose, "v", true, "Whether subprocess command lines should be printed")
 	flags.BoolVar(&env.shouldPreserveWorkDir, "work", false, "if true, the temporary work directory will be preserved")
 	return env
 }

For reference: https://sourcegraph.com/github.com/bazelbuild/examples/-/blob/bzlmod/02-override_bazel_module/MODULE.bazel?L26 // https://github.com/bazelbuild/examples/blob/main/bzlmod/02-override_bazel_module/MODULE.bazel#L26

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