I tried to build a CLI using bubbletea/huh in macOS.
It spits out errors when using -x flag:
../../go/pkg/mod/golang.org/x/sys@v0.43.0/unix/zsyscall_darwin_arm64.go:275: linker could not find symbol _golang.org/x/sys/unix.syscall_syscall6
../../go/pkg/mod/golang.org/x/sys@v0.43.0/unix/zsyscall_darwin_arm64.go:734: linker could not find symbol _golang.org/x/sys/unix.syscall_syscall
../../go/pkg/mod/golang.org/x/sys@v0.43.0/unix/zsyscall_darwin_arm64.go:1080: linker could not find symbol _golang.org/x/sys/unix.syscall_syscall
../../go/pkg/mod/golang.org/x/sys@v0.43.0/unix/zsyscall_darwin_arm64.go:1915: linker could not find symbol _golang.org/x/sys/unix.syscall_syscall
../../go/pkg/mod/golang.org/
When I try to cross-compile for windows:
$ GOOS=windows tinygo build
open /opt/homebrew/Cellar/tinygo/0.41.1/lib/mingw-w64/mingw-w64-headers/crt/_mingw.h.in: no such file or directory
When I try to cross-compile for linux:
$ GOOS=linux tinygo build
Reserved registers on the clobber list may not be preserved across the asm statement, and clobbering them may lead to undefined behaviour.
$ tinygo version
tinygo version 0.41.1 darwin/arm64 (using go version go1.26.1 and LLVM version 20.1.1)
module x
go 1.26.1
require (
charm.land/huh/v2 v2.0.3
charm.land/lipgloss/v2 v2.0.3
github.com/charmbracelet/x/exp/strings v0.1.0
)
require (
charm.land/bubbles/v2 v2.0.0 // indirect
charm.land/bubbletea/v2 v2.0.2 // indirect
github.com/atotto/clipboard v0.1.4 // indirect
github.com/catppuccin/go v0.2.0 // indirect
github.com/charmbracelet/colorprofile v0.4.3 // indirect
github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 // indirect
github.com/charmbracelet/x/ansi v0.11.7 // indirect
github.com/charmbracelet/x/exp/ordered v0.1.0 // indirect
github.com/charmbracelet/x/term v0.2.2 // indirect
github.com/charmbracelet/x/termios v0.1.1 // indirect
github.com/charmbracelet/x/windows v0.2.2 // indirect
github.com/clipperhouse/displaywidth v0.11.0 // indirect
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/lucasb-eyer/go-colorful v1.4.0 // indirect
github.com/mattn/go-runewidth v0.0.23 // indirect
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.43.0 // indirect
)
package main
import (
"errors"
"fmt"
"os"
"strconv"
"strings"
"time"
"charm.land/huh/v2"
"charm.land/huh/v2/spinner"
"charm.land/lipgloss/v2"
xstrings "github.com/charmbracelet/x/exp/strings"
)
type Spice int
const (
Mild Spice = iota + 1
Medium
Hot
)
func (s Spice) String() string {
switch s {
case Mild:
return "Mild "
case Medium:
return "Medium-Spicy "
case Hot:
return "Spicy-Hot "
default:
return ""
}
}
type Order struct {
Burger Burger
Side string
Name string
Instructions string
Discount bool
}
type Burger struct {
Type string
Toppings []string
Spice Spice
}
func main() {
var burger Burger
order := Order{Burger: burger}
// Should we run in accessible mode?
accessible, _ := strconv.ParseBool(os.Getenv("ACCESSIBLE"))
form := huh.NewForm(
huh.NewGroup(huh.NewNote().
Title("Charmburger").
Description("Welcome to _Charmburger™_.\n\nHow may we take your order?").
Next(true).
NextLabel("Next"),
),
// Choose a burger.
// We'll need to know what topping to add too.
huh.NewGroup(
huh.NewSelect[string]().
Options(huh.NewOptions("Charmburger Classic", "Chickwich", "Fishburger", "Charmpossible™ Burger")...).
Title("Choose your burger").
Description("At Charm we truly have a burger for everyone.").
Validate(func(t string) error {
if t == "Fishburger" {
return fmt.Errorf("no fish today, sorry")
}
return nil
}).
Value(&order.Burger.Type),
huh.NewMultiSelect[string]().
Title("Toppings").
Description("Choose up to 4.").
Options(
huh.NewOption("Lettuce", "Lettuce").Selected(true),
huh.NewOption("Tomatoes", "Tomatoes").Selected(true),
huh.NewOption("Charm Sauce", "Charm Sauce"),
huh.NewOption("Jalapeños", "Jalapeños"),
huh.NewOption("Cheese", "Cheese"),
huh.NewOption("Vegan Cheese", "Vegan Cheese"),
huh.NewOption("Nutella", "Nutella"),
).
Validate(func(t []string) error {
if len(t) <= 0 {
return fmt.Errorf("at least one topping is required")
}
return nil
}).
Value(&order.Burger.Toppings).
Filterable(true).
Limit(4),
),
// Prompt for toppings and special instructions.
// The customer can ask for up to 4 toppings.
huh.NewGroup(
huh.NewSelect[Spice]().
Title("Spice level").
Options(
huh.NewOption("Mild", Mild).Selected(true),
huh.NewOption("Medium", Medium),
huh.NewOption("Hot", Hot),
).
Value(&order.Burger.Spice),
huh.NewSelect[string]().
Options(huh.NewOptions("Fries", "Disco Fries", "R&B Fries", "Carrots")...).
Value(&order.Side).
Title("Sides").
Description("You get one free side with this order."),
),
// Gather final details for the order.
huh.NewGroup(
huh.NewInput().
Value(&order.Name).
Title("What's your name?").
Placeholder("Margaret Thatcher").
Validate(func(s string) error {
if s == "Frank" {
return errors.New("no franks, sorry")
}
return nil
}).
Description("For when your order is ready."),
huh.NewText().
Value(&order.Instructions).
Placeholder("Just put it in the mailbox please").
Title("Special Instructions").
Description("Anything we should know?").
CharLimit(400).
Lines(5),
huh.NewConfirm().
Title("Would you like 15% off?").
Value(&order.Discount).
Affirmative("Yes!").
Negative("No."),
),
).WithAccessible(accessible)
err := form.Run()
if err != nil {
fmt.Println("Uh oh:", err)
os.Exit(1)
}
prepareBurger := func() {
time.Sleep(2 * time.Second)
}
_ = spinner.New().Title("Preparing your burger...").WithAccessible(accessible).Action(prepareBurger).Run()
// Print order summary.
{
var sb strings.Builder
keyword := func(s string) string {
return lipgloss.NewStyle().Foreground(lipgloss.Color("212")).Render(s)
}
fmt.Fprintf(&sb,
"%s\n\nOne %s%s, topped with %s with %s on the side.",
lipgloss.NewStyle().Bold(true).Render("BURGER RECEIPT"),
keyword(order.Burger.Spice.String()),
keyword(order.Burger.Type),
keyword(xstrings.EnglishJoin(order.Burger.Toppings, true)),
keyword(order.Side),
)
name := order.Name
if name != "" {
name = ", " + name
}
fmt.Fprintf(&sb, "\n\nThanks for your order%s!", name)
if order.Discount {
fmt.Fprint(&sb, "\n\nEnjoy 15% off.")
}
fmt.Println(
lipgloss.NewStyle().
Width(40).
BorderStyle(lipgloss.RoundedBorder()).
BorderForeground(lipgloss.Color("63")).
Padding(1, 2).
Render(sb.String()),
)
}
}
I tried to build a CLI using bubbletea/huh in macOS.
It spits out errors when using
-xflag:When I try to cross-compile for windows:
When I try to cross-compile for linux: