leptris 1.9.361.0-ppc64le-linux → 1.9.362.1-ppc64le-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.adoc +21 -0
- data/Rakefile +50 -24
- data/ext/build_native_per_minor.rb +81 -0
- data/ext/build_windows_native.rb +6 -3
- data/ext/check_bundle_linkage.rb +61 -0
- data/ext/leptris/native/extconf.rb +41 -13
- data/ext/leptris/native/native.c +72 -28
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/builder.rb +1 -1
- data/lib/leptris/xml/document.rb +42 -4
- data/lib/leptris/xml/element.rb +36 -5
- data/lib/leptris/xml/ffi.rb +15 -0
- data/lib/leptris/xml/native.so +0 -0
- data/lib/leptris/xml/native_3_3.so +0 -0
- data/lib/leptris/xml/native_layer.rb +21 -5
- data/lib/leptris/xml/searchable.rb +10 -3
- data/lib/leptris/xml.rb +3 -1
- data/lib/libleptris.so +0 -0
- data/vendor-src/README.md +1 -1
- data/vendor-src/libleptris/CHANGELOG.md +41 -0
- data/vendor-src/libleptris/CMakeLists.txt +1 -1
- data/vendor-src/libleptris/src/leptris/xinclude/xinclude.c +37 -0
- data/vendor-src/libleptris/src/leptris/xsd/compile.c +81 -8
- data/vendor-src/libleptris/src/leptris/xsd/content_model.c +5 -1
- data/vendor-src/libleptris/src/leptris/xsd/validate.c +10 -2
- data/vendor-src/libleptris/src/leptris/xsd/xsd_internal.h +7 -0
- data/vendor-src/libleptris/test/CMakeLists.txt +1 -0
- data/vendor-src/libleptris/test/xinclude/test_xinclude_fallback_elem.cpp +81 -0
- data/vendor-src/libleptris/test/xpath/test_xpath.cpp +68 -0
- data/vendor-src/libleptris/test/xsd/test_xsd_compile.cpp +193 -0
- data/vendor-src/libleptris/vcpkg.json +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9780542c27af094df56b7dbf848569f0006fcb73c60b941430dd04324e5ec49e
|
|
4
|
+
data.tar.gz: 23fb2d1e896b432b6b19719bd5f4c7ba2684c527029abc41eb8b1795f3079bfc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '034691190cf53120d6ac25a1508baf4884cabbcbfb610eaecd4d77e8df8030f603f144a70c9cc646dc0584280de9f3baeb96e6a81325ec0a70e6103fb9f25198'
|
|
7
|
+
data.tar.gz: 2fc3de4b4ace30d69581f8025737b2f3208a759b7d5218af3e311e4490cc0721aece5cc106e24c403a51860aeb264ea4f345054f42f6ec33f993e80a014fbf05
|
data/README.adoc
CHANGED
|
@@ -17,6 +17,27 @@ The C DOM is the single source of truth — Ruby objects are thin FFI
|
|
|
17
17
|
handles over the C pointers, so every Ruby method maps to one FFI call.
|
|
18
18
|
No tree hydration, no parallel Ruby-side model.
|
|
19
19
|
|
|
20
|
+
== Versioning: {engine-semver}.{binding-patch}
|
|
21
|
+
|
|
22
|
+
Gem versions are **`{libleptris-semver}.{binding-patch}`** — the lockstep
|
|
23
|
+
scheme. The first three components name the EXACT libleptris engine
|
|
24
|
+
release the gem vendors; the fourth is the binding's own patch number
|
|
25
|
+
for that engine.
|
|
26
|
+
|
|
27
|
+
* engine `v1.9.361` + first binding release → `1.9.361.0`
|
|
28
|
+
* binding-only fix on the same engine → `1.9.361.1`
|
|
29
|
+
* engine `v1.9.362` ride → `1.9.362.0`
|
|
30
|
+
|
|
31
|
+
The triple is a contract: `~> 1.9.361` pins both the engine behavior
|
|
32
|
+
and the binding surface. **Never** publish a version whose first three
|
|
33
|
+
components are not an existing engine release, never let the binding
|
|
34
|
+
line run ahead of the engine line, and every engine release must get
|
|
35
|
+
its binding ride (`.0`, or `.1` when the ride itself carries binding
|
|
36
|
+
fixes). Releases go through the release workflow with an explicit
|
|
37
|
+
`next_version` — the workflow owns the bump; version numbers are
|
|
38
|
+
computed from the engine tag being ridden, never from
|
|
39
|
+
"previous gem + 1".
|
|
40
|
+
|
|
20
41
|
== Installation
|
|
21
42
|
|
|
22
43
|
Add to your Gemfile:
|
data/Rakefile
CHANGED
|
@@ -8,7 +8,7 @@ RSpec::Core::RakeTask.new(:spec)
|
|
|
8
8
|
# Pin for `rake compile` and the platform-gem builds. Keep in lockstep
|
|
9
9
|
# with .github/workflows/build.yml (which calls `rake compile`) and the
|
|
10
10
|
# CHANGELOG when libleptris releases.
|
|
11
|
-
LIBLEPTRIS_VERSION = "1.9.
|
|
11
|
+
LIBLEPTRIS_VERSION = "1.9.362"
|
|
12
12
|
# Vendored alongside libleptris for fn:normalize-unicode (TODO
|
|
13
13
|
# .restructure/20): built per platform with a RELOCATABLE @rpath
|
|
14
14
|
# install name, loaded by ffi.rb before libleptris so the
|
|
@@ -292,13 +292,14 @@ task :compile do
|
|
|
292
292
|
Dir.chdir(ext_dir) do
|
|
293
293
|
sh "ruby extconf.rb"
|
|
294
294
|
if RUBY_PLATFORM =~ /darwin/
|
|
295
|
-
# Link the bundle ourselves:
|
|
296
|
-
#
|
|
297
|
-
#
|
|
298
|
-
#
|
|
299
|
-
#
|
|
300
|
-
#
|
|
301
|
-
# interpreter) and a
|
|
295
|
+
# Link the bundle ourselves: mkmf snapshots LIBRUBYARG from
|
|
296
|
+
# RbConfig at require time, so setup-ruby's shared-libruby
|
|
297
|
+
# rubies record their absolute hostedtoolcache path in the
|
|
298
|
+
# bundle (shipped broken through 1.9.36x, #1739) and no
|
|
299
|
+
# post-require clearing can stop it. Compile via the
|
|
300
|
+
# Makefile, link with pure -undefined dynamic_lookup (Ruby
|
|
301
|
+
# symbols resolve from the loading interpreter) and a
|
|
302
|
+
# conservative deployment target.
|
|
302
303
|
sh "make native.o"
|
|
303
304
|
sh "cc -dynamic -bundle -undefined dynamic_lookup " \
|
|
304
305
|
"-mmacosx-version-min=#{ENV['MACOSX_DEPLOYMENT_TARGET'] || '11.0'} " \
|
|
@@ -312,10 +313,11 @@ task :compile do
|
|
|
312
313
|
# their symbols via -rdynamic, like any extension .so).
|
|
313
314
|
sh "make native.o"
|
|
314
315
|
sh "#{RbConfig::CONFIG['CC']} -shared -fPIC -o native.so native.o"
|
|
315
|
-
# Guard the contract in the build log.
|
|
316
|
-
sh "if strings native.so | grep -q libruby; then " \
|
|
317
|
-
"echo 'ERROR: native.so links libruby (#207)'; exit 1; fi"
|
|
318
316
|
end
|
|
317
|
+
# Guard the linkage contract at the build chokepoint (#1739):
|
|
318
|
+
# no libruby reference, allowlisted load commands on darwin.
|
|
319
|
+
sh "#{RbConfig.ruby} ../../check_bundle_linkage.rb " \
|
|
320
|
+
"#{RUBY_PLATFORM =~ /darwin/ ? 'native.bundle' : 'native.so'}"
|
|
319
321
|
end
|
|
320
322
|
bundle = Dir.glob("#{ext_dir}/native.{bundle,so,dll}").first
|
|
321
323
|
if bundle.nil?
|
|
@@ -337,6 +339,18 @@ task :compile do
|
|
|
337
339
|
cp(bundle, "#{dest}.new")
|
|
338
340
|
mv("#{dest}.new", dest)
|
|
339
341
|
sign_darwin_binaries(dest)
|
|
342
|
+
# Per-minor twin (ruby#476): the loader prefers
|
|
343
|
+
# native_<minor>.{bundle,so}; dev builds run same-minor, so
|
|
344
|
+
# the copy is byte-identical and keeps `rake compile` +
|
|
345
|
+
# `rake spec` working without a full release matrix.
|
|
346
|
+
unless Gem.win_platform?
|
|
347
|
+
minor = RUBY_VERSION[/\A\d+\.\d+/].tr('.', '_')
|
|
348
|
+
ext = RUBY_PLATFORM.include?('darwin') ? '.bundle' : '.so'
|
|
349
|
+
twin = "lib/leptris/xml/native_#{minor}#{ext}"
|
|
350
|
+
cp(dest, "#{twin}.new")
|
|
351
|
+
mv("#{twin}.new", twin)
|
|
352
|
+
sign_darwin_binaries(twin)
|
|
353
|
+
end
|
|
340
354
|
puts "Vendored native layer (#{File.basename(bundle)}) into lib/leptris/xml/"
|
|
341
355
|
end
|
|
342
356
|
end
|
|
@@ -412,11 +426,19 @@ namespace :audit do
|
|
|
412
426
|
# leptris_version() equals the gem's engine pin (a half-bumped
|
|
413
427
|
# lockstep state can no longer package). Negative proof lives
|
|
414
428
|
# in spec/audit_codesign_spec.rb.
|
|
415
|
-
desc "Fail on unsigned/tampered macOS artifacts
|
|
429
|
+
desc "Fail on unsigned/tampered macOS artifacts, engine-version drift, or libruby-linked native layers"
|
|
416
430
|
task :artifacts do
|
|
431
|
+
# Linkage contract over EVERY shipped native layer, per-minor
|
|
432
|
+
# twins included (#1739) — every platform: the 1.9.36x trains
|
|
433
|
+
# packaged runner-absolute libruby loads in native_3_2/3_4
|
|
434
|
+
# artifacts that audit:symbols/audit:artifacts never opened.
|
|
435
|
+
bundles = Dir.glob("lib/leptris/xml/native*.{bundle,so}")
|
|
436
|
+
bundles.each do |b|
|
|
437
|
+
sh "#{RbConfig.ruby} ext/check_bundle_linkage.rb #{b}"
|
|
438
|
+
end
|
|
417
439
|
unless RUBY_PLATFORM =~ /darwin/
|
|
418
|
-
puts "audit:artifacts:
|
|
419
|
-
"
|
|
440
|
+
puts "audit:artifacts: #{bundles.size} native layers linkage-clean; " \
|
|
441
|
+
"codesign gates skip off-darwin"
|
|
420
442
|
next
|
|
421
443
|
end
|
|
422
444
|
abort "audit:artifacts: codesign unavailable" \
|
|
@@ -439,8 +461,8 @@ namespace :audit do
|
|
|
439
461
|
abort "audit:artifacts: engine-version drift — vendored " \
|
|
440
462
|
"#{vendored.inspect} != pin #{pinned.inspect}"
|
|
441
463
|
end
|
|
442
|
-
puts "audit:artifacts: #{libs.size} macOS artifacts
|
|
443
|
-
"strictly and engine-synced (#{pinned})"
|
|
464
|
+
puts "audit:artifacts: #{libs.size} macOS artifacts + #{bundles.size} native " \
|
|
465
|
+
"layers verify strictly, linkage-clean and engine-synced (#{pinned})"
|
|
444
466
|
end
|
|
445
467
|
|
|
446
468
|
# Packaging doctrine (#271): every BUILT gem carries the engine
|
|
@@ -563,14 +585,18 @@ platforms.each do |platform|
|
|
|
563
585
|
spec.files += Dir.glob("vendor-src/**/*")
|
|
564
586
|
spec.files += %w[ext/leptris/native/extconf.rb
|
|
565
587
|
ext/leptris/native/native.c]
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
588
|
+
# #207/#227 + ruby#476: per-Ruby-minor bundles on EVERY
|
|
589
|
+
# platform (the ext's compiled-in RString layout changed in
|
|
590
|
+
# 3.2 — one CI-built bundle segfaults 3.1). DOT-FREE names —
|
|
591
|
+
# MRI derives the init symbol from the basename cut at the
|
|
592
|
+
# first dot (native_3_3.so -> Init_native_3_3; the dotted form
|
|
593
|
+
# made Ruby look for "Init_native-3", which cannot exist).
|
|
594
|
+
spec.files += Dir.glob("lib/leptris/xml/native_*.so")
|
|
595
|
+
spec.files += Dir.glob("lib/leptris/xml/native_*.bundle")
|
|
596
|
+
if !platform.include?("mingw")
|
|
597
|
+
# The unversioned bundle rides for toolchains that only run
|
|
598
|
+
# rake compile's single build (native_layer prefers the
|
|
599
|
+
# per-minor variant and never loads a wrong-ABI file).
|
|
574
600
|
spec.files += Dir.glob("lib/leptris/xml/native.{bundle,so,dll}")
|
|
575
601
|
end
|
|
576
602
|
task = Gem::PackageTask.new(spec)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Builds the native read layer bundle for the CURRENT Ruby and
|
|
4
|
+
# installs it under its minor-versioned name
|
|
5
|
+
# (lib/leptris/xml/native_<major>_<minor>.bundle on darwin, .so on
|
|
6
|
+
# Linux).
|
|
7
|
+
#
|
|
8
|
+
# ruby#476: the ext's compiled-in RString layout changed in Ruby
|
|
9
|
+
# 3.2 — a bundle built by a newer minor reads garbage pointers and
|
|
10
|
+
# lengths under 3.1 (the parse segfaulted inside the engine's
|
|
11
|
+
# correctly-bounded NEON text counter). One bundle per supported
|
|
12
|
+
# minor therefore ships in the darwin/Linux platform gems — the
|
|
13
|
+
# same contract the Windows gems have had since #207/#227 — and
|
|
14
|
+
# native_layer picks by RUBY_VERSION at require, falling back to
|
|
15
|
+
# the FFI surface when the variant for the running minor is
|
|
16
|
+
# absent. A WRONG-ABI load is never attempted.
|
|
17
|
+
#
|
|
18
|
+
# The name is DOT-FREE: MRI derives a C extension's init symbol
|
|
19
|
+
# from the require feature's basename cut at the first dot, so
|
|
20
|
+
# native_3_1.bundle resolves Init_native_3_1 (exported by
|
|
21
|
+
# native.c).
|
|
22
|
+
|
|
23
|
+
require "rbconfig"
|
|
24
|
+
require "fileutils"
|
|
25
|
+
|
|
26
|
+
root = File.expand_path("..", __dir__)
|
|
27
|
+
ext_dir = File.join(root, "ext", "leptris", "native")
|
|
28
|
+
minor = RUBY_VERSION[/\A\d+\.\d+/]
|
|
29
|
+
minor_us = minor.tr(".", "_")
|
|
30
|
+
ext = RUBY_PLATFORM.include?("darwin") ? ".bundle" : ".so"
|
|
31
|
+
|
|
32
|
+
Dir.chdir(ext_dir) do
|
|
33
|
+
# Force a clean compile on every invocation (stale objects from
|
|
34
|
+
# a failed earlier attempt ship silent wrong-ABI builds).
|
|
35
|
+
FileUtils.rm_f(Dir.glob("#{ext_dir}/native.{o,so,bundle}"))
|
|
36
|
+
system(RbConfig.ruby, "extconf.rb") or abort "extconf failed under #{RUBY_VERSION}"
|
|
37
|
+
# Link WITHOUT libruby (#1739): mkmf's Makefile rule records the
|
|
38
|
+
# building ruby's libruby — for setup-ruby builds by absolute
|
|
39
|
+
# hostedtoolcache path — in every LC_LOAD_DYLIB / DT_NEEDED, which
|
|
40
|
+
# dlopen-fails on any other machine. Compile via the Makefile,
|
|
41
|
+
# link exactly like rake compile's native branch: pure
|
|
42
|
+
# dynamic_lookup, rb_* resolve from the loading interpreter.
|
|
43
|
+
system("make native.o") or abort "make native.o failed under #{RUBY_VERSION}"
|
|
44
|
+
cc = RbConfig::CONFIG["CC"]
|
|
45
|
+
link =
|
|
46
|
+
if ext == ".bundle"
|
|
47
|
+
"#{cc} -dynamic -bundle -undefined dynamic_lookup " \
|
|
48
|
+
"-mmacosx-version-min=#{ENV['MACOSX_DEPLOYMENT_TARGET'] || '11.0'} " \
|
|
49
|
+
"-o native.bundle native.o"
|
|
50
|
+
else
|
|
51
|
+
"#{cc} -shared -fPIC -o native.so native.o"
|
|
52
|
+
end
|
|
53
|
+
system(link) or abort "native link failed under #{RUBY_VERSION}: #{link}"
|
|
54
|
+
built = Dir.glob("native.{so,bundle}").first
|
|
55
|
+
abort "native bundle not produced under #{RUBY_VERSION}" unless built
|
|
56
|
+
|
|
57
|
+
# Linkage gate: no libruby reference, and (darwin) only
|
|
58
|
+
# allowlisted load commands — enforced HERE so a violated bundle
|
|
59
|
+
# never reaches packaging (the 1.9.36x trains shipped exactly
|
|
60
|
+
# this shape, #1739).
|
|
61
|
+
system(RbConfig.ruby, File.join(root, "ext", "check_bundle_linkage.rb"),
|
|
62
|
+
File.expand_path(built)) or
|
|
63
|
+
abort "linkage gate failed under #{RUBY_VERSION}"
|
|
64
|
+
|
|
65
|
+
# Functional gate: dlopen the built bundle and resolve the
|
|
66
|
+
# MINOR-SUFFIXED init symbol — only a real lookup proves
|
|
67
|
+
# require "leptris/xml/native_<minor>" will resolve.
|
|
68
|
+
begin
|
|
69
|
+
require "fiddle"
|
|
70
|
+
Fiddle.dlopen(File.expand_path(built))["Init_native_#{minor_us}"]
|
|
71
|
+
rescue LoadError => e
|
|
72
|
+
warn "fiddle unavailable under #{RUBY_VERSION} (#{e.message}) — skipping"
|
|
73
|
+
rescue Fiddle::DLError => e
|
|
74
|
+
abort "#{built} does not export Init_native_#{minor_us} — refusing to " \
|
|
75
|
+
"install a bundle that would fail at require (#{e.message})"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
dest = File.join(root, "lib", "leptris", "xml", "native_#{minor_us}#{ext}")
|
|
79
|
+
FileUtils.cp(built, dest)
|
|
80
|
+
puts "Installed native layer for Ruby #{minor} -> #{dest}"
|
|
81
|
+
end
|
data/ext/build_windows_native.rb
CHANGED
|
@@ -29,14 +29,17 @@ Dir.chdir(ext_dir) do
|
|
|
29
29
|
# because make reused a stale native.obj from a failed earlier
|
|
30
30
|
# attempt (the log shows "creating Makefile -> linking" with no
|
|
31
31
|
# compile). Force a clean compile on every invocation.
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
# The globs cover both spellings of the mkmf target: the
|
|
33
|
+
# unversioned name and the per-minor name extconf now creates
|
|
34
|
+
# the Makefile for (#476 source-install parity).
|
|
35
|
+
FileUtils.rm_f(Dir.glob("#{ext_dir}/native*.{o,obj,so,dll}"))
|
|
36
|
+
FileUtils.rm_f(Dir.glob("#{ext_dir}/leptris/xml/native*.so"))
|
|
34
37
|
system(RbConfig.ruby, "extconf.rb") or abort "extconf failed under #{RUBY_VERSION}"
|
|
35
38
|
# mkmf's link binds the CURRENT Ruby's runtime DLL — exactly
|
|
36
39
|
# what the versioned naming is for.
|
|
37
40
|
success = system("make")
|
|
38
41
|
abort "make failed under #{RUBY_VERSION}" unless success
|
|
39
|
-
so = Dir.glob("native
|
|
42
|
+
so = Dir.glob("native*.so").first
|
|
40
43
|
abort "native bundle not produced under #{RUBY_VERSION}" unless so
|
|
41
44
|
# Functional export gate: dlopen the built DLL and resolve the
|
|
42
45
|
# MINOR-SUFFIXED init symbol. A PE DLL can carry the symbol in its
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Linkage contract for shipped native layers (#1739 / ruby#481): a
|
|
4
|
+
# Ruby extension resolves rb_* symbols from the LOADING interpreter,
|
|
5
|
+
# so the artifact must never link libruby — mkmf records the
|
|
6
|
+
# building ruby's absolute path (setup-ruby's hostedtoolcache
|
|
7
|
+
# location), which dlopen-fails on every other machine and silently
|
|
8
|
+
# degrades the whole install to FFI. On darwin the check is
|
|
9
|
+
# stricter: every load command must stay inside the loader
|
|
10
|
+
# allowlist. Windows PE DLLs are exempt — binding the build
|
|
11
|
+
# runtime is the documented contract there (#227).
|
|
12
|
+
#
|
|
13
|
+
# Runnable as a script over any number of artifacts (exit 1 on the
|
|
14
|
+
# first violated contract batch) or required for the pure checks in
|
|
15
|
+
# spec/check_bundle_linkage_spec.rb.
|
|
16
|
+
module CheckBundleLinkage
|
|
17
|
+
ALLOWED_PREFIXES = %w[@rpath/ @loader_path/ @executable_path/ /usr/lib/ /System/].freeze
|
|
18
|
+
|
|
19
|
+
# The LC_LOAD_DYLIB paths otool -L lists that fall outside the
|
|
20
|
+
# allowlist. +otool_output+ is the raw stdout of `otool -L <file>`;
|
|
21
|
+
# entries are the tab-indented "<install name> (compatibility
|
|
22
|
+
# version X, current version Y)" lines.
|
|
23
|
+
def self.load_command_violations(otool_output)
|
|
24
|
+
otool_output.lines.grep(/^\t.*\(compatibility version/)
|
|
25
|
+
.filter_map { |l| l.split.first }
|
|
26
|
+
.reject { |path| ALLOWED_PREFIXES.any? { |p| path.start_with?(p) } }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# The libruby sonames a strings(1) dump reveals — the ELF-side
|
|
30
|
+
# tripwire for DT_NEEDED entries and RUNPATH spellings alike.
|
|
31
|
+
def self.libruby_references(strings_output)
|
|
32
|
+
strings_output.scan(/libruby[\w.]*/).uniq
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if $PROGRAM_NAME == __FILE__
|
|
37
|
+
require "shellwords"
|
|
38
|
+
|
|
39
|
+
status = 0
|
|
40
|
+
ARGV.each do |path|
|
|
41
|
+
next if path.end_with?(".dll")
|
|
42
|
+
|
|
43
|
+
bad = CheckBundleLinkage.libruby_references(`strings #{Shellwords.escape(path)} 2>/dev/null`)
|
|
44
|
+
unless bad.empty?
|
|
45
|
+
warn "ERROR: #{path} references #{bad.join(', ')} — Ruby symbols must " \
|
|
46
|
+
"resolve from the loading interpreter, never a linked libruby " \
|
|
47
|
+
"(#1739); link with -undefined dynamic_lookup / plain -shared"
|
|
48
|
+
status = 1
|
|
49
|
+
end
|
|
50
|
+
next unless RUBY_PLATFORM.include?("darwin")
|
|
51
|
+
|
|
52
|
+
viol = CheckBundleLinkage.load_command_violations(`otool -L #{Shellwords.escape(path)} 2>/dev/null`)
|
|
53
|
+
next if viol.empty?
|
|
54
|
+
|
|
55
|
+
warn "ERROR: #{path} carries load commands outside the loader " \
|
|
56
|
+
"allowlist (#{CheckBundleLinkage::ALLOWED_PREFIXES.join(' ')}): " \
|
|
57
|
+
"#{viol.join(', ')} (#1739)"
|
|
58
|
+
status = 1
|
|
59
|
+
end
|
|
60
|
+
exit status
|
|
61
|
+
end
|
|
@@ -28,6 +28,19 @@ unless %w[ruby truffleruby].include?(RUBY_ENGINE)
|
|
|
28
28
|
"installing without the compiled native layer"
|
|
29
29
|
exit 0
|
|
30
30
|
end
|
|
31
|
+
# Never link libruby: a Ruby extension resolves rb_* symbols from
|
|
32
|
+
# the LOADING interpreter, and mkmf records the building ruby's
|
|
33
|
+
# libruby (for setup-ruby, an absolute hostedtoolcache path) into
|
|
34
|
+
# the bundle otherwise — dlopen-failing on every other machine
|
|
35
|
+
# (#1739). mkmf snapshots $LIBRUBYARG* from RbConfig at require
|
|
36
|
+
# time, so this MUST precede `require "mkmf"`; a later clearing is
|
|
37
|
+
# a silent no-op (exactly how the 1.9.36x trains shipped broken).
|
|
38
|
+
if RUBY_PLATFORM =~ /darwin/
|
|
39
|
+
%w[LIBRUBYARG LIBRUBYARG_SHARED LIBRUBYARG_STATIC].each do |key|
|
|
40
|
+
RbConfig::CONFIG[key] = ""
|
|
41
|
+
RbConfig::MAKEFILE_CONFIG[key] = ""
|
|
42
|
+
end
|
|
43
|
+
end
|
|
31
44
|
require "mkmf"
|
|
32
45
|
|
|
33
46
|
# A prebuilt libleptris in lib/ (dev checkout after rake compile,
|
|
@@ -106,18 +119,25 @@ if RUBY_PLATFORM =~ /darwin/
|
|
|
106
119
|
[$LDFLAGS, $DLDFLAGS].each do |var|
|
|
107
120
|
var << lookup unless var.include?("dynamic_lookup")
|
|
108
121
|
end
|
|
109
|
-
#
|
|
110
|
-
#
|
|
111
|
-
#
|
|
112
|
-
#
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
# ruby#476: newer ld64 defaults BUNDLES to two-level namespace —
|
|
123
|
+
# with -undefined dynamic_lookup a two-level bind records the
|
|
124
|
+
# symbol as expected from the MAIN EXECUTABLE ("main-executable"),
|
|
125
|
+
# and interpreters that don't re-export every ruby symbol from
|
|
126
|
+
# their binary abort at first call ("dyld missing symbol called",
|
|
127
|
+
# hit at Init_native's first import). -flat_namespace is the
|
|
128
|
+
# classic C-extension pattern: dynamic_lookup symbols search all
|
|
129
|
+
# loaded images at call time and resolve from libruby.
|
|
130
|
+
flat = " -Wl,-flat_namespace"
|
|
131
|
+
[$LDFLAGS, $DLDFLAGS].each do |var|
|
|
132
|
+
var << flat unless var.include?("flat_namespace")
|
|
133
|
+
end
|
|
134
|
+
# Belt for the require-time snapshot: RbConfig was cleared BEFORE
|
|
135
|
+
# `require "mkmf"` (top of file), and the module globals mkmf
|
|
136
|
+
# captured then are zeroed here too — a Ruby extension resolves
|
|
137
|
+
# Ruby symbols from the loading interpreter; never link libruby.
|
|
138
|
+
$LIBRUBYARG = ""
|
|
139
|
+
$LIBRUBYARG_SHARED = ""
|
|
140
|
+
$LIBRUBYARG_STATIC = ""
|
|
121
141
|
end
|
|
122
142
|
if Gem.win_platform?
|
|
123
143
|
# Windows names the artifact per Ruby minor, DOT-FREE (#227
|
|
@@ -137,4 +157,12 @@ if Gem.win_platform?
|
|
|
137
157
|
win_def = " #{def_path.tr('/', '\\\\')}"
|
|
138
158
|
$DLDFLAGS << win_def unless $DLDFLAGS.include?("native_exports.def")
|
|
139
159
|
end
|
|
140
|
-
|
|
160
|
+
# Name the artifact per Ruby minor EVERYWHERE (#476): the loader
|
|
161
|
+
# requires native_<minor> and deliberately has NO unversioned
|
|
162
|
+
# fallback (loading a bundle built by another minor is the 3.1
|
|
163
|
+
# wrong-ABI segfault class), so a source install must produce the
|
|
164
|
+
# per-minor name itself. mkmf derives Init_native_<minor> from the
|
|
165
|
+
# same basename — exported by native.c and pinned in the Windows
|
|
166
|
+
# .def above.
|
|
167
|
+
minor_us = RUBY_VERSION[/\A\d+\.\d+/].tr(".", "_")
|
|
168
|
+
create_makefile("leptris/xml/native_#{minor_us}")
|