From c71c83d01e1752e21993396445d2dbf30f8b68b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Hasi=C5=84ski?= Date: Mon, 16 Feb 2026 23:56:39 +0100 Subject: [PATCH] Hide Go runtime symbols to allow coexistence with other Charm gems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When multiple Charm gems (bubbletea, lipgloss, etc.) are loaded in the same Ruby process, each embeds its own Go runtime via c-archive static linking. Ruby loads .bundle files with RTLD_GLOBAL, causing ~1900 Go runtime symbols to clash in the global namespace, resulting in a segfault. Fix this by using -load_hidden (macOS) / --version-script (Linux) to make all Go runtime symbols local to the .bundle. Only Init_lipgloss is exported. The Go API symbols (lipgloss_*) remain accessible within the bundle since they're resolved at link time. Tested: bubbletea + lipgloss loaded together in Ruby 4.0 — no segfault. --- ext/lipgloss/extconf.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ext/lipgloss/extconf.rb b/ext/lipgloss/extconf.rb index 829c1a3..3c58069 100644 --- a/ext/lipgloss/extconf.rb +++ b/ext/lipgloss/extconf.rb @@ -42,16 +42,20 @@ def detect_platform ERROR end +go_lib_path = File.join(go_lib_dir, "liblipgloss.a") + $LDFLAGS << " -L#{go_lib_dir}" $INCFLAGS << " -I#{go_lib_dir}" -$LOCAL_LIBS << " #{go_lib_dir}/liblipgloss.a" - case RbConfig::CONFIG["host_os"] when /darwin/ + $LDFLAGS << " -Wl,-load_hidden,#{go_lib_path}" + $LDFLAGS << " -Wl,-exported_symbol,_Init_lipgloss" $LDFLAGS << " -framework CoreFoundation -framework Security -framework SystemConfiguration" $LDFLAGS << " -lresolv" when /linux/ + $LOCAL_LIBS << " #{go_lib_path}" + $LDFLAGS << " -Wl,--exclude-libs,ALL" $LDFLAGS << " -lpthread -lm -ldl" $LDFLAGS << " -lresolv" if find_library("resolv", "res_query") end