tebako 0.15.1 → 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 +14 -2
- data/README.adoc +9 -4
- data/cmake/tebako-libtfs.cmake +1 -3
- data/include/tebako/tpkg.h +11 -15
- data/lib/tebako/bootstrap_manager.rb +158 -0
- data/lib/tebako/cli.rb +17 -5
- data/lib/tebako/cli_helpers.rb +78 -3
- data/lib/tebako/deploy_helper.rb +5 -1
- data/lib/tebako/error.rb +3 -0
- data/lib/tebako/launcher_abi.rb +6 -0
- data/lib/tebako/options_manager.rb +33 -11
- data/lib/tebako/packager/pass1_patch.rb +20 -1
- data/lib/tebako/packager/pass2msys_patch.rb +3 -0
- data/lib/tebako/packager/patch_helpers.rb +3 -1
- data/lib/tebako/packager.rb +57 -1
- data/lib/tebako/ruby_version.rb +35 -10
- data/lib/tebako/runtime_manager.rb +50 -6
- data/lib/tebako/stitcher.rb +22 -6
- data/lib/tebako/version.rb +1 -1
- metadata +2 -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
|
@@ -175,7 +175,7 @@ string(CONCAT RUBY_API_VER ${RUBY_VER_BASE} ".0")
|
|
|
175
175
|
# NOTE: the env override in def_ext_prj_g (tebako-tools) is currently broken
|
|
176
176
|
# (`if (DEFINED ENV{${TAG})` is missing a closing brace, so the test never
|
|
177
177
|
# fires); this default is the operative tag selection.
|
|
178
|
-
def_ext_prj_g(DWARFS_WR "v0.12.
|
|
178
|
+
def_ext_prj_g(DWARFS_WR "v0.12.9")
|
|
179
179
|
|
|
180
180
|
# Provisions libtfs (prebuilt package or vcpkg toolchain for the source
|
|
181
181
|
# build), the prebuilt mkdwarfs, and -- for the prebuilt path -- the
|
|
@@ -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/README.adoc
CHANGED
|
@@ -420,7 +420,7 @@ tebako press \
|
|
|
420
420
|
[-c|--cwd=<package-current-working-directory>] \
|
|
421
421
|
[-D|--devmode] \
|
|
422
422
|
[-P|--patchelf] \
|
|
423
|
-
[-m|--mode=<bundle|both|application|runtime>] \
|
|
423
|
+
[-m|--mode=<lean|fat|classic|bundle|both|application|runtime>] \
|
|
424
424
|
[-u|--ref=<runtime-reference>] \
|
|
425
425
|
[-t|--tebafile=<path-to-tebafile>]
|
|
426
426
|
----
|
|
@@ -452,6 +452,7 @@ On Windows, the output file is automatically appended the `.exe` extension.
|
|
|
452
452
|
|
|
453
453
|
*** in `runtime` mode, the runtime package is created at `tebako-runtime`.
|
|
454
454
|
*** in `application` mode, the application package is created at `<current-folder>/<entry-point-base-name>`.
|
|
455
|
+
*** in `lean`, `fat` and `classic` modes, the package is created at `<current-folder>/<entry-point-base-name>`.
|
|
455
456
|
*** in `bundle` mode, the bundled package is created at `<current-folder>/<entry-point-base-name>`.
|
|
456
457
|
*** in `both` mode, the runtime package is created at `<current-folder>/<entry-point-base-name>`,
|
|
457
458
|
and the application package is created at `<current-folder>/<entry-point-base-name>.tebako`.
|
|
@@ -460,6 +461,7 @@ and the application package is created at `<current-folder>/<entry-point-base-na
|
|
|
460
461
|
|
|
461
462
|
*** in `runtime` mode, the runtime package is named according to the `-o` option.
|
|
462
463
|
*** in `application` mode, the application package is named according to the `-o` option.
|
|
464
|
+
*** in `lean`, `fat` and `classic` modes, the package is named according to the `-o` option.
|
|
463
465
|
*** in `bundle` mode, the bundled package is named according to the `-o` option.
|
|
464
466
|
*** in `both` mode, the runtime package is named according to the `-o` option,
|
|
465
467
|
and the application package is named according to the `-o` option with the `.tebako` extension.
|
|
@@ -502,10 +504,13 @@ For example, a package created at Ubuntu 20 system can be used on Ubuntu 22.
|
|
|
502
504
|
NOTE: The feature is exeprimental, we may consider another approach in the future.
|
|
503
505
|
|
|
504
506
|
`--mode=<mode>`::
|
|
505
|
-
(optional, defaults to `
|
|
506
|
-
Package output mode, determines
|
|
507
|
-
|
|
507
|
+
(optional, defaults to `lean`)
|
|
508
|
+
Package output mode, determines the package layout (three-part or runtime-stitched)
|
|
509
|
+
and whether the runtime and/or application are separately packaged.
|
|
508
510
|
|
|
511
|
+
`lean`::: Create a three-part package: the tebako-bootstrap launcher plus the application image slot(s) and a tpkg manifest trailer carrying the runtime reference. At first run the bootstrap resolves (downloads, verifies and caches) the referenced prebuilt runtime into the machine-wide cache (`~/.tebako` or `$TEBAKO_HOME`); subsequent runs of any lean package built for the same runtime share that cache entry. The output file is named according to the `-o` option.
|
|
512
|
+
`fat`::: Like `lean`, but the runtime package is also embedded as a payload slot. The first run installs it into the cache without network access (works with `TEBAKO_OFFLINE=1`). The output file is named according to the `-o` option.
|
|
513
|
+
`classic`::: Stitch the application image onto a prebuilt runtime package (the Stage-3A layout; identical to `bundle` with the default `--runtime prebuilt`). The output file is named according to the `-o` option.
|
|
509
514
|
`bundle`::: Create a single package bundling both the runtime and application. The output file is named according to the `-o` option.
|
|
510
515
|
`both`::: Create separate packages for the runtime and application. Outputs two separate files: one for the runtime at the location specified at the `-o {filename}` and one for the application at `{filename}.package`.
|
|
511
516
|
`application`::: Create the application package only. The output file is named according to the `-o` option.
|
data/cmake/tebako-libtfs.cmake
CHANGED
|
@@ -82,9 +82,7 @@ endif()
|
|
|
82
82
|
if(IS_GNU)
|
|
83
83
|
set(LIBTFS_PLATFORM "linux-gnu-${__LIBTFS_ARCH}")
|
|
84
84
|
elseif(IS_MUSL)
|
|
85
|
-
|
|
86
|
-
message(FATAL_ERROR "No prebuilt libtfs package for linux-musl-${__LIBTFS_ARCH}; use -DDWARFS_PRELOAD=OFF (source build)")
|
|
87
|
-
endif()
|
|
85
|
+
# musl-arm64 prebuilt packages first ship in libtfs v0.12.9
|
|
88
86
|
set(LIBTFS_PLATFORM "linux-musl-${__LIBTFS_ARCH}")
|
|
89
87
|
elseif(IS_DARWIN)
|
|
90
88
|
set(LIBTFS_PLATFORM "macos-${__LIBTFS_ARCH}")
|
data/include/tebako/tpkg.h
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
* offset size field
|
|
49
49
|
* 0 8 u64 offset (image start, absolute file offset)
|
|
50
50
|
* 8 8 u64 size (image length in bytes)
|
|
51
|
-
* 16 4 u32 format_id (0=auto(magic), 1=dwarfs, 2=squashfs, 3=zip)
|
|
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
53
|
* 24 256 char mount_point[256] (UTF-8, NUL-padded)
|
|
54
54
|
*
|
|
@@ -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,6 +108,9 @@ extern "C" {
|
|
|
108
108
|
#define TPKG_FORMAT_DWARFS 1u
|
|
109
109
|
#define TPKG_FORMAT_SQUASHFS 2u
|
|
110
110
|
#define TPKG_FORMAT_ZIP 3u
|
|
111
|
+
/* A runtime payload slot (fat packages): the compressed language-runtime
|
|
112
|
+
* package the bootstrap installs into the shared cache on first run. */
|
|
113
|
+
#define TPKG_FORMAT_RUNTIME 4u
|
|
111
114
|
|
|
112
115
|
/* ---- error codes (returned by tpkg_errno) -------------------------------- */
|
|
113
116
|
|
|
@@ -157,7 +160,7 @@ int tpkg_read_mem(const void* data, size_t size, tpkg_manifest* out);
|
|
|
157
160
|
int tpkg_write_fd(int fd, const tpkg_manifest* m);
|
|
158
161
|
|
|
159
162
|
/* Magic-independent structural checks: version supported, slot_count in
|
|
160
|
-
* 1..TPKG_MAX_SLOTS, offset+size non-overflowing, format_id <=
|
|
163
|
+
* 1..TPKG_MAX_SLOTS, offset+size non-overflowing, format_id <= TPKG_FORMAT_RUNTIME,
|
|
161
164
|
* runtime_ref and mount_points NUL-terminated within their fixed fields. */
|
|
162
165
|
int tpkg_validate(const tpkg_manifest* m);
|
|
163
166
|
|
|
@@ -220,19 +223,12 @@ enum {
|
|
|
220
223
|
};
|
|
221
224
|
|
|
222
225
|
/* slot record field offsets */
|
|
223
|
-
enum {
|
|
224
|
-
TPKG__REC_OFFSET = 0,
|
|
225
|
-
TPKG__REC_SIZE = 8,
|
|
226
|
-
TPKG__REC_FORMAT = 16,
|
|
227
|
-
TPKG__REC_FLAGS = 20,
|
|
228
|
-
TPKG__REC_MOUNT = 24
|
|
229
|
-
};
|
|
226
|
+
enum { TPKG__REC_OFFSET = 0, TPKG__REC_SIZE = 8, TPKG__REC_FORMAT = 16, TPKG__REC_FLAGS = 20, TPKG__REC_MOUNT = 24 };
|
|
230
227
|
|
|
231
228
|
/* wire sizes are fixed by the format; catch exotic padding at compile time */
|
|
232
229
|
typedef char tpkg__assert_slot_size[(sizeof(tpkg_slot) == TPKG_SLOT_SIZE) ? 1 : -1];
|
|
233
|
-
typedef char tpkg__assert_manifest_size[(sizeof(tpkg_manifest) ==
|
|
234
|
-
|
|
235
|
-
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))
|
|
236
232
|
? 1
|
|
237
233
|
: -1];
|
|
238
234
|
|
|
@@ -397,7 +393,7 @@ int tpkg_validate(const tpkg_manifest* m)
|
|
|
397
393
|
if (s->size > UINT64_MAX - s->offset) {
|
|
398
394
|
return tpkg__fail(TPKG_ERR_INVALID);
|
|
399
395
|
}
|
|
400
|
-
if (s->format_id >
|
|
396
|
+
if (s->format_id > TPKG_FORMAT_RUNTIME) {
|
|
401
397
|
return tpkg__fail(TPKG_ERR_INVALID);
|
|
402
398
|
}
|
|
403
399
|
if (tpkg__strnlen(s->mount_point, TPKG_MOUNT_POINT_LEN) == TPKG_MOUNT_POINT_LEN) {
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2026 [Ribose Inc](https://www.ribose.com).
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
# This file is a part of the Tebako project.
|
|
6
|
+
#
|
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
|
8
|
+
# modification, are permitted provided that the following conditions
|
|
9
|
+
# are met:
|
|
10
|
+
# 1. Redistributions of source code must retain the above copyright
|
|
11
|
+
# notice, this list of conditions and the following disclaimer.
|
|
12
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
|
13
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
14
|
+
# documentation and/or other materials provided with the distribution.
|
|
15
|
+
#
|
|
16
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
17
|
+
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
18
|
+
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
19
|
+
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
|
20
|
+
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
21
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
22
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
23
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
24
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
25
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
26
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
|
|
28
|
+
require_relative "runtime_manager"
|
|
29
|
+
|
|
30
|
+
# Tebako - an executable packager
|
|
31
|
+
module Tebako
|
|
32
|
+
# Resolution, download, verification and machine-wide caching of the
|
|
33
|
+
# tebako-bootstrap launcher binaries published by tamatebako/tebako-bootstrap.
|
|
34
|
+
# The launcher is the base binary of lean/fat three-part packages.
|
|
35
|
+
#
|
|
36
|
+
# Cache layout (rooted at $TEBAKO_HOME or ~/.tebako, shared with the
|
|
37
|
+
# runtime package cache):
|
|
38
|
+
# bootstraps/tebako-bootstrap-<version>-<platform>/
|
|
39
|
+
# tebako-bootstrap-<version>-<platform>[.exe]
|
|
40
|
+
# sha256 -- digest the installed file was verified against
|
|
41
|
+
# origin -- URL the binary was downloaded from
|
|
42
|
+
#
|
|
43
|
+
# All download/verify/lock machinery is inherited from RuntimeManager; only
|
|
44
|
+
# the release-shape specifics (asset naming, manifest.json object format,
|
|
45
|
+
# SHA256SUMS index name, mirror env var) differ.
|
|
46
|
+
class BootstrapManager < RuntimeManager
|
|
47
|
+
DEFAULT_MIRROR = "https://github.com/tamatebako/tebako-bootstrap/releases/download"
|
|
48
|
+
BOOTSTRAPS_DIR = "bootstraps"
|
|
49
|
+
INDEX_FILES = ["manifest.json", "SHA256SUMS"].freeze
|
|
50
|
+
|
|
51
|
+
# tebako-bootstrap release consumed by default (TEBAKO_BOOTSTRAP_VERSION
|
|
52
|
+
# overrides). 0.2.0 is the first release that installs a fat package's
|
|
53
|
+
# runtime payload slot into the cache at first run.
|
|
54
|
+
BOOTSTRAP_VERSION = "0.2.0"
|
|
55
|
+
PAYLOAD_MIN_VERSION = "0.2.0"
|
|
56
|
+
|
|
57
|
+
class << self
|
|
58
|
+
def default_version
|
|
59
|
+
version = ENV.fetch("TEBAKO_BOOTSTRAP_VERSION", nil)
|
|
60
|
+
version.nil? || version.empty? ? BOOTSTRAP_VERSION : version.sub(/\Av/, "")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def resolve(platform, bootstrap_version: default_version)
|
|
64
|
+
new.resolve(platform, bootstrap_version: bootstrap_version)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def resolve(platform, bootstrap_version: self.class.default_version)
|
|
69
|
+
super(bootstrap_version, platform, tebako_version: bootstrap_version)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def default_mirror
|
|
75
|
+
DEFAULT_MIRROR
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def mirror_env_var
|
|
79
|
+
"TEBAKO_BOOTSTRAP_MIRROR"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def index_files
|
|
83
|
+
INDEX_FILES
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def cache_subdir
|
|
87
|
+
BOOTSTRAPS_DIR
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def release_name
|
|
91
|
+
"tebako-bootstrap"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def entry_dir(_version, platform, bootstrap_version)
|
|
95
|
+
File.join(@cache_root, BOOTSTRAPS_DIR, "tebako-bootstrap-#{bootstrap_version}-#{platform}")
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def runtime_filename(_version, platform, bootstrap_version)
|
|
99
|
+
suffix = platform.start_with?("windows") ? ".exe" : ""
|
|
100
|
+
"tebako-bootstrap-#{bootstrap_version}-#{platform}#{suffix}"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def runtime_ref(_version, platform, bootstrap_version)
|
|
104
|
+
"tebako-bootstrap@#{bootstrap_version} (#{platform})"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def find_entry(index, _version, platform, bootstrap_version)
|
|
108
|
+
entry = index.find { |candidate| candidate["platform"] == platform }
|
|
109
|
+
return entry if entry
|
|
110
|
+
|
|
111
|
+
platforms = index.map { |candidate| candidate["platform"] }
|
|
112
|
+
Tebako.packaging_error(131, "no tebako-bootstrap package for #{platform} (bootstrap #{bootstrap_version}). " \
|
|
113
|
+
"Available: #{platforms.join(", ")}.")
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def offline_check(ref, bootstrap_version)
|
|
117
|
+
return unless offline?
|
|
118
|
+
|
|
119
|
+
Tebako.packaging_error(132, "#{ref} is not cached and downloads are disabled " \
|
|
120
|
+
"(release index: #{index_urls(bootstrap_version).join(", ")}; " \
|
|
121
|
+
"#{mirror_env_var}=#{@mirror})")
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# tebako-bootstrap's manifest.json is an object
|
|
125
|
+
# ({name:, version:, assets: [{platform:, file:, sha256:}]}), not the
|
|
126
|
+
# entry array tebako-runtime-ruby publishes
|
|
127
|
+
def parse_manifest(body, _bootstrap_version)
|
|
128
|
+
manifest_assets(body)
|
|
129
|
+
.select { |asset| asset["platform"] && asset["file"] && asset["sha256"] }
|
|
130
|
+
.map { |asset| manifest_entry(asset) }
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def manifest_assets(body)
|
|
134
|
+
data = JSON.parse(body)
|
|
135
|
+
assets = data.is_a?(Hash) ? data["assets"] : nil
|
|
136
|
+
raise IndexUnavailable, "manifest.json has no assets array" unless assets.is_a?(Array)
|
|
137
|
+
|
|
138
|
+
assets
|
|
139
|
+
rescue JSON::ParserError
|
|
140
|
+
raise IndexUnavailable, "manifest.json is not valid JSON"
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def manifest_entry(asset)
|
|
144
|
+
{ "platform" => asset["platform"], "filename" => asset["file"], "sha256" => asset["sha256"].downcase }
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def parse_sha256sums(body, bootstrap_version)
|
|
148
|
+
pattern = /\Atebako-bootstrap-#{Regexp.escape(bootstrap_version)}-(.+?)(?:\.exe)?\z/
|
|
149
|
+
body.each_line.filter_map do |line|
|
|
150
|
+
sha256, file = line.strip.split(/\s+/, 2)
|
|
151
|
+
match = file && pattern.match(file.sub(/\A\*/, ""))
|
|
152
|
+
next unless match
|
|
153
|
+
|
|
154
|
+
{ "platform" => match[1], "filename" => file.sub(/\A\*/, ""), "sha256" => sha256.downcase }
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
data/lib/tebako/cli.rb
CHANGED
|
@@ -174,9 +174,10 @@ module Tebako
|
|
|
174
174
|
DESC
|
|
175
175
|
|
|
176
176
|
RUNTIME_DESCRIPTION = <<~DESC
|
|
177
|
-
Runtime provenance: 'prebuilt' resolves/downloads a prebuilt tebako runtime package
|
|
178
|
-
#{" " * 65}#
|
|
179
|
-
#{" " * 65}#
|
|
177
|
+
Runtime provenance: 'prebuilt' resolves/downloads a prebuilt tebako runtime package (default for the
|
|
178
|
+
#{" " * 65}# 'bundle', 'classic', 'lean' and 'fat' modes); 'source' keeps the Stage-2 source build
|
|
179
|
+
#{" " * 65}# (not available for 'lean'/'fat' -- the bootstrap resolves tebako-runtime-ruby releases
|
|
180
|
+
#{" " * 65}# at run time). Modes other than those always build from source.
|
|
180
181
|
DESC
|
|
181
182
|
|
|
182
183
|
IMAGE_DESCRIPTION = <<~DESC
|
|
@@ -184,6 +185,16 @@ module Tebako
|
|
|
184
185
|
#{" " * 65}# must be distinct. Prebuilt runtime only.
|
|
185
186
|
DESC
|
|
186
187
|
|
|
188
|
+
MODE_DESCRIPTION = <<~DESC
|
|
189
|
+
Tebako press mode, 'lean' by default.
|
|
190
|
+
#{" " * 65}# 'lean' presses a three-part package (tebako-bootstrap + application image(s) + tpkg trailer);
|
|
191
|
+
#{" " * 65}# the runtime is resolved into the shared cache at first run.
|
|
192
|
+
#{" " * 65}# 'fat' is 'lean' plus the runtime package as a payload slot -- the first run installs it
|
|
193
|
+
#{" " * 65}# into the cache without network access.
|
|
194
|
+
#{" " * 65}# 'classic' stitches the application image onto a prebuilt runtime (Stage-3A layout);
|
|
195
|
+
#{" " * 65}# 'bundle', 'both', 'application' and 'runtime' keep their legacy behaviors.
|
|
196
|
+
DESC
|
|
197
|
+
|
|
187
198
|
desc "press", "Press tebako image"
|
|
188
199
|
method_option :cwd, type: :string, aliases: "-c", required: false, desc: CWD_DESCRIPTION
|
|
189
200
|
method_option :"log-level", type: :string, aliases: "-l", required: false, enum: %w[error warn debug trace],
|
|
@@ -197,8 +208,9 @@ module Tebako
|
|
|
197
208
|
enum: Tebako::RubyVersion::RUBY_VERSIONS.keys,
|
|
198
209
|
desc: "Tebako package Ruby version, #{Tebako::RubyVersion::DEFAULT_RUBY_VERSION} by default"
|
|
199
210
|
method_option :patchelf, aliases: "-P", type: :boolean, desc: RGP_DESCRIPTION
|
|
200
|
-
method_option :mode, type: :string, aliases: "-m", required: false,
|
|
201
|
-
|
|
211
|
+
method_option :mode, type: :string, aliases: "-m", required: false,
|
|
212
|
+
enum: %w[lean fat classic bundle both runtime application],
|
|
213
|
+
desc: MODE_DESCRIPTION
|
|
202
214
|
method_option :ref, type: :string, aliases: "-u", required: false, desc: REF_DESCRIPTION
|
|
203
215
|
method_option :runtime, type: :string, required: false, enum: %w[prebuilt source], desc: RUNTIME_DESCRIPTION
|
|
204
216
|
method_option :"build-runtime", type: :boolean, required: false,
|
data/lib/tebako/cli_helpers.rb
CHANGED
|
@@ -25,13 +25,16 @@
|
|
|
25
25
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
26
26
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
|
|
28
|
+
require "digest"
|
|
28
29
|
require "etc"
|
|
29
30
|
require "fileutils"
|
|
30
31
|
require "pathname"
|
|
31
32
|
require "rbconfig"
|
|
32
33
|
|
|
34
|
+
require_relative "bootstrap_manager"
|
|
33
35
|
require_relative "codegen"
|
|
34
36
|
require_relative "error"
|
|
37
|
+
require_relative "launcher_abi"
|
|
35
38
|
require_relative "options_manager"
|
|
36
39
|
require_relative "runtime_manager"
|
|
37
40
|
require_relative "scenario_manager"
|
|
@@ -86,8 +89,13 @@ module Tebako
|
|
|
86
89
|
options_manager.process_gemfile(scenario_manager.gemfile_path) if scenario_manager.with_gemfile
|
|
87
90
|
check_warnings(options_manager)
|
|
88
91
|
puts options_manager.press_announce(scenario_manager.msys?)
|
|
92
|
+
dispatch_press(options_manager, scenario_manager)
|
|
93
|
+
end
|
|
89
94
|
|
|
90
|
-
|
|
95
|
+
def dispatch_press(options_manager, scenario_manager)
|
|
96
|
+
if options_manager.three_part?
|
|
97
|
+
do_press_three_part(options_manager, scenario_manager)
|
|
98
|
+
elsif options_manager.prebuilt_runtime?
|
|
91
99
|
do_press_prebuilt(options_manager, scenario_manager)
|
|
92
100
|
else
|
|
93
101
|
do_press_source(options_manager, scenario_manager)
|
|
@@ -104,7 +112,8 @@ module Tebako
|
|
|
104
112
|
def do_press_prebuilt(options_manager, scenario_manager)
|
|
105
113
|
Tebako::Packager.check_prebuilt_env!(options_manager.stash_dir, options_manager.deps_bin_dir)
|
|
106
114
|
runtime_path = Tebako::RuntimeManager.resolve(options_manager.ruby_ver, options_manager.host_platform)
|
|
107
|
-
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))
|
|
108
117
|
|
|
109
118
|
images = [{ path: app_image, mount_point: scenario_manager.fs_mount_point,
|
|
110
119
|
format_id: Tebako::Stitcher::FORMAT_DWARFS }] + options_manager.images
|
|
@@ -113,6 +122,72 @@ module Tebako
|
|
|
113
122
|
puts "Created tebako #{options_manager.output_type_first} at \"#{package}\""
|
|
114
123
|
end
|
|
115
124
|
|
|
125
|
+
# Press a three-part package (Stage 3B): tebako-bootstrap + application
|
|
126
|
+
# image slot(s) + tpkg trailer with the runtime reference (launcher ABI
|
|
127
|
+
# v1). 'lean' (the default) resolves the runtime into the shared cache at
|
|
128
|
+
# first run; 'fat' additionally embeds the runtime package as a payload
|
|
129
|
+
# slot, so the first run installs it without any network access.
|
|
130
|
+
def do_press_three_part(options_manager, scenario_manager)
|
|
131
|
+
bootstrap_path, runtime_path = resolve_three_part_parts(options_manager)
|
|
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)
|
|
136
|
+
package = "#{options_manager.package}#{scenario_manager.exe_suffix}"
|
|
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)
|
|
142
|
+
Tebako::Stitcher.stitch(bootstrap_path, images: images, output: package, lean: true,
|
|
143
|
+
ruby_version: options_manager.ruby_ver,
|
|
144
|
+
launcher_abi: Tebako::LauncherAbi::VERSION,
|
|
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
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Validate the options and the packaging environment, then resolve the
|
|
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)
|
|
157
|
+
def resolve_three_part_parts(options_manager)
|
|
158
|
+
options_manager.runtime_source # validates the mode/provenance combination
|
|
159
|
+
check_bootstrap_version!(options_manager)
|
|
160
|
+
Tebako::Packager.check_prebuilt_env!(options_manager.stash_dir, options_manager.deps_bin_dir)
|
|
161
|
+
runtime_path = Tebako::RuntimeManager.resolve(options_manager.ruby_ver, options_manager.host_platform)
|
|
162
|
+
[Tebako::BootstrapManager.resolve(options_manager.host_platform), runtime_path]
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def three_part_images(options_manager, scenario_manager, app_image, runtime_path)
|
|
166
|
+
images = [{ path: app_image, mount_point: scenario_manager.fs_mount_point,
|
|
167
|
+
format_id: Tebako::Stitcher::FORMAT_DWARFS }] + options_manager.images
|
|
168
|
+
images << { path: runtime_path, mount_point: "", format_id: Tebako::Stitcher::FORMAT_RUNTIME } if runtime_path
|
|
169
|
+
images
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# The fat payload slot is installed by the bootstrap at first run — a
|
|
173
|
+
# capability added in tebako-bootstrap 0.2.0
|
|
174
|
+
def check_bootstrap_version!(options_manager)
|
|
175
|
+
return unless options_manager.fat?
|
|
176
|
+
|
|
177
|
+
version = Tebako::BootstrapManager.default_version
|
|
178
|
+
minimum = Tebako::BootstrapManager::PAYLOAD_MIN_VERSION
|
|
179
|
+
return if payload_capable?(version, minimum)
|
|
180
|
+
|
|
181
|
+
Tebako.packaging_error(134, "fat mode requires tebako-bootstrap >= #{minimum} (selected: #{version}; " \
|
|
182
|
+
"set TEBAKO_BOOTSTRAP_VERSION to a payload-capable release)")
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def payload_capable?(version, minimum)
|
|
186
|
+
Gem::Version.new(version) >= Gem::Version.new(minimum)
|
|
187
|
+
rescue ArgumentError
|
|
188
|
+
false
|
|
189
|
+
end
|
|
190
|
+
|
|
116
191
|
def do_press_application(options_manager, scenario_manager)
|
|
117
192
|
return unless %w[both application].include?(options_manager.mode)
|
|
118
193
|
|
|
@@ -121,7 +196,7 @@ module Tebako
|
|
|
121
196
|
end
|
|
122
197
|
|
|
123
198
|
def do_press_runtime(options_manager, scenario_manager)
|
|
124
|
-
return unless %w[both runtime bundle].include?(options_manager.mode)
|
|
199
|
+
return unless %w[both runtime bundle classic].include?(options_manager.mode)
|
|
125
200
|
|
|
126
201
|
generate_files(options_manager, scenario_manager)
|
|
127
202
|
merged_env = ENV.to_h.merge(scenario_manager.b_env)
|
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/error.rb
CHANGED
|
@@ -57,6 +57,9 @@ module Tebako
|
|
|
57
57
|
127 => "Stitch input file is not accessible",
|
|
58
58
|
128 => "Prebuilt runtime press requires the packaging environment (run 'tebako setup' first)",
|
|
59
59
|
130 => "Option combination is not supported",
|
|
60
|
+
131 => "No tebako-bootstrap package for the requested platform",
|
|
61
|
+
132 => "TEBAKO_OFFLINE is set and the requested tebako-bootstrap package is not cached",
|
|
62
|
+
134 => "Fat mode requires a payload-capable tebako-bootstrap release",
|
|
60
63
|
201 => "Warning. Could not create cache version file"
|
|
61
64
|
}.freeze
|
|
62
65
|
|
data/lib/tebako/launcher_abi.rb
CHANGED
|
@@ -30,6 +30,12 @@ module Tebako
|
|
|
30
30
|
# three-part package model (spec §4.4).
|
|
31
31
|
#
|
|
32
32
|
# A lean package is [tebako-bootstrap][.tfs image slots][tpkg trailer].
|
|
33
|
+
# A fat package has the same layout plus the runtime package itself as a
|
|
34
|
+
# payload slot (format_id TPKG_FORMAT_RUNTIME, empty mount point,
|
|
35
|
+
# ";sha256=<hex>" appended to the trailer's runtime_ref): at first run the
|
|
36
|
+
# bootstrap installs the payload into the shared cache instead of
|
|
37
|
+
# downloading it. Payload slots are never handed over as --tebako-image.
|
|
38
|
+
#
|
|
33
39
|
# The bootstrap (tamatebako/tebako-bootstrap) parses the trailer of its own
|
|
34
40
|
# executable, resolves the language runtime into the shared cache, and
|
|
35
41
|
# execs it as:
|
|
@@ -41,6 +41,13 @@ require_relative "version"
|
|
|
41
41
|
module Tebako
|
|
42
42
|
# Cli helpers
|
|
43
43
|
class OptionsManager # rubocop:disable Metrics/ClassLength
|
|
44
|
+
# Press modes producing three-part packages (tebako-bootstrap + image
|
|
45
|
+
# slots + tpkg trailer): 'lean' resolves the runtime at first run, 'fat'
|
|
46
|
+
# additionally embeds it as a payload slot (self-installing, offline)
|
|
47
|
+
THREE_PART_MODES = %w[lean fat].freeze
|
|
48
|
+
# Modes whose default runtime provenance is a prebuilt runtime package
|
|
49
|
+
PREBUILT_DEFAULT_MODES = %w[bundle classic lean fat].freeze
|
|
50
|
+
|
|
44
51
|
def initialize(options)
|
|
45
52
|
@options = options
|
|
46
53
|
@rv = Tebako::RubyVersion.new(@options["Ruby"])
|
|
@@ -157,14 +164,24 @@ module Tebako
|
|
|
157
164
|
end
|
|
158
165
|
|
|
159
166
|
def mode
|
|
160
|
-
@mode ||= @options["mode"].nil? ? "
|
|
167
|
+
@mode ||= @options["mode"].nil? ? "lean" : @options["mode"]
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def three_part?
|
|
171
|
+
THREE_PART_MODES.include?(mode)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def fat?
|
|
175
|
+
mode == "fat"
|
|
161
176
|
end
|
|
162
177
|
|
|
163
178
|
# Runtime provenance: "prebuilt" (resolve/download a prebuilt runtime
|
|
164
|
-
# package
|
|
165
|
-
#
|
|
166
|
-
#
|
|
167
|
-
#
|
|
179
|
+
# package) or "source" (the Stage-2 source build). Default is "prebuilt"
|
|
180
|
+
# for the bundle/classic/lean/fat modes; other modes always build from
|
|
181
|
+
# source, and --build-runtime forces the source path everywhere it is
|
|
182
|
+
# allowed (back-compat alias for '--runtime source'). The three-part
|
|
183
|
+
# modes (lean/fat) require prebuilt runtime packages: the bootstrap
|
|
184
|
+
# resolves tebako-runtime-ruby releases at run time.
|
|
168
185
|
def runtime_source
|
|
169
186
|
@runtime_source ||= checked_runtime_source(requested_runtime_source)
|
|
170
187
|
end
|
|
@@ -246,7 +263,7 @@ module Tebako
|
|
|
246
263
|
press_announce_application(is_msys)
|
|
247
264
|
when "both"
|
|
248
265
|
press_announce_both
|
|
249
|
-
when "bundle"
|
|
266
|
+
when "bundle", "classic", "lean", "fat"
|
|
250
267
|
press_announce_bundle
|
|
251
268
|
when "runtime"
|
|
252
269
|
press_announce_runtime
|
|
@@ -290,7 +307,7 @@ module Tebako
|
|
|
290
307
|
def press_announce_bundle
|
|
291
308
|
<<~ANN
|
|
292
309
|
Running tebako press at #{prefix}
|
|
293
|
-
Mode: '
|
|
310
|
+
Mode: '#{mode}'
|
|
294
311
|
Ruby version: '#{@ruby_ver}'
|
|
295
312
|
Project root: '#{root}'
|
|
296
313
|
Application entry point: '#{fs_entrance}'
|
|
@@ -374,14 +391,19 @@ module Tebako
|
|
|
374
391
|
def requested_runtime_source
|
|
375
392
|
explicit = @options["runtime"]
|
|
376
393
|
return "source" if @options["build-runtime"]
|
|
377
|
-
return mode
|
|
394
|
+
return PREBUILT_DEFAULT_MODES.include?(mode) ? "prebuilt" : "source" if explicit.nil?
|
|
378
395
|
|
|
379
396
|
explicit
|
|
380
397
|
end
|
|
381
398
|
|
|
382
399
|
def checked_runtime_source(source)
|
|
383
|
-
if source == "prebuilt" && mode
|
|
384
|
-
Tebako.packaging_error(130, "--runtime prebuilt is supported in bundle
|
|
400
|
+
if source == "prebuilt" && !PREBUILT_DEFAULT_MODES.include?(mode)
|
|
401
|
+
Tebako.packaging_error(130, "--runtime prebuilt is supported in bundle, classic, lean and fat modes only " \
|
|
402
|
+
"(mode: '#{mode}')")
|
|
403
|
+
end
|
|
404
|
+
if source == "source" && three_part?
|
|
405
|
+
Tebako.packaging_error(130, "mode '#{mode}' requires a prebuilt runtime package " \
|
|
406
|
+
"(the bootstrap resolves tebako-runtime-ruby releases at first run)")
|
|
385
407
|
end
|
|
386
408
|
source
|
|
387
409
|
end
|
|
@@ -399,7 +421,7 @@ module Tebako
|
|
|
399
421
|
|
|
400
422
|
def host_arch_id(arch)
|
|
401
423
|
case arch
|
|
402
|
-
when /^(x86_64|amd64)$/ then "x86_64"
|
|
424
|
+
when /^(x86_64|amd64|x64)$/ then "x86_64"
|
|
403
425
|
when /^(aarch64|arm64)$/ then "arm64"
|
|
404
426
|
else
|
|
405
427
|
Tebako.packaging_error(112, arch)
|
|
@@ -203,6 +203,21 @@ module Tebako
|
|
|
203
203
|
"/* tebako patched */ static const struct vktable *console_win32_vk(const char *, size_t);"
|
|
204
204
|
}.freeze
|
|
205
205
|
|
|
206
|
+
# Ruby's win32.c defines clock_gettime/clock_getres fallbacks with no
|
|
207
|
+
# HAVE_* configure guard (at least through 3.4); modern mingw-w64
|
|
208
|
+
# winpthreads headers (pthread_time.h, pulled in by time.h) carry
|
|
209
|
+
# static-inline definitions of the same symbols, so the toolchain
|
|
210
|
+
# build fails with redefinition errors. Rename ruby's fallbacks
|
|
211
|
+
# before the toolchain build; the CRT/winpthreads implementations
|
|
212
|
+
# (which configure detects) serve the calls. Pass2 re-applies the
|
|
213
|
+
# same rename from pristine sources for the final build.
|
|
214
|
+
WIN32_WIN32_C_CLOCK_PATCH = {
|
|
215
|
+
"clock_gettime(clockid_t clock_id, struct timespec *sp)" =>
|
|
216
|
+
"_dummy_clock_gettime(clockid_t clock_id, struct timespec *sp)",
|
|
217
|
+
"clock_getres(clockid_t clock_id, struct timespec *sp)" =>
|
|
218
|
+
"_dummy_clock_getres(clockid_t clock_id, struct timespec *sp)"
|
|
219
|
+
}.freeze
|
|
220
|
+
|
|
206
221
|
def patch_map
|
|
207
222
|
pm = msys_patches
|
|
208
223
|
pm.merge!(super)
|
|
@@ -246,7 +261,11 @@ module Tebako
|
|
|
246
261
|
"ext/openssl/extconf.rb" => OPENSSL_EXTCONF_RB_PATCH,
|
|
247
262
|
# ....................................................
|
|
248
263
|
# Fix the signature of console_win32_vk
|
|
249
|
-
"ext/io/console/win32_vk.inc" => EXT_IO_CONSOLE_WIN32_VK_INC_PATCH
|
|
264
|
+
"ext/io/console/win32_vk.inc" => EXT_IO_CONSOLE_WIN32_VK_INC_PATCH,
|
|
265
|
+
# ....................................................
|
|
266
|
+
# Rename ruby's clock_gettime/clock_getres fallbacks before the
|
|
267
|
+
# toolchain build (winpthreads static-inline collision)
|
|
268
|
+
"win32/win32.c" => WIN32_WIN32_C_CLOCK_PATCH
|
|
250
269
|
}
|
|
251
270
|
end
|
|
252
271
|
|
|
@@ -114,6 +114,9 @@ module Tebako
|
|
|
114
114
|
"#if defined _MSC_VER && _MSC_VER <= 1200" =>
|
|
115
115
|
"#{PatchLiterals::C_FILE_SUBST_LESS}\n#if defined _MSC_VER && _MSC_VER <= 1200",
|
|
116
116
|
"len = GetCurrentDirectoryW(0, NULL);" => WIN32_WIN32_C_MSYS_SUBST,
|
|
117
|
+
# Keep the clock renames in sync with Pass1MSysPatch::WIN32_WIN32_C_CLOCK_PATCH:
|
|
118
|
+
# pass1 applies them for the toolchain build, this pass re-applies them
|
|
119
|
+
# from pristine sources for the final build
|
|
117
120
|
"clock_gettime(clockid_t clock_id, struct timespec *sp)" =>
|
|
118
121
|
"_dummy_clock_gettime(clockid_t clock_id, struct timespec *sp)",
|
|
119
122
|
"clock_getres(clockid_t clock_id, struct timespec *sp)" =>
|
|
@@ -76,7 +76,9 @@ module Tebako
|
|
|
76
76
|
|
|
77
77
|
def recreate(dirname)
|
|
78
78
|
FileUtils.rm_rf(dirname, noop: nil, verbose: nil, secure: true)
|
|
79
|
-
|
|
79
|
+
# mkdir_p: in three-part/prebuilt press flows no cmake configure runs,
|
|
80
|
+
# so the parent output folder may not exist yet
|
|
81
|
+
FileUtils.mkdir_p(dirname)
|
|
80
82
|
end
|
|
81
83
|
|
|
82
84
|
def restore_and_save(fname, strict: true)
|
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,11 +84,15 @@ 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)
|
|
89
94
|
@cache_root = cache_root || self.class.default_cache_root
|
|
90
|
-
@mirror = (mirror || ENV.fetch(
|
|
95
|
+
@mirror = (mirror || ENV.fetch(mirror_env_var, nil) || default_mirror).sub(%r{/+\z}, "")
|
|
91
96
|
@lock_timeout = lock_timeout
|
|
92
97
|
@retry_delay = retry_delay
|
|
93
98
|
end
|
|
@@ -105,8 +110,24 @@ 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
|
-
base = File.join(@cache_root,
|
|
130
|
+
base = File.join(@cache_root, cache_subdir)
|
|
110
131
|
return [] unless Dir.exist?(base)
|
|
111
132
|
|
|
112
133
|
Dir.children(base).sort.filter_map do |name|
|
|
@@ -131,6 +152,29 @@ module Tebako
|
|
|
131
152
|
|
|
132
153
|
private
|
|
133
154
|
|
|
155
|
+
# ---- extension points for BootstrapManager (tebako-bootstrap release
|
|
156
|
+
# resolution); overridden there, everything else is shared machinery ----
|
|
157
|
+
|
|
158
|
+
def default_mirror
|
|
159
|
+
DEFAULT_MIRROR
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def mirror_env_var
|
|
163
|
+
"TEBAKO_RUNTIME_MIRROR"
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def index_files
|
|
167
|
+
INDEX_FILES
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def cache_subdir
|
|
171
|
+
RUNTIMES_DIR
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def release_name
|
|
175
|
+
"tebako-runtime-ruby"
|
|
176
|
+
end
|
|
177
|
+
|
|
134
178
|
def install(executable, ruby_version, platform, tebako_version)
|
|
135
179
|
ref = runtime_ref(ruby_version, platform, tebako_version)
|
|
136
180
|
offline_check(ref, tebako_version)
|
|
@@ -146,7 +190,7 @@ module Tebako
|
|
|
146
190
|
|
|
147
191
|
Tebako.packaging_error(123, "#{ref} is not cached and downloads are disabled " \
|
|
148
192
|
"(release index: #{index_urls(tebako_version).join(", ")}; " \
|
|
149
|
-
"
|
|
193
|
+
"#{mirror_env_var}=#{@mirror})")
|
|
150
194
|
end
|
|
151
195
|
|
|
152
196
|
def find_entry(index, ruby_version, platform, tebako_version)
|
|
@@ -178,14 +222,14 @@ module Tebako
|
|
|
178
222
|
|
|
179
223
|
def fetch_index(tebako_version)
|
|
180
224
|
tried = []
|
|
181
|
-
|
|
225
|
+
index_files.each do |name|
|
|
182
226
|
return parse_index(name, fetch_text(index_url(name, tebako_version)), tebako_version)
|
|
183
227
|
rescue IndexUnavailable
|
|
184
228
|
tried << index_url(name, tebako_version)
|
|
185
229
|
rescue DownloadFailed => e
|
|
186
230
|
Tebako.packaging_error(122, e.message)
|
|
187
231
|
end
|
|
188
|
-
Tebako.packaging_error(124, "
|
|
232
|
+
Tebako.packaging_error(124, "#{release_name} release v#{tebako_version} provides no usable package " \
|
|
189
233
|
"index (tried: #{tried.join(", ")})")
|
|
190
234
|
end
|
|
191
235
|
|
|
@@ -333,7 +377,7 @@ module Tebako
|
|
|
333
377
|
end
|
|
334
378
|
|
|
335
379
|
def index_urls(tebako_version)
|
|
336
|
-
|
|
380
|
+
index_files.map { |name| index_url(name, tebako_version) }
|
|
337
381
|
end
|
|
338
382
|
|
|
339
383
|
def package_url(filename, tebako_version)
|
data/lib/tebako/stitcher.rb
CHANGED
|
@@ -75,7 +75,10 @@ module Tebako
|
|
|
75
75
|
FORMAT_DWARFS = 1
|
|
76
76
|
FORMAT_SQUASHFS = 2
|
|
77
77
|
FORMAT_ZIP = 3
|
|
78
|
-
|
|
78
|
+
# Runtime payload slot of a fat package: installed into the shared cache
|
|
79
|
+
# by the bootstrap at first run, never mounted (tpkg.h TPKG_FORMAT_RUNTIME)
|
|
80
|
+
FORMAT_RUNTIME = 4
|
|
81
|
+
FORMAT_IDS = (FORMAT_AUTO..FORMAT_RUNTIME).freeze
|
|
79
82
|
|
|
80
83
|
# Header field offsets
|
|
81
84
|
OFF_PACKAGE_FLAGS = 14
|
|
@@ -89,17 +92,21 @@ module Tebako
|
|
|
89
92
|
# copy of the runtime at +runtime_path+, writing +output+.
|
|
90
93
|
# lean: true marks the package LEAN and records runtime_ref
|
|
91
94
|
# ("ruby@<ruby_version>;tebako=<tebako_version>"); classic packages
|
|
92
|
-
# carry an empty runtime_ref.
|
|
95
|
+
# carry an empty runtime_ref. runtime_sha256 appends ";sha256=<hex>" to
|
|
96
|
+
# the runtime_ref — the checksum the bootstrap verifies a fat package's
|
|
97
|
+
# runtime payload slot against before installing it into the cache.
|
|
93
98
|
def stitch(runtime_path, images:, output:, lean: false, ruby_version: nil, # rubocop:disable Metrics/ParameterLists
|
|
94
|
-
tebako_version: Tebako::VERSION, launcher_abi: 0)
|
|
99
|
+
tebako_version: Tebako::VERSION, launcher_abi: 0, runtime_sha256: nil)
|
|
95
100
|
images = normalize_images(images)
|
|
96
101
|
validate_inputs!(runtime_path, images, lean, ruby_version)
|
|
102
|
+
validate_runtime_sha256!(runtime_sha256)
|
|
97
103
|
|
|
98
104
|
FileUtils.mkdir_p(File.dirname(output))
|
|
99
105
|
FileUtils.cp(runtime_path, output)
|
|
100
106
|
FileUtils.chmod(0o755, output)
|
|
101
107
|
|
|
102
|
-
append(images, output, package_flags(lean), runtime_ref(lean, ruby_version, tebako_version
|
|
108
|
+
append(images, output, package_flags(lean), runtime_ref(lean, ruby_version, tebako_version, runtime_sha256),
|
|
109
|
+
launcher_abi)
|
|
103
110
|
resign_if_needed(output)
|
|
104
111
|
output
|
|
105
112
|
end
|
|
@@ -157,6 +164,8 @@ module Tebako
|
|
|
157
164
|
seen = {}
|
|
158
165
|
images.each do |image|
|
|
159
166
|
validate_image!(image)
|
|
167
|
+
next if image[:format_id] == FORMAT_RUNTIME # payload slots are never mounted
|
|
168
|
+
|
|
160
169
|
mount = image[:mount_point]
|
|
161
170
|
Tebako.packaging_error(126, "duplicate mount point '#{mount}'") if seen[mount]
|
|
162
171
|
|
|
@@ -166,7 +175,7 @@ module Tebako
|
|
|
166
175
|
|
|
167
176
|
def validate_image!(image)
|
|
168
177
|
unless FORMAT_IDS.cover?(image[:format_id])
|
|
169
|
-
Tebako.packaging_error(126, "invalid format_id #{image[:format_id]} (0..
|
|
178
|
+
Tebako.packaging_error(126, "invalid format_id #{image[:format_id]} (0..4 expected)")
|
|
170
179
|
end
|
|
171
180
|
return unless image[:mount_point].bytesize >= MOUNT_POINT_LEN
|
|
172
181
|
|
|
@@ -174,14 +183,21 @@ module Tebako
|
|
|
174
183
|
"mount point '#{image[:mount_point][0, 32]}...' exceeds #{MOUNT_POINT_LEN - 1} bytes")
|
|
175
184
|
end
|
|
176
185
|
|
|
186
|
+
def validate_runtime_sha256!(runtime_sha256)
|
|
187
|
+
return if runtime_sha256.nil? || runtime_sha256.match?(/\A[0-9a-f]{64}\z/)
|
|
188
|
+
|
|
189
|
+
Tebako.packaging_error(126, "runtime_sha256 must be 64 lowercase hex characters")
|
|
190
|
+
end
|
|
191
|
+
|
|
177
192
|
def package_flags(lean)
|
|
178
193
|
lean ? FLAG_LEAN : 0
|
|
179
194
|
end
|
|
180
195
|
|
|
181
|
-
def runtime_ref(lean, ruby_version, tebako_version)
|
|
196
|
+
def runtime_ref(lean, ruby_version, tebako_version, runtime_sha256)
|
|
182
197
|
return "" unless lean
|
|
183
198
|
|
|
184
199
|
ref = "ruby@#{ruby_version};tebako=#{tebako_version}"
|
|
200
|
+
ref += ";sha256=#{runtime_sha256}" if runtime_sha256
|
|
185
201
|
if ref.bytesize >= RUNTIME_REF_LEN
|
|
186
202
|
Tebako.packaging_error(126, "runtime_ref '#{ref}' exceeds #{RUNTIME_REF_LEN - 1} bytes")
|
|
187
203
|
end
|
data/lib/tebako/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tebako
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.15.
|
|
4
|
+
version: 0.15.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -212,6 +212,7 @@ files:
|
|
|
212
212
|
- include/tebako/tebako-prism.h
|
|
213
213
|
- include/tebako/tpkg.h
|
|
214
214
|
- lib/tebako.rb
|
|
215
|
+
- lib/tebako/bootstrap_manager.rb
|
|
215
216
|
- lib/tebako/build_helpers.rb
|
|
216
217
|
- lib/tebako/cache_manager.rb
|
|
217
218
|
- lib/tebako/cli.rb
|