cli / gh-extension-precompile

Action for publishing binary GitHub CLI extensions
MIT License
93 stars 41 forks source link

Error: android/amd64 requires external (cgo) linking, but cgo is not enabled #50

Closed nicokosi closed 2 months ago

nicokosi commented 8 months ago

Hello,

I cannot release nicokosi/gh-collab-scanner, cf. this GitHub Actions' job:

Run cli/gh-extension-precompile@v1
  with:
    go_version: 1.22
Run actions/setup-go@v3
Setup go version spec 1.22
Found in cache @ /opt/hostedtoolcache/go/1.22.0/x64
Added go to the path
Successfully set up Go version 1.22
go version go1.22.0 linux/amd64

go env
Run if [ -n "$INPUT_TOKEN" ]; then
Run if [ -n "$INPUT_TAG" ]; then
Run if [ -n "$INPUT_TITLE" ]; then
Run ${GITHUB_ACTION_PATH//\\//}/build_and_release.sh
go: downloading github.com/cli/go-gh/v2 v2.5.0
✂️...✂️
go: downloading github.com/mattn/go-runewidth v0.0.14
go: downloading github.com/rivo/uniseg v0.4.4
android/amd64 requires external (cgo) linking, but cgo is not enabled
Error: Process completed with exit code 1.

The last release that succeeded, v1.5.3:

I tried several changes: enable CGO (not sure it is correct), use a Windows runner etc. but I could not make the release succeed (see the GitHub Actions build history).

Do you have any advice/tip? Thank you!

nicokosi commented 8 months ago

No error after downgrading Go to 1.21, see gh-collab-scanner 1.5.4. I presume that it is a Go issue related to GitHub Actions Runner Images, but maybe that this issue can be kept open (using Go 1.21 instead of latest 1.22 is a work-around)? 🤷

Biswa96 commented 8 months ago

Try with CGO_ENABLED=1

baruchiro commented 8 months ago

With CGO_ENABLED=1:

gcc_android.c:6:10: fatal error: android/log.h: No such file or directory
    6 | #include <android/log.h>
      |          ^~~~~~~~~~~~~~~
compilation terminated.

Go version: 1.22

the-hotmann commented 7 months ago

Same error here. Since go v1.22 it requires cgo for at least those platforms:

... maybe more

andyfeller commented 6 months ago

@nicokosi @Biswa96 @baruchiro @the-hotmann : firstly, thank you all for raising this issue and starting exploring the nuances. ❤

I'm currently looking into this issue to see how this changing behavior with Go 1.22 should be taken into account here 🙇

Research

Source: https://github.com/golang/go/blob/1ca31eac40c0400efc8211bc2483fd621264be11/src/internal/platform/supported.go#L83-L127

// MustLinkExternal reports whether goos/goarch requires external linking
// with or without cgo dependencies.
func MustLinkExternal(goos, goarch string, withCgo bool) bool {
    if withCgo {
        switch goarch {
        case "loong64", "mips", "mipsle", "mips64", "mips64le":
            // Internally linking cgo is incomplete on some architectures.
            // https://go.dev/issue/14449
            return true
        case "arm64":
            if goos == "windows" {
                // windows/arm64 internal linking is not implemented.
                return true
            }
        case "ppc64":
            // Big Endian PPC64 cgo internal linking is not implemented for aix or linux.
            // https://go.dev/issue/8912
            if goos == "aix" || goos == "linux" {
                return true
            }
        }

        switch goos {
        case "android":
            return true
        case "dragonfly":
            // It seems that on Dragonfly thread local storage is
            // set up by the dynamic linker, so internal cgo linking
            // doesn't work. Test case is "go test runtime/cgo".
            return true
        }
    }

    switch goos {
    case "android":
        if goarch != "arm64" {
            return true
        }
    case "ios":
        if goarch == "arm64" {
            return true
        }
    }
    return false
}
andyfeller commented 6 months ago

Update

Doing a bit of digging, one option I need to carve out a little more time to try comes from https://github.com/golang/go/issues/42725#issuecomment-731438285, which highlights the need to override CC when compiling for android to point to Android NDK which is maintained on GitHub-hosted runners:

GOOS=android GOARCH=arm64 CGO_ENABLED=1 CC=$NDK_ROOT/21.3.6528147/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang go build

This should live within $ANDROID_NDK_HOME on GitHub-managed runners

Finding similar approaches in the wild

chtzvt commented 3 months ago

For what it's worth, I've been able to work around this problem by forking the action and removing Android build targets from build_and_release.sh:

platforms=(
  darwin-amd64
  darwin-arm64
  freebsd-386
  freebsd-amd64
  freebsd-arm64
  linux-386
  linux-amd64
  linux-arm
  linux-arm64
  windows-386
  windows-amd64
  windows-arm64
)

I'm uninformed regarding the rationale for maintaining Android as a build target for CLI extensions in the first place. In our case, we decided that the accessibility of recent Go versions was more important than maintaining support for a build target we expect to be used rarely (if ever) by the end users of our particular extension.