Top Level Namespace
Defined Under Namespace
Modules: CurlImpersonate
Instance Method Summary collapse
-
#configure_from_dir(dir) ⇒ Object
Resolve libcurl-impersonate location.
- #configure_from_pkg_config ⇒ Object
Instance Method Details
#configure_from_dir(dir) ⇒ Object
Resolve libcurl-impersonate location.
Priority:
1. ENV["CURL_IMPERSONATE_DIR"] — explicit override (CI)
2. ext/curl_impersonate/vendor/<arch>/ — bundled in precompiled gem
3. pkg-config --libs --cflags libcurl-impersonate — system install (brew/apt)
In all cases we end up statically linking libcurl-impersonate.a so that the resulting .bundle / .so has BoringSSL baked in and the end user does not need the library installed at runtime.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'ext/curl_impersonate/extconf.rb', line 32 def configure_from_dir(dir) raise "CURL_IMPERSONATE_DIR=#{dir} does not exist" unless File.directory?(dir) lib_dir = File.join(dir, "lib") include_dir = File.join(dir, "include") $LIBPATH.unshift(lib_dir) if File.directory?(lib_dir) $CFLAGS << " -I#{include_dir.shellescape}" if File.directory?(include_dir) $CFLAGS << " -I#{File.join(include_dir, "curl-impersonate").shellescape}" if File.directory?(File.join(include_dir, "curl-impersonate")) static_archive = File.join(lib_dir, "libcurl-impersonate.a") unless File.exist?(static_archive) raise "libcurl-impersonate.a not found under #{lib_dir}" end # Link the static archive directly so its symbols (including curl_easy_impersonate) # end up in our .bundle / .so. $LDFLAGS << " #{static_archive.shellescape}" # libcurl-impersonate.a bundles BoringSSL, nghttp{2,3}, ngtcp2, zstd, and # brotli statically — but its remaining external dependencies have to be # linked separately. The list differs by target platform; we use the # vendor directory name as a hint when one is available, otherwise fall # back to RUBY_PLATFORM. target = File.basename(dir) target = RUBY_PLATFORM if target.empty? || target == "vendor" case target when /darwin/ # Source: pkg-config --libs libcurl-impersonate on brew installation. $LDFLAGS << " -framework CoreFoundation -framework SystemConfiguration" $LDFLAGS << " -framework Security -framework LDAP" # ruby/setup-ruby on macos-14 builds a Ruby whose libruby has an absolute # install_name (e.g. /Users/runner/hostedtoolcache/Ruby/3.3.11/arm64/lib/ # libruby.3.3.dylib). Any extension we statically-link against that Ruby # inherits the absolute reference, breaking the precompiled gem on every # other machine. Tell the linker to leave Ruby symbols unresolved and let # the dynamic loader fill them in at require time — this is the standard # macOS pattern for portable Ruby extensions. $DLDFLAGS << " -Wl,-undefined,dynamic_lookup" $libs = "#{$libs} -lresolv -liconv -lz -lc++" when /linux/ # The lexiforest release tarball is a fully-static archive — zstd, brotli, # idn2, nghttp{2,3}, ngtcp2, BoringSSL, and a copy of curl itself are all # statically linked into libcurl-impersonate.a. The only external symbols # are the system C/C++ runtime, zlib (often satisfied by libz.so.1 which # ships on every distro), and a handful of pthread/dl/m intrinsics. $libs = "#{$libs} -lz -lpthread -ldl -lm -lstdc++" end end |
#configure_from_pkg_config ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'ext/curl_impersonate/extconf.rb', line 83 def configure_from_pkg_config unless pkg_config("libcurl-impersonate") raise "pkg-config could not locate libcurl-impersonate" end # pkg_config sets $LIBS to "-lcurl-impersonate -lz ...". We want the static .a # baked into the .bundle, so prepend the absolute path to the archive and strip # the dynamic -lcurl-impersonate flag. libdir = `pkg-config --variable=libdir libcurl-impersonate`.strip static_archive = File.join(libdir, "libcurl-impersonate.a") unless File.exist?(static_archive) raise "libcurl-impersonate.a not found at #{static_archive}" end $libs = $libs.to_s.gsub(/-lcurl-impersonate\b/, "").strip $LDFLAGS << " #{static_archive.shellescape}" end |