Using https://github.com/uber/h3-go in Netlify Functions?

I am trying to use this GitHub - uber/h3-go: Go bindings for H3, a hierarchical hexagonal geospatial indexing system in a Netlify Function on https://expl.netlify.app

They have this in their README:

If you see errors/warnings like “build constraints exclude all Go files…” , then the cgo build constraint is likely disabled; try setting CGO_ENABLED=1 environment variable in your go build step.

I seem to have done so, but still unable to build:

10:09:59 AM: Netlify Build                                                 
10:09:59 AM: ────────────────────────────────────────────────────────────────
10:09:59 AM: ​
10:09:59 AM: ❯ Version
10:09:59 AM:   @netlify/build 29.53.0
10:09:59 AM: ​
10:09:59 AM: ❯ Flags
10:09:59 AM:   baseRelDir: true
10:09:59 AM:   buildId: 66b5dcd33f408123e6a8ed9c
10:09:59 AM:   deployId: 66b5dcd33f408123e6a8ed9e
10:09:59 AM: ​
10:09:59 AM: ❯ Current directory
10:09:59 AM:   /opt/build/repo
10:09:59 AM: ​
10:09:59 AM: ❯ Config file
10:09:59 AM:   /opt/build/repo/netlify.toml
10:09:59 AM: ​
10:09:59 AM: ❯ Context
10:09:59 AM:   production
10:09:59 AM: ​
10:09:59 AM: build.command from netlify.toml                               
10:09:59 AM: ────────────────────────────────────────────────────────────────
10:09:59 AM: ​
10:09:59 AM: $ CGO_ENABLED=1 go build
10:09:59 AM: go: downloading github.com/joho/godotenv v1.5.1
10:09:59 AM: go: downloading github.com/lib/pq v1.10.9
10:09:59 AM: go: downloading github.com/uber/h3-go v3.0.1+incompatible
10:10:03 AM: ​
10:10:03 AM: (build.command completed in 3.4s)
10:10:03 AM: ​
10:10:03 AM: Functions bundling                                            
10:10:03 AM: ────────────────────────────────────────────────────────────────
10:10:03 AM: ​
10:10:03 AM: Packaging Functions from netlify/functions directory:
10:10:03 AM:  - hello/main.go
10:10:03 AM:  - visited/main.go
10:10:03 AM: ​
10:10:07 AM: Failed during stage 'building site': Build script returned non-zero exit code: 2 (https://ntl.fyi/exit-code-2)
10:10:07 AM: Could not compile Go function visited:
10:10:07 AM: ​
10:10:07 AM: Bundling of function "visited" failed                         
10:10:07 AM: ────────────────────────────────────────────────────────────────
10:10:07 AM: ​
10:10:07 AM:   Error message
10:10:07 AM:   Command failed with exit code 1: go build -o /tmp/zisi-66b5dcd33f408123e6a8ed9e/visited -ldflags -s -w -tags lambda.norpc (https://ntl.fyi/exit-code-1)
10:10:07 AM:   go: downloading github.com/aws/aws-lambda-go v1.47.0
10:10:07 AM:   go: downloading github.com/uber/h3-go/v4 v4.1.0
10:10:07 AM:   github.com/uber/h3-go/v4: build constraints exclude all Go files in /opt/buildhome/.gimme_cache/gopath/pkg/mod/github.com/uber/h3-go/v4@v4.1.0
10:10:07 AM: ​
10:10:07 AM:   Error location
10:10:07 AM:   While bundling function "visited"
10:10:07 AM: ​
10:10:07 AM:   Resolved config
10:10:07 AM:   build:
10:10:07 AM:     command: CGO_ENABLED=1 go build
10:10:07 AM:     commandOrigin: config
10:10:07 AM:     environment:
10:10:07 AM:       - POSTGRES_URL_NON_POOLING
10:10:07 AM:       - CGO_ENABLED
10:10:07 AM:     publish: /opt/build/repo/public
10:10:07 AM:     publishOrigin: config
10:10:07 AM:   functionsDirectory: /opt/build/repo/netlify/functions
10:10:07 AM:   headers:
10:10:07 AM:     - for: /*
      values:
        Access-Control-Allow-Origin: '*'
  headersOrigin: config
10:10:07 AM: Build failed due to a user error: Build script returned non-zero exit code: 2
10:10:07 AM: Failing build: Failed to build site
10:10:08 AM: Finished processing build request in 18.641s

Any suggestions on how to approach this?

Do you have a minimal reproduction we can try?

My understanding is that as soon as I import “GitHub - uber/h3-go: Go bindings for H3, a hierarchical hexagonal geospatial indexing system” build would fail.

This could be a simple function that does use h3-go but I can not properly test it if it actually works or builds.

package main

import (
  "encoding/json"
  "net/http"

  "github.com/aws/aws-lambda-go/events"
  "github.com/aws/aws-lambda-go/lambda"
  "github.com/uber/h3-go"
)

type VisitedH3 struct {
  H3Index     string       `json:"h3Index"`
  HexBoundary [][2]float64 `json:"hexBoundary"`
}

func handler(request events.APIGatewayProxyRequest) (*events.APIGatewayProxyResponse, error) {
  h3Index := "89391020913ffff"
  hexBoundary := h3.ToGeoBoundary(h3.FromString(h3Index))
  var boundary [][2]float64
  for _, b := range hexBoundary {
    boundary = append(boundary, [2]float64{b.Latitude, b.Longitude})
  }

  visitedH3 := VisitedH3{
    H3Index:     h3Index,
    HexBoundary: boundary,
  }

  body, err := json.Marshal(visitedH3)
  if err != nil {
    return &events.APIGatewayProxyResponse{
      StatusCode: http.StatusInternalServerError,
      Body:       "Failed to encode response",
    }, nil
  }

  return &events.APIGatewayProxyResponse{
    StatusCode: 200,
    Body:       string(body),
  }, nil
}

func main() {
  lambda.Start(handler)
}

I can reproduce the error. I believe the only way to solve this would be by pre-compiling the Go Function (for Linux) yourself and uploading that as a part of your repo so we can deploy it. With CGO_ENABLED Go needs gcc and those binaries don’t exist in Netlify’s Build Image. Usually, it’s possible to use apt to install it, but apt needs sudo and we don’t allow sudo for security reasons.