tebako 0.15.2 → 0.15.3
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/CMakeLists.txt +13 -1
- data/include/tebako/tpkg.h +8 -15
- data/lib/tebako/cli_helpers.rb +21 -14
- data/lib/tebako/deploy_helper.rb +5 -1
- data/lib/tebako/packager.rb +57 -1
- data/lib/tebako/ruby_version.rb +35 -10
- data/lib/tebako/runtime_manager.rb +21 -0
- data/lib/tebako/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8ec3da7722b76d52f17d341664974ff8ea5f5164feec924958cd2725238439d0
|
|
4
|
+
data.tar.gz: 2e244d8b29c27a4f884aa969961dca6968323d21376012bf539dbce28c5b7baa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ccf67b3e4bf6444ca31627b27e9876699f743cdac01e2ebea0cee29a9ea8113d24d5ef34d6b15ebd8461620c8e29bb3d75ef7332b5a1934e3b3d579130cdb871
|
|
7
|
+
data.tar.gz: 51695b16c05b1063678bc2f4c6042ae65c3111799f14f81a5d3982a30c4f94f74f7f28d2fa587c11cdcf509ff9a5f105428ed95eff693d47377337980d349177
|
data/CMakeLists.txt
CHANGED
|
@@ -217,6 +217,7 @@ endif()
|
|
|
217
217
|
def_ext_prj_g(PATCHELF "65e14792061c298f1d2bc44becd48a10cbf0bc81")
|
|
218
218
|
|
|
219
219
|
set(LIBYAML_RUBY_OPTION "")
|
|
220
|
+
set(RUBY_LIBS "")
|
|
220
221
|
if(${RUBY_VER} VERSION_LESS "3.2.0")
|
|
221
222
|
set(LIBYAML_RUBY_OPTION "--enable-bundled-libyaml")
|
|
222
223
|
endif(${RUBY_VER} VERSION_LESS "3.2.0")
|
|
@@ -397,6 +398,16 @@ else(IS_DARWIN)
|
|
|
397
398
|
if(RB_W32)
|
|
398
399
|
string(CONCAT RUBY_C_FLAGS ${RUBY_C_FLAGS} " -DRB_W32=1")
|
|
399
400
|
string(CONCAT RUBY_L_FLAGS ${RUBY_L_FLAGS} " -l:libstdc++.a -L${TLIBD}")
|
|
401
|
+
# vcpkg's static libcrypto.a (the CAPI engine, e_capi.obj) references
|
|
402
|
+
# the CryptoAPI certificate store (CertFreeCertificateContext & co.),
|
|
403
|
+
# but ruby's default mingw $LIBS lack -lcrypt32, so every ext/openssl
|
|
404
|
+
# have_func link probe failed with undefined Cert* references and the
|
|
405
|
+
# OpenSSL-1.1.0 accessor fallbacks in openssl_missing.c compiled
|
|
406
|
+
# against opaque 3.x structs (tebako#345). mkmf appends $LIBS after
|
|
407
|
+
# -lssl/-lcrypto, so LIBS here lands in the right order for static
|
|
408
|
+
# linking; advapi32/user32 cover the rest of the usual static-openssl
|
|
409
|
+
# system-lib tail.
|
|
410
|
+
set(RUBY_LIBS "-lcrypt32 -ladvapi32 -luser32")
|
|
400
411
|
set(C_FLAGS_DEST cppflags)
|
|
401
412
|
endif(RB_W32)
|
|
402
413
|
|
|
@@ -432,7 +443,8 @@ ExternalProject_Add(${RUBY_PRJ}
|
|
|
432
443
|
--with-out-ext=${RUBY_WITHOUT_EXT} \
|
|
433
444
|
--prefix=${DATA_SRC_DIR} \
|
|
434
445
|
${C_FLAGS_DEST}=\"${RUBY_C_FLAGS}\" \
|
|
435
|
-
LDFLAGS=\"${RUBY_L_FLAGS}\"
|
|
446
|
+
LDFLAGS=\"${RUBY_L_FLAGS}\" \
|
|
447
|
+
LIBS=\"${RUBY_LIBS}\""
|
|
436
448
|
COMMAND ruby ${EXE}/tebako-packager pass2 ${OSTYPE_TXT} ${RUBY_SOURCE_DIR} ${DEPS_LIB_DIR} ${DATA_SRC_DIR} ${RUBY_STASH_DIR} ${RUBY_VER}
|
|
437
449
|
INSTALL_COMMAND ""
|
|
438
450
|
)
|
data/include/tebako/tpkg.h
CHANGED
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
* 8 8 u64 size (image length in bytes)
|
|
51
51
|
* 16 4 u32 format_id (0=auto(magic), 1=dwarfs, 2=squashfs, 3=zip, 4=runtime payload)
|
|
52
52
|
* 20 4 u32 flags
|
|
53
|
-
* 24 256 char mount_point[256] (UTF-8, NUL-padded
|
|
53
|
+
* 24 256 char mount_point[256] (UTF-8, NUL-padded)
|
|
54
54
|
*
|
|
55
55
|
* Reader algorithm: read the fixed-size header at EOF - TPKG_HEADER_SIZE,
|
|
56
56
|
* check the magic, verify header_crc32, then read slot_count slot records at
|
|
@@ -97,8 +97,8 @@ extern "C" {
|
|
|
97
97
|
#define TPKG_MOUNT_POINT_LEN 256u
|
|
98
98
|
#define TPKG_RUNTIME_REF_LEN 128u
|
|
99
99
|
#define TPKG_MAGIC "TEBAKOTFS"
|
|
100
|
-
#define TPKG_MAGIC_LEN 10u
|
|
101
|
-
#define TPKG_MAGIC_PREFIX_LEN 4u
|
|
100
|
+
#define TPKG_MAGIC_LEN 10u /* including the terminating NUL */
|
|
101
|
+
#define TPKG_MAGIC_PREFIX_LEN 4u /* "TEBA": absent-vs-corrupt discriminator */
|
|
102
102
|
|
|
103
103
|
/* package_flags */
|
|
104
104
|
#define TPKG_FLAG_LEAN 0x1u
|
|
@@ -108,8 +108,8 @@ extern "C" {
|
|
|
108
108
|
#define TPKG_FORMAT_DWARFS 1u
|
|
109
109
|
#define TPKG_FORMAT_SQUASHFS 2u
|
|
110
110
|
#define TPKG_FORMAT_ZIP 3u
|
|
111
|
-
/* runtime payload slot
|
|
112
|
-
*
|
|
111
|
+
/* A runtime payload slot (fat packages): the compressed language-runtime
|
|
112
|
+
* package the bootstrap installs into the shared cache on first run. */
|
|
113
113
|
#define TPKG_FORMAT_RUNTIME 4u
|
|
114
114
|
|
|
115
115
|
/* ---- error codes (returned by tpkg_errno) -------------------------------- */
|
|
@@ -223,19 +223,12 @@ enum {
|
|
|
223
223
|
};
|
|
224
224
|
|
|
225
225
|
/* slot record field offsets */
|
|
226
|
-
enum {
|
|
227
|
-
TPKG__REC_OFFSET = 0,
|
|
228
|
-
TPKG__REC_SIZE = 8,
|
|
229
|
-
TPKG__REC_FORMAT = 16,
|
|
230
|
-
TPKG__REC_FLAGS = 20,
|
|
231
|
-
TPKG__REC_MOUNT = 24
|
|
232
|
-
};
|
|
226
|
+
enum { TPKG__REC_OFFSET = 0, TPKG__REC_SIZE = 8, TPKG__REC_FORMAT = 16, TPKG__REC_FLAGS = 20, TPKG__REC_MOUNT = 24 };
|
|
233
227
|
|
|
234
228
|
/* wire sizes are fixed by the format; catch exotic padding at compile time */
|
|
235
229
|
typedef char tpkg__assert_slot_size[(sizeof(tpkg_slot) == TPKG_SLOT_SIZE) ? 1 : -1];
|
|
236
|
-
typedef char tpkg__assert_manifest_size[(sizeof(tpkg_manifest) ==
|
|
237
|
-
|
|
238
|
-
TPKG_MAX_SLOTS * sizeof(tpkg_slot))
|
|
230
|
+
typedef char tpkg__assert_manifest_size[(sizeof(tpkg_manifest) == 4 * sizeof(uint32_t) + TPKG_RUNTIME_REF_LEN +
|
|
231
|
+
TPKG_MAX_SLOTS * sizeof(tpkg_slot))
|
|
239
232
|
? 1
|
|
240
233
|
: -1];
|
|
241
234
|
|
data/lib/tebako/cli_helpers.rb
CHANGED
|
@@ -112,7 +112,8 @@ module Tebako
|
|
|
112
112
|
def do_press_prebuilt(options_manager, scenario_manager)
|
|
113
113
|
Tebako::Packager.check_prebuilt_env!(options_manager.stash_dir, options_manager.deps_bin_dir)
|
|
114
114
|
runtime_path = Tebako::RuntimeManager.resolve(options_manager.ruby_ver, options_manager.host_platform)
|
|
115
|
-
app_image = Tebako::Packager.build_app_image(options_manager, scenario_manager
|
|
115
|
+
app_image = Tebako::Packager.build_app_image(options_manager, scenario_manager,
|
|
116
|
+
Tebako::RuntimeManager.layout(runtime_path))
|
|
116
117
|
|
|
117
118
|
images = [{ path: app_image, mount_point: scenario_manager.fs_mount_point,
|
|
118
119
|
format_id: Tebako::Stitcher::FORMAT_DWARFS }] + options_manager.images
|
|
@@ -128,33 +129,39 @@ module Tebako
|
|
|
128
129
|
# slot, so the first run installs it without any network access.
|
|
129
130
|
def do_press_three_part(options_manager, scenario_manager)
|
|
130
131
|
bootstrap_path, runtime_path = resolve_three_part_parts(options_manager)
|
|
131
|
-
app_image = Tebako::Packager.build_app_image(options_manager, scenario_manager
|
|
132
|
-
|
|
132
|
+
app_image = Tebako::Packager.build_app_image(options_manager, scenario_manager,
|
|
133
|
+
Tebako::RuntimeManager.layout(runtime_path))
|
|
134
|
+
payload_path = options_manager.fat? ? runtime_path : nil
|
|
135
|
+
images = three_part_images(options_manager, scenario_manager, app_image, payload_path)
|
|
133
136
|
package = "#{options_manager.package}#{scenario_manager.exe_suffix}"
|
|
134
|
-
|
|
137
|
+
stitch_three_part(options_manager, bootstrap_path, images, package, payload_path)
|
|
138
|
+
puts "Created tebako #{options_manager.output_type_first} at \"#{package}\""
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def stitch_three_part(options_manager, bootstrap_path, images, package, payload_path)
|
|
135
142
|
Tebako::Stitcher.stitch(bootstrap_path, images: images, output: package, lean: true,
|
|
136
143
|
ruby_version: options_manager.ruby_ver,
|
|
137
144
|
launcher_abi: Tebako::LauncherAbi::VERSION,
|
|
138
|
-
runtime_sha256:
|
|
139
|
-
|
|
145
|
+
runtime_sha256: payload_sha256(payload_path))
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def payload_sha256(payload_path)
|
|
149
|
+
payload_path && Digest::SHA256.file(payload_path).hexdigest
|
|
140
150
|
end
|
|
141
151
|
|
|
142
152
|
# Validate the options and the packaging environment, then resolve the
|
|
143
|
-
# bootstrap
|
|
153
|
+
# bootstrap and the runtime into the shared cache. The runtime is needed
|
|
154
|
+
# in both three-part modes: 'fat' embeds it as a payload slot, 'lean'
|
|
155
|
+
# uses its extracted layout to align the application image's arch
|
|
156
|
+
# conventions (and references it in the trailer for first-run resolution)
|
|
144
157
|
def resolve_three_part_parts(options_manager)
|
|
145
158
|
options_manager.runtime_source # validates the mode/provenance combination
|
|
146
159
|
check_bootstrap_version!(options_manager)
|
|
147
160
|
Tebako::Packager.check_prebuilt_env!(options_manager.stash_dir, options_manager.deps_bin_dir)
|
|
148
|
-
runtime_path =
|
|
161
|
+
runtime_path = Tebako::RuntimeManager.resolve(options_manager.ruby_ver, options_manager.host_platform)
|
|
149
162
|
[Tebako::BootstrapManager.resolve(options_manager.host_platform), runtime_path]
|
|
150
163
|
end
|
|
151
164
|
|
|
152
|
-
def fat_runtime_path(options_manager)
|
|
153
|
-
return nil unless options_manager.fat?
|
|
154
|
-
|
|
155
|
-
Tebako::RuntimeManager.resolve(options_manager.ruby_ver, options_manager.host_platform)
|
|
156
|
-
end
|
|
157
|
-
|
|
158
165
|
def three_part_images(options_manager, scenario_manager, app_image, runtime_path)
|
|
159
166
|
images = [{ path: app_image, mount_point: scenario_manager.fs_mount_point,
|
|
160
167
|
format_id: Tebako::Stitcher::FORMAT_DWARFS }] + options_manager.images
|
data/lib/tebako/deploy_helper.rb
CHANGED
|
@@ -190,7 +190,11 @@ module Tebako
|
|
|
190
190
|
def configure_commands_not_msys
|
|
191
191
|
@cmd_suffix = ""
|
|
192
192
|
@bat_suffix = ""
|
|
193
|
-
|
|
193
|
+
# Force the ruby (source) platform for gems: precompiled variants link
|
|
194
|
+
# against shared system libraries (libffi & co.) that do not exist
|
|
195
|
+
# inside a tebako package -- e.g. ffi-x86_64-linux-gnu fails to load in
|
|
196
|
+
# the memfs (tebako#343). msys has always forced this.
|
|
197
|
+
@force_ruby_platform = "true"
|
|
194
198
|
@nokogiri_option = "--no-use-system-libraries"
|
|
195
199
|
end
|
|
196
200
|
|
data/lib/tebako/packager.rb
CHANGED
|
@@ -129,16 +129,72 @@ module Tebako
|
|
|
129
129
|
# Deploy the application and build its DwarFS image for stitching onto
|
|
130
130
|
# a prebuilt runtime. Same layout as the bundle-mode image, plus an
|
|
131
131
|
# entry dispatcher at /local/stub.rb (the runtime's compiled-in entry).
|
|
132
|
-
|
|
132
|
+
# When layout_dir is given (the resolved runtime's extracted layout),
|
|
133
|
+
# the image's arch conventions are aligned to the runtime's: ruby's
|
|
134
|
+
# compiled-in search paths come from the runtime build, while the
|
|
135
|
+
# local packaging environment names arch directories after the press
|
|
136
|
+
# machine -- on macOS the arch string embeds the kernel version
|
|
137
|
+
# (arm64-darwin23 vs arm64-darwin24), so they differ whenever press
|
|
138
|
+
# and runtime were built on different macOS releases.
|
|
139
|
+
def build_app_image(options_manager, scenario_manager, layout_dir = nil) # rubocop:disable Metrics/AbcSize
|
|
133
140
|
init(options_manager.stash_dir, options_manager.data_src_dir, options_manager.data_pre_dir,
|
|
134
141
|
options_manager.data_bin_dir)
|
|
135
142
|
deploy(options_manager.data_src_dir, options_manager.data_pre_dir, options_manager.rv,
|
|
136
143
|
options_manager.root, scenario_manager.fs_entrance, options_manager.cwd)
|
|
144
|
+
align_layout_to_runtime!(options_manager.data_src_dir, layout_dir, options_manager.rv) if layout_dir
|
|
137
145
|
write_entry_dispatcher(options_manager.data_src_dir, scenario_manager, options_manager.cwd)
|
|
138
146
|
mkdwarfs(options_manager.deps_bin_dir, options_manager.data_bundle_file, options_manager.data_src_dir)
|
|
139
147
|
options_manager.data_bundle_file
|
|
140
148
|
end
|
|
141
149
|
|
|
150
|
+
# Rename the image's arch directories to the runtime's names and drop
|
|
151
|
+
# in the runtime's own rbconfig.rb. No-op when the conventions already
|
|
152
|
+
# match (always the case off macOS, where the arch string carries no
|
|
153
|
+
# OS version).
|
|
154
|
+
def align_layout_to_runtime!(data_src_dir, layout_dir, ruby_ver)
|
|
155
|
+
align_stdlib_arch!(data_src_dir, layout_dir, ruby_ver.api_version)
|
|
156
|
+
align_gem_ext_arch!(data_src_dir, layout_dir, ruby_ver.api_version)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def align_stdlib_arch!(data_src_dir, layout_dir, api_ver)
|
|
160
|
+
runtime_arch = arch_dir_of(File.join(layout_dir, "lib", "ruby", api_ver), "rbconfig.rb")
|
|
161
|
+
image_arch = arch_dir_of(File.join(data_src_dir, "lib", "ruby", api_ver), "rbconfig.rb")
|
|
162
|
+
return if runtime_arch.nil? || image_arch.nil? || runtime_arch == image_arch
|
|
163
|
+
|
|
164
|
+
puts " ... aligning app image layout to the runtime (#{image_arch} -> #{runtime_arch})"
|
|
165
|
+
FileUtils.mv(File.join(data_src_dir, "lib", "ruby", api_ver, image_arch),
|
|
166
|
+
File.join(data_src_dir, "lib", "ruby", api_ver, runtime_arch))
|
|
167
|
+
FileUtils.cp(File.join(layout_dir, "lib", "ruby", api_ver, runtime_arch, "rbconfig.rb"),
|
|
168
|
+
File.join(data_src_dir, "lib", "ruby", api_ver, runtime_arch, "rbconfig.rb"))
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Native-gem extensions dir uses the dashed flavor of the arch string
|
|
172
|
+
# (arm64-darwin-23); align it to the runtime's as well
|
|
173
|
+
def align_gem_ext_arch!(data_src_dir, layout_dir, api_ver)
|
|
174
|
+
img_ext = File.join(data_src_dir, "lib", "ruby", "gems", api_ver, "extensions")
|
|
175
|
+
rt_ext = File.join(layout_dir, "lib", "ruby", "gems", api_ver, "extensions")
|
|
176
|
+
runtime_ext = first_dir(rt_ext)
|
|
177
|
+
return if runtime_ext.nil? || !Dir.exist?(img_ext)
|
|
178
|
+
|
|
179
|
+
Dir.children(img_ext).each do |d|
|
|
180
|
+
next if d == runtime_ext || !File.directory?(File.join(img_ext, d))
|
|
181
|
+
|
|
182
|
+
FileUtils.mv(File.join(img_ext, d), File.join(img_ext, runtime_ext))
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def arch_dir_of(dir, marker)
|
|
187
|
+
return nil unless Dir.exist?(dir)
|
|
188
|
+
|
|
189
|
+
Dir.children(dir).find { |d| File.exist?(File.join(dir, d, marker)) }
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def first_dir(dir)
|
|
193
|
+
return nil unless Dir.exist?(dir)
|
|
194
|
+
|
|
195
|
+
Dir.children(dir).find { |d| File.directory?(File.join(dir, d)) }
|
|
196
|
+
end
|
|
197
|
+
|
|
142
198
|
# The prebuilt runtime packages are pressed in 'runtime' mode, so their
|
|
143
199
|
# compiled-in entry point is /local/stub.rb. A stitched package mounts
|
|
144
200
|
# the application image as the root filesystem; the dispatcher written
|
data/lib/tebako/ruby_version.rb
CHANGED
|
@@ -46,7 +46,14 @@ module Tebako
|
|
|
46
46
|
"3.3.6" => "8dc48fffaf270f86f1019053f28e51e4da4cce32a36760a0603a9aee67d7fd8d",
|
|
47
47
|
"3.3.7" => "9c37c3b12288c7aec20ca121ce76845be5bb5d77662a24919651aaf1d12c8628",
|
|
48
48
|
"3.4.1" => "3d385e5d22d368b064c817a13ed8e3cc3f71a7705d7ed1bae78013c33aa7c87f",
|
|
49
|
-
"3.4.2" => "41328ac21f2bfdd7de6b3565ef4f0dd7543354d37e96f157a1552a6bd0eb364b"
|
|
49
|
+
"3.4.2" => "41328ac21f2bfdd7de6b3565ef4f0dd7543354d37e96f157a1552a6bd0eb364b",
|
|
50
|
+
"4.0.0" => "2e8389c8c072cb658c93a1372732d9eac84082c88b065750db1e52a5ac630271",
|
|
51
|
+
"4.0.1" => "3924be2d05db30f4e35f859bf028be85f4b7dd01714142fd823e4af5de2faf9d",
|
|
52
|
+
"4.0.2" => "51502b26b50b68df4963336ca41e368cde92c928faf91654de4c4c1791f82aac",
|
|
53
|
+
"4.0.3" => "77964acc370d5c8375b9502e5ba6c13c03ef91ab9eb9f521c84fb42b9c9a6b0f",
|
|
54
|
+
"4.0.4" => "f35f6edfa3dabb3f723f9d0cf1906c6512ae77f4e412ab1e68cc6e91d230fa80",
|
|
55
|
+
"4.0.5" => "7d6149079a63f8ae1d326c9fa65c6019ba2dc3155eae7b39159817911c88958e",
|
|
56
|
+
"4.0.6" => "837d299e8f7ddf2be31a229a7a7e019d354979825117989acb3b32b1a9be262a"
|
|
50
57
|
}.freeze
|
|
51
58
|
|
|
52
59
|
MIN_RUBY_VERSION_WINDOWS = "3.1.6"
|
|
@@ -72,38 +79,40 @@ module Tebako
|
|
|
72
79
|
@lib_version ||= "#{@ruby_version.split(".")[0..1].join}0"
|
|
73
80
|
end
|
|
74
81
|
|
|
82
|
+
# Version gates compare numerically so 4.x lines fall out naturally
|
|
83
|
+
# (string indexing broke the moment the major version hit 4)
|
|
75
84
|
def ruby3x?
|
|
76
|
-
@ruby3x ||=
|
|
85
|
+
@ruby3x ||= version_at_least?(3, 0)
|
|
77
86
|
end
|
|
78
87
|
|
|
79
88
|
def ruby31?
|
|
80
|
-
@ruby31 ||=
|
|
89
|
+
@ruby31 ||= version_at_least?(3, 1)
|
|
81
90
|
end
|
|
82
91
|
|
|
83
92
|
def ruby32?
|
|
84
|
-
@ruby32 ||=
|
|
93
|
+
@ruby32 ||= version_at_least?(3, 2)
|
|
85
94
|
end
|
|
86
95
|
|
|
87
96
|
def ruby32only?
|
|
88
|
-
@ruby32only ||=
|
|
97
|
+
@ruby32only ||= major_minor == [3, 2]
|
|
89
98
|
end
|
|
90
99
|
|
|
91
100
|
def ruby33?
|
|
92
|
-
@ruby33 ||=
|
|
101
|
+
@ruby33 ||= version_at_least?(3, 3)
|
|
93
102
|
end
|
|
94
103
|
|
|
95
104
|
def ruby33only?
|
|
96
|
-
@ruby33only ||=
|
|
105
|
+
@ruby33only ||= major_minor == [3, 3]
|
|
97
106
|
end
|
|
98
107
|
|
|
99
108
|
def ruby3x7?
|
|
100
109
|
@ruby3x7 ||= ruby34? ||
|
|
101
|
-
(ruby33only? &&
|
|
102
|
-
(ruby32only? &&
|
|
110
|
+
(ruby33only? && patch_version >= 7) ||
|
|
111
|
+
(ruby32only? && patch_version >= 7)
|
|
103
112
|
end
|
|
104
113
|
|
|
105
114
|
def ruby34?
|
|
106
|
-
@ruby34 ||=
|
|
115
|
+
@ruby34 ||= version_at_least?(3, 4)
|
|
107
116
|
end
|
|
108
117
|
|
|
109
118
|
def run_checks
|
|
@@ -112,6 +121,22 @@ module Tebako
|
|
|
112
121
|
version_check_msys
|
|
113
122
|
end
|
|
114
123
|
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
def major_minor
|
|
127
|
+
@major_minor ||= @ruby_version.split(".").first(2).map(&:to_i)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def patch_version
|
|
131
|
+
@patch_version ||= @ruby_version.split(".")[2].to_i
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def version_at_least?(major, minor)
|
|
135
|
+
(major_minor <=> [major, minor]) >= 0
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
public
|
|
139
|
+
|
|
115
140
|
def version_check
|
|
116
141
|
return if RUBY_VERSIONS.key?(@ruby_version)
|
|
117
142
|
|
|
@@ -31,6 +31,7 @@ require "json"
|
|
|
31
31
|
require "net/http"
|
|
32
32
|
require "uri"
|
|
33
33
|
|
|
34
|
+
require_relative "build_helpers"
|
|
34
35
|
require_relative "error"
|
|
35
36
|
require_relative "version"
|
|
36
37
|
|
|
@@ -83,6 +84,10 @@ module Tebako
|
|
|
83
84
|
def resolve(ruby_version, platform, tebako_version: Tebako::VERSION)
|
|
84
85
|
new.resolve(ruby_version, platform, tebako_version: tebako_version)
|
|
85
86
|
end
|
|
87
|
+
|
|
88
|
+
def layout(runtime_path)
|
|
89
|
+
new.layout(runtime_path)
|
|
90
|
+
end
|
|
86
91
|
end
|
|
87
92
|
|
|
88
93
|
def initialize(cache_root: nil, mirror: nil, lock_timeout: LOCK_TIMEOUT, retry_delay: RETRY_DELAY)
|
|
@@ -105,6 +110,22 @@ module Tebako
|
|
|
105
110
|
executable
|
|
106
111
|
end
|
|
107
112
|
|
|
113
|
+
# Extract the runtime package's filesystem layout next to the cached
|
|
114
|
+
# package (idempotent) and return the layout root. The layout is the
|
|
115
|
+
# authoritative source of the runtime's arch conventions (rbconfig
|
|
116
|
+
# location, gem extension dir naming), which the application image must
|
|
117
|
+
# match: ruby's compiled-in search paths come from the runtime build,
|
|
118
|
+
# while a local packaging environment names them after the press machine
|
|
119
|
+
# (macOS embeds the kernel version, e.g. arm64-darwin23 vs -darwin24).
|
|
120
|
+
def layout(runtime_path)
|
|
121
|
+
layout_dir = File.join(File.dirname(runtime_path), "layout")
|
|
122
|
+
return layout_dir if File.directory?(File.join(layout_dir, "lib"))
|
|
123
|
+
|
|
124
|
+
FileUtils.mkdir_p(layout_dir)
|
|
125
|
+
Tebako::BuildHelpers.run_with_capture_v([runtime_path, "--tebako-extract", layout_dir])
|
|
126
|
+
layout_dir
|
|
127
|
+
end
|
|
128
|
+
|
|
108
129
|
def entries
|
|
109
130
|
base = File.join(@cache_root, cache_subdir)
|
|
110
131
|
return [] unless Dir.exist?(base)
|
data/lib/tebako/version.rb
CHANGED