From ca50a547be47603eb6ef9c566714bd5b60329de2 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 29 Apr 2026 08:03:49 -0700 Subject: [PATCH] ext: hide statically-linked symbols to prevent llhttp collision libgit2 >= 1.8 bundles llhttp as its default HTTP parser. Without visibility controls, all 119 llhttp_* symbols are exported from rugged.so and collide with the llhttp-ffi gem (used by the http gem) when both are loaded in the same process. Fix by: - Passing -DCMAKE_C_VISIBILITY_PRESET=hidden to cmake so libgit2 and its bundled deps (including llhttp) are compiled with -fvisibility=hidden on all platforms. - Appending -Wl,--exclude-libs,ALL to $LDFLAGS on Linux as a belt-and-suspenders linker-level guard (macOS ld does not support this flag, but the cmake flag covers it there). Co-Authored-By: Claude Sonnet 4.6 --- ext/rugged/extconf.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ext/rugged/extconf.rb b/ext/rugged/extconf.rb index 738098201..02ca57055 100644 --- a/ext/rugged/extconf.rb +++ b/ext/rugged/extconf.rb @@ -110,7 +110,7 @@ def self.run_cmake(timeout, args) Dir.chdir("build") do # On Windows, Ruby-DevKit is MSYS-based, so ensure to use MSYS Makefiles. generator = "-G \"MSYS Makefiles\"" if Gem.win_platform? - run_cmake(5 * 60, ".. -DBUILD_TESTS=OFF -DUSE_THREADS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS=-fPIC -DCMAKE_BUILD_TYPE=RelWithDebInfo #{cmake_flags.join(' ')} #{generator}") + run_cmake(5 * 60, ".. -DBUILD_TESTS=OFF -DUSE_THREADS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS=-fPIC -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_VISIBILITY_PRESET=hidden #{cmake_flags.join(' ')} #{generator}") sys(MAKE) # "normal" libraries (and libgit2 builds) get all these when they build but we're doing it @@ -122,6 +122,10 @@ def self.run_cmake(timeout, args) else pcfile = File.join(LIBGIT2_DIR, "build", "libgit2.pc") $LDFLAGS << " " + `pkg-config --libs --static #{pcfile}`.strip + # Prevent statically-linked symbols (e.g. llhttp) from being exported + # into rugged.so, where they would collide with other gems bundling the + # same library (e.g. llhttp-ffi used by the http gem). + $LDFLAGS << " -Wl,--exclude-libs,ALL" if RbConfig::CONFIG['target_os'] =~ /linux/ end end end