Class: Bundler::Spinel::ExtDetector
- Inherits:
-
Object
- Object
- Bundler::Spinel::ExtDetector
- Defined in:
- lib/bundler/spinel/ext_detector.rb
Overview
Auto-detect a gem’s Spinel C-extensions from the ‘ffi_cflags “@PLACEHOLDER@”` declarations already in its Ruby source — and emit a draft `spinel-ext.json`. This keeps the convention strictly consumer-side: a gem author doesn’t have to know about (or ship) ‘spinel-ext.json`; spinelgems infers what it needs from the existing `ffi_cflags` markers and any sibling `.c` files. The supplier can adopt the manifest natively later if they want — it’s a faster, more explicit path, not a precondition.
Matching heuristic: ‘@<PREFIX>_<NAME>_O@` → `.o` placeholder; look for a `*<name>*.c` near the declaring `.rb`. `@<PREFIX>_<NAME>_CFLAGS@` → a system-libs placeholder (no source); the maintainer or proxy still has to supply `pkg_config` and `disabled_cflags`, but the placeholder + name are detected. Whatever the detector can’t infer it leaves blank and warns —the output is a draft meant to be reviewed.
Constant Summary collapse
- FFI_CFLAGS =
Legacy form: ffi_cflags “@PLACEHOLDER@” → substitution at vendor time.
/ffi_cflags\s+["'](@[A-Z0-9_]+@)["']/.freeze
- FFI_CFLAGS_EXPAND =
Post-matz/spinel#1011 form: ffi_cflags File.expand_path(“name.o”, __dir__). Spinel const-folds the path from source position, so no substitution is needed — vendor just has to compile the .c and place the .o where the const-fold will look (next to the placed .rb).
/ffi_cflags\s+File\.expand_path\(\s*["']([^"']+\.o)["']\s*,\s*__dir__\s*\)/.freeze
Instance Method Summary collapse
-
#detect ⇒ Object
array of entries shaped like spinel-ext.json.
-
#initialize(dir, warn_io: $stderr) ⇒ ExtDetector
constructor
A new instance of ExtDetector.
- #to_json ⇒ Object
Constructor Details
#initialize(dir, warn_io: $stderr) ⇒ ExtDetector
Returns a new instance of ExtDetector.
28 29 30 31 |
# File 'lib/bundler/spinel/ext_detector.rb', line 28 def initialize(dir, warn_io: $stderr) @dir = File.(dir) @warn = warn_io end |
Instance Method Details
#detect ⇒ Object
array of entries shaped like spinel-ext.json. Legacy form (placeholder): dedup’d by placeholder; vendor substitutes. Const-fold form (post-#1011): dedup’d by source path; vendor compiles + places the .o, no substitution.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/bundler/spinel/ext_detector.rb', line 37 def detect decls = scan_declarations return [] if decls.empty? seen = {} decls.each_with_object([]) do |d, acc| key = d[:kind] == :placeholder ? d[:value] : :"src:#{c_for(d)}" next if seen[key] seen[key] = true entry = d[:kind] == :placeholder ? build_placeholder_entry(d) : (d) acc << entry if entry end end |
#to_json ⇒ Object
52 |
# File 'lib/bundler/spinel/ext_detector.rb', line 52 def to_json = JSON.pretty_generate(detect) |