Add precompiled binary gem support and modernize build system#2
Add precompiled binary gem support and modernize build system#2wesleyjellis wants to merge 6 commits into
Conversation
- Build a static, self-contained extension: vendor OpsLevel's jq fork
(env/$ENV always return {}) plus Onigmo 6.2.0 for regex support,
compiled with --disable-shared --enable-static --with-pic
- Move the binary to lib/jq/jq_core.so and load a per-Ruby-minor
precompiled binary when present, falling back to the source build
- Add .github/workflows/cibuildgem.yaml to compile, test, verify, and
release fat platform gems (x86_64-linux, arm64-darwin) for Ruby
3.3/3.4/4.0 via Shopify's cibuildgem
- Declare required_ruby_version >= 3.3; drop mini_portile2 from
platform gems
- Add specs guarding regex support and the fork's empty env behavior
- Bump version to 0.3.0; update README; remove stale .travis.yml
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PpxfE1fTm5fFQYBqWTzg4y
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
libruby exports its own onig_* functions and ELF's flat namespace lets calls bind across copies of Onigmo; today both are 6.2.0 so it works by coincidence, but a version skew would cause crashes. Keep the vendored jq/Onigmo symbols local to the extension. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
wesleyjellis
left a comment
There was a problem hiding this comment.
https://github.com/flavorjones/mini_portile mentions that "gem "mini_portile2", "~> 2.0.0" # NECESSARY if used in extconf.rb. see below." which seems missing
| recipe = MiniPortile.new('jq', '1.6') | ||
| recipe.files = ['https://github.com/stedolan/jq/archive/jq-1.6.tar.gz'] | ||
| onigmo = MiniPortile.new('onigmo', '6.2.0') | ||
| onigmo.files = ['https://github.com/k-takata/Onigmo/releases/download/Onigmo-6.2.0/onigmo-6.2.0.tar.gz'] |
There was a problem hiding this comment.
We should add the expected sha256
| require 'mkmf' | ||
|
|
||
| def using_system_libraries? | ||
| arg_config('--use-system-libraries', ENV.key?('RUBYJQ_USE_SYSTEM_LIBRARIES')) |
There was a problem hiding this comment.
we set this in Opslevel, might have to remove it
| begin | ||
| # Load the precompiled binary matching the current Ruby, if this is a | ||
| # platform-specific gem packaged by cibuildgem. | ||
| require "jq/#{RUBY_VERSION[/\d+\.\d+/]}/jq_core" |
There was a problem hiding this comment.
I don't understand how this magic works
There was a problem hiding this comment.
but it is the suggested path here: https://github.com/Shopify/cibuildgem/wiki/1.-Setup-cibuildgem-on-your-project#prepare-your-gem-to-load-the-right-binary
There was a problem hiding this comment.
Ok, so the cibuildgem has to actually make a gem with the ruby version in it (eg: require "jq/3.3/jq.core") since the gem's compiled code references a specific ruby version.
There's also a change here from jq_core as the output of the compiled library via ext.lib_dir = 'lib/jq' change below. Apparently it's common and it should Just Work
|
|
||
| # OpsLevel fork of jq: `env`/`$ENV` always return an empty object. | ||
| recipe = MiniPortile.new('jq', '1.6.opslevel') | ||
| recipe.files = ['https://github.com/OpsLevel/jq/archive/845f4206dd8a82355325bafffbb54a5155cf67ec.tar.gz'] |
…le2 version 2, and tighten dependency to avoid version 3
| '--disable-maintainer-mode' | ||
| '--disable-maintainer-mode', | ||
| '--disable-docs', | ||
| '--disable-shared', |
There was a problem hiding this comment.
why the switch from --enabled-shared to disabled?
| # extension's dynamic symbol table: libruby exports its own onig_* functions, | ||
| # and the flat ELF namespace would let calls bind across copies. (Mach-O uses | ||
| # two-level namespaces, and its linker lacks this flag.) | ||
| $LDFLAGS << ' -Wl,--exclude-libs,ALL' unless RUBY_PLATFORM.include?('darwin') # rubocop:disable Style/GlobalVars |
There was a problem hiding this comment.
What does -Wl actually do?
Summary
This PR modernizes the ruby-jq gem's build and release infrastructure by adding support for precompiled platform-specific binaries, updating to use OpsLevel's jq fork, and migrating from Travis CI to GitHub Actions with cibuildgem.
Key Changes
.github/workflows/cibuildgem.yaml) to build and release platform-specific gems forx86_64-linuxandarm64-darwinacross multiple Ruby versions (3.3, 3.4, 4.0)env/$ENValways return an empty objectRakefileto output compiled extensions tolib/jq/and excludemini_portile2from platform gem dependencieslib/jq.rbto load precompiled binaries matching the Ruby version, with fallback to source-compiled extensionextconf.rbto compile both Onigmo and jq statically with proper configuration options.travis.ymlin favor of GitHub Actions workflowREADME.mdto document precompiled binary availability and build requirementsMetrics/LineLengthtoLayout/LineLength)Notable Implementation Details
jq/3.3/jq_core) with graceful fallbackenvbehaviorhttps://claude.ai/code/session_01PpxfE1fTm5fFQYBqWTzg4y